How module routing works in Yii2

Image like oooh honeycombs are like modules, or something…

In this article, I will shortly outline how to register a new module in Yii2, a bit about routing in Yii2 and the best place to put your breakpoints to debug URL routing.

In Yii, the app should be divided into several areas of responsibility. Each of these areas are reflected in code as modules. For example, a blogging website would have User, Post, Comment, Authentication and similar modules, each containing the database models, repositories, controllers and services relating to that area of code.

To create a module:

  1. Create a folder in the app root directory of your project. (Usually this app/ or src/ or something similar. In here you will put all code written by you relating to your project.) The module folder should be named after the app functionality it will be responsible for. Inside, create a module declaration file.
src/Team/Functionality/FunctionalityModule.php

Code in the file:

<?php
declare(strict_types=1);
namespace Team\Functionality;use yii\base\Module;class FunctionalityModule extends Module
{
}

2. Register the module in config/main.php. In the return array, under the modules key. The key you use here will be the first path component of the URL we’ll call to get the page content. It must be kebab-case. The value will be an array with a single element — key class and value will be the module class name. For example,

‘example’ => [‘class’ => \Team\Functionality\FunctionalityModule::class],

3. We’ll put the controllers in the Controllers/ directory in the module. In this example, we will have 2 controllers — one for rendering FE views and another for API calls. (It is not always necessary to make this distinction, but here I am using this example in case each controller needs to extend from a different base class.)

We will register them in the Module file — this will declare the “module-name/items-controller/get-items” part of our route. It can be any kebab-case string — that’s why it’s a map!

class FunctionalityModule extends Module
{
public $controllerMap = [
‘example’ => ExampleController::class,
‘api’ => ExampleApiController::class,
];
}

A little about Yii routing: a Yii route consists of 3 parts: module, controller, action e.g. module-name/items-controller/get-items
The module part is the one we declared in main.php. (Modules can have submodules, so you could actually have a route that’s module/submodule/subsubmodule/controller/action, and Yii will resolve it. See comment in \yii\base\Module::createController for more details.) The action is the controller function name after action-, transformed into kebab-case.

Yii also allows for a default controller in each module, technically allowing routes like module-name/get-items, though the routing can get tricky with this, especially if the route has a trailing / — Yii will interpret module-name/get-items/ differently, looking for GetItemsModule or GetItemsController. If you’re unsure of how your path will be routed, it’s best to put a breakpoint inside \yii\base\Module::createController and see for yourself.

4. Finally we’ll add a view. In the ExampleController, we’ll have an action function that will return $this->render(‘index’); The view file name has to be the same as the parameter given to render(), and it has to be located it in views/example/. The subdirectory name here has to be the same as the controller key in the Module’s $controllerMap — in Yii, each controller is supposed to have its own view subdirectory. views/ must not be capitalised.

This is what the final directory structure should look like:

src/
Team/
Functionality/
Controllers/
ExampleController.php
ExampleRpcController.php
views/
example/
index.php
ExampleModule.php

I have found that information online on Yii2 is quite scarce, and the official documentation is not always helpful. Since this is the framework I’m working with at the moment, I thought I’d write up some things that I stumbled upon when developing for it! If I’ve gotten something wrong, or you have anything to add, please comment and I will amend the article. The goal here is to inform developers who will be googling around in the future! :)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store