What is Package?

Package is an important part of Windwalker's system structure, which helps us organize our code and architecture, make system more modular. Here is a image to describe the package system:


From above image, we will notice that there can be multiple packages and its' own MVC groups in Windwalker. That makes our application more flexible. For example, we can create a FrontendPackage for front-end an AdminPackage as for back-end use. And an ApiPackage to provide RESTful API for mobile APP if we need.

Every package is pretty much a simple application having MVC, routing, configuration and database schema:


Use Package as Extension

Package can be used as extensions for developer. You can create a package and submit it to Packagist. Then anyone can install it by composer.


Create Package

We will use Flower as example package. Create a php class in /src/Flower/FlowerPackage.php:

// /src/Flower/FlowerPackage.php

namespace Flower;

use Windwalker\Core\Package\AbstractPackage;

class FlowerPackage extends AbstractPackage

Then add this package to /etc/windwalker.php file (or web.php if you only want it run in web environment):

// etc/app/windwalker.php

// ...

    'packages' => [
        'main' => \Main\MainPackage::class
        'flower' => \Flower\FlowerPackage::class // Add this line

// ...

The array key is package name alias, you can customize it. For example, If you use egg as package alias, then you must get this package by \Windwalker\Core\Package\PackageHelper::getPackage('egg'). Mostly we use an alias same with package name, but sometimes if there has package name conflict, we can try to use different alias.

Add Package Routing

Create /src/Flower/routing.yml, then add some routes:

## /src/Flower/routing.yml

    pattern: /sakura(/id)
    controller: Sakura

    pattern: /sakuras
    controller: Sakuras

    pattern: /roses
    controller: Roses

Different from the global routing, you don't need to write all controller namespace, just write controller short name, the package will auto find this controller. For example: controller: Sakura will find Flower\Controller\Sakura\{action} to execute.

We have to register this routes to root routing file. Open /etc/routing.yml And add this route profile.

## /etc/routing.yml

    pattern: /flower
    package: flower

The package: flower tells Windwalker to import all Flower package's routes, and all patterns will prefix with: /flower/..., the compiled routes will look like:

    pattern: /flower/sakura(/id)
    controller: Sakura

    pattern: /flower/sakuras
    controller: Sakuras

    pattern: /flower/roses
    controller: Roses

Use browser open /flower/sakuras, Windwalker will find Flower\Controller\Sakuras\GetController to render page. We can create a controller to match this route:

// src/Flower/Controller/Sakuras/GetController.php

namespace Flower\Controller\Sakuras;

use Windwalker\Core\Controller\Controller;

class GetController extends Controller
    protected function doExecute()
        return 'Output of Sakuras Controller';

About how routing and controller work, please see Routing section.

Add & Get Packages

Use PackageResolver.

$resolver = $container->get('package.resolver');

$resolver->getPackage('flower'); // Get flower package

$resolver->getPackage(); // Get current package

$resoler->addPackage('alias', $package); // Add new package

Use PackageHelper, this class is a facade of PackageResolver.

use Windwalker\Core\Package\PackageHelper;

PackageHelper::getPackage('flower'); // Get flower package

PackageHelper::getPackage(); // Get current package

PackageHelper::addPackage('alias', $package); // Add new package

You can also get package from Application.

$app = Ioc::getApplication();

$app->getPackage([$alias|null]); // NULL will get current package

Install Package

After registering package to Windwalker, we can run

$ php windwlaker package install <package_alias>

to install package config, routing and assets.

If you found a typo or error, please help us improve this document.