How to Build a Module

Preparation

Before you begin working on a module, you need to decide on a couple things:

  • Namespace – The root namespace that your module’s classes will live in. (See the PSR-4 autoloading specification for details.) Note that this should not begin with craft\; use something that identifies you (the developer), or the project.
  • Module ID – Something that uniquely identifies your plugin within your project. (Module IDs must begin with a letter and contain only lowercase letters, numbers, and dashes. They should be kebab-cased.)

WARNING

When choosing a module ID, try to avoid names that will conflict with Craft’s core controllers (e.g. app would conflict with AppController.php), as well as any installed plugin handles. Otherwise bad things will happen.

Set up the basic file structure

To create a module, create a new directory for it somewhere within your Craft project, such as modules/<ModuleID>/. For example, if your module ID is foo, you might set it up like this:

my-project.test/
├── modules/
│   └── foo/
│       └── Module.php
├── templates/
└── ...

TIP

Use pluginfactory.io to create your module’s scaffolding with just a few clicks.

Set up class autoloading

Next up, you need to tell Composer how to find your module’s classes by setting the autoload field in your project’s composer.json file. For example, if your module’s namespace is bar, and it’s located at modules/foo/, this is what you should add:

{
  // ...
  "autoload": {
    "psr-4": {
      "bar\\": "modules/foo/"
    }
  }
}

With that in place, go to your project’s directory in your terminal, and run the following command:

composer dump-autoload -a

That will tell Composer to update its class autoloader script based on your new autoload mapping.

Update the application config

You can add your module to your project’s application configuration by listing it in the modules and bootstrap arrays. For example, if your module ID is foo and its Module class name is foo\Module, this is what you should add to config/app.php:

return [
    // ...
    'modules' => [
        'foo' => foo\Module::class,
    ],
    'bootstrap' => [
        'foo',
    ],
];

TIP

If your module doesn’t need to get loaded on every request, you can remove its ID from the bootstrap array.

The Module class

The Module.php file is your module’s entry point for the system. Its init() method is the best place to register event listeners, and any other steps it needs to take to initialize itself.

Use this template as a starting point for your Module.php file:

<?php
namespace bar;

class Module extends \yii\base\Module
{
    public function init()
    {
        parent::init();

        // Custom initialization code goes here...
    }
}

Replace bar with your module’s actual namespace.

Further Reading

To learn more about modules, see the Yii documentation.