Module

A module is a self-contained software unit that consists of models, views, controllers and other supporting components. In many aspects, a module resembles to an application. The main difference is that a module cannot be deployed alone and it must reside inside of an application. Users can access the controllers in a module like they do with normal application controllers.

Modules are useful in several scenarios. For a large-scale application, we may divide it into several modules, each being developed and maintained separately. Some commonly used features, such as user management, comment management, may be developed in terms of modules so that they can be reused easily in future projects.

1. Creating Module

A module is organized as a directory whose name serves as its unique ID. The structure of the module directory is similar to that of the application base directory. The following shows the typical directory structure of a module named forum:

forum/
   ForumModule.php            the module class file
   components/                containing reusable user components
      views/                  containing view files for widgets
   controllers/               containing controller class files
      DefaultController.php   the default controller class file
   extensions/                containing third-party extensions
   models/                    containing model class files
   views/                     containing controller view and layout files
      layouts/                containing layout view files
      default/                containing view files for DefaultController
         index.php            the index view file

A module must have a module class that extends from CWebModule. The class name is determined using the expression ucfirst($id).'Module', where $id refers to the module ID (or the module directory name). The module class serves as the central place for storing information shared among the module code. For example, we can use CWebModule::params to store module parameters, and use CWebModule::components to share application components at the module level.

Tip: We can use the module generator in Gii to create the basic skeleton of a new module.

2. Using Module

To use a module, first place the module directory under modules of the application base directory. Then declare the module ID in the modules property of the application. For example, in order to use the above forum module, we can use the following application configuration:

return array(
    ......
    'modules'=>array('forum',...),
    ......
);

A module can also be configured with initial property values. The usage is very similar to configuring application components. For example, the forum module may have a property named postPerPage in its module class which can be configured in the application configuration as follows:

return array(
    ......
    'modules'=>array(
        'forum'=>array(
            'postPerPage'=>20,
        ),
    ),
    ......
);

The module instance may be accessed via the module property of the currently active controller. Through the module instance, we can then access information that are shared at the module level. For example, in order to access the above postPerPage information, we can use the following expression:

$postPerPage=Yii::app()->controller->module->postPerPage;
// or the following if $this refers to the controller instance
// $postPerPage=$this->module->postPerPage;

A controller action in a module can be accessed using the route moduleID/controllerID/actionID. For example, assuming the above forum module has a controller named PostController, we can use the route forum/post/create to refer to the create action in this controller. The corresponding URL for this route would be http://www.example.com/index.php?r=forum/post/create.

Tip: If a controller is in a sub-directory of controllers, we can still use the above route format. For example, assuming PostController is under forum/controllers/admin, we can refer to the create action using forum/admin/post/create.

3. Nested Module

Modules can be nested in unlimited levels. That is, a module can contain another module which can contain yet another module. We call the former parent module while the latter child module. Child modules must be declared in the modules property of their parent module, like we declare modules in the application configuration shown as above.

To access a controller action in a child module, we should use the route parentModuleID/childModuleID/controllerID/actionID.

$Id$

Total 6 comments

#9890 report it
flarpy at 2012/09/19 09:16am
Access to other modules

To access a different module or a model within a different module, use

Yii::app()->getModule('moduleName');

You can then use models from that module in the usual way.

#8820 report it
yugene at 2012/06/30 01:14am
Case sensitivity

Please notice, when using module that contains uppercase characters in its name, if you have caseSensitive parameter of urlManager set to false

'urlManager' => array(
            'caseSensitive' => false,
)

then you won't be able to reach this module, getting Error 404 (Page not found). So you have whether to rename your module to have lowercase name or set 'caseSensitive' parameter to TRUE.

This is an expected behavior, please read documentation

#5100 report it
Jose Rullan at 2011/09/14 12:31pm
How to access the Module from within its views and controllers

The modules can be accessed through the CController property "module" - it returns the CWebModule to which the controller belongs. So for example if you want to know the base path of a module from within its controller or view, you can do it like this:

$myPath = $this->module->basePath;
#3707 report it
marcovtwout at 2011/04/29 10:28am
Alias ... is invalid

Note the case sensitive paths in Linux. Yii's preferred version is module name in lowercase.

I created my own module 'application/modules/Page/', developing on a Windows machine. When running the application on a Linux machine, I received the following error "Alias "page.PageModule" is invalid. Make sure it points to an existing PHP file.". Renaming the module directory to 'page' fixed the problem.

#2234 report it
Trejder at 2010/11/30 03:07am
Initial property values declaration!

To make example with initial property values (see "2. Using Module") work, you must remember that property you are setting this way must be declared in module main file!

I.e. If you are building module forum and want to be able to setup postPerPage property (as in the example), you have to edit protected/modules/forum/ForumModule.php and add in the beginning following code:

class UserModule extends CWebModule
{
    public $postPerPage = 20;
    ...
}

where 20 is a default value for this property, in case user would not specify one in module configuration.

Without this you will see error 500 saying that property ForumModule.postPerPage is an undefined.

#1746 report it
MasterAM at 2009/04/19 05:58am
Setting nested modules

I did the following in order to nest modules:

'modules'=>array(
    'module1'=>array(
        'modules'=>array(
            'module2',
            'module3'
        )
    )
)
Where modules 2 and 3 are nested within module 1

Leave a comment

Please to leave your comment.