Alex Jose Alex Jose - 1 year ago 96
PHP Question

Yii - Eliminate default controller ID for a module from URL

I created a module and there exists a default controller inside that. Now I can access the index action (default action) in the default controller like /mymodule/. For all other action i need to specify the controller id in the url like /mymodule/default/register/ . I would like to know is it possible to eliminate the controller id from url for the default controller in a module.

I need to set url rule like this:

before beautify :

after beautify :

Note: I want this to happen only for the default controller.


Answer Source

This is a little tricky because the action part might be considered as a controller or you might be pointing to an existing controller. But you can get away with this by using a Custom URL Rule Class. Here's an example (I tested it and it seems to work well):

class CustomURLRule extends CBaseUrlRule
  const MODULE = 'mymodule';
  const DEFAULT_CONTROLLER = 'default';

  public function parseUrl($manager, $request, $pathInfo, $rawPathInfo)
    if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches)) {
      // Make sure the url has 2 or more segments (e.g. mymodule/action)
      // and the path is under our target module. 
      if (count($matches) != 4 || !isset($matches[1]) || !isset($matches[3]) || $matches[1] != self::MODULE)
        return false;

      // check first if the route already exists
      if (($controller = Yii::app()->createController($pathInfo))) {
        // Route exists, don't handle it since it is probably pointing to another controller
        // besides the default.
        return false;
      } else {
        // Route does not exist, return our new path using the default controller.
        $path = $matches[1] . '/' . self::DEFAULT_CONTROLLER . '/' . $matches[3];
        return $path;
    return false;

  public function createUrl($manager, $route, $params, $ampersand)
    // @todo: implement
    return false;