Search code examples
moduleyii2url-routingyii2-module

Yii2: Omit controller ID from module route


A typical Yii2 route to any action in a module controller is as follows:

<moduleID>/<controllerID>/<actionID>

How do we configure/structure our module (which has only 1 controller) so that we may reach its actions directly using the following route:

<moduleID>/<actionID>

without having to override the routes in the main application's urlManager?


Solution

  • Combining the answers from Bizley and IStranger and and adding some of my own wisdom I have come up with a solution. As long as your module is being added through composer, this is what you can do:

    1. In your module create a RouteBootstrap.php file with the following content:

      namespace your\name\space;
      
      class RouteBootstrap implements \yii\basic\BootstrapInterface {
          public function bootstrap($app) {
              if ($app instanceof \yii\web\Application) {
                  $app->urlManager->addRules([
                      ['moduleID/<action>' => 'moduleID/default/<action>'],
                  ]);
              }
          }
      }
      

      (be sure to replace moduleID with you actual module ID). This is the same technique used by the official Yii2 Gii module.

    2. Add the following to your module's composer.json file:

      "extra": {
          "bootstrap": "your\\name\\space\\RouteBootstrap"
      }
      

      More details about this trick are described in the documentation.

    3. Remove the module from your vendors directory and run composer update.

    That's it. Your module will automagically add the route rule to the main app and you will be able to access the DefaultController's actions using <moduleID>/<actionID> routes.

    On the other hand this is still not the ideal solution. It is more of a workaround to Yii2's design flaw. If someone comes up with a better solution, it will be set as the accepted answer.