Module Layout

I created a module called administration and I wanted to use a layout in administration/views/layouts called main. The DefaultController insisted on using the application layout, I noticed when I searched the forums a few other people had the same problem and used a work around where they set the layout in the controller and not in the module as is recommended in the documentation.

The documentation recommends setting module::layout and module::layoutPath and as CController defaults to a NULL layout it will use the module layout.

What I missed however is that the DefaultController generated by gii during module generation actually extends Controller not CCcontroller and if you generated your app from the CLI tool then the layout for Controller defaults to:


public $layout='//layouts/column1';

Hope this saves someone from the stupid mistake I made.

My sollution was to have DefaultController extend CController and do:




$this->layoutPath = Yii::getPathOfAlias('administration.views.layouts');

$this->layout = 'administration';



in AdministrationModule::init()

NOTE: moved to proper section (Tips, Snippets, tutorials instead of General Discussion)

Hi Luke

welcome to the yii forum and thanks for the useful post

In case you’re using the module generated by gii, you’ll also need to do the following:

  1. Copy the files from the main ‘layouts’ folder into your module’s layouts folder (it is empty);

  2. Remove from your module’s views/default/index.php :




<?php

$this->breadcrumbs=array(

	$this->module->id,

);

?>



  1. In AdminModule.php (or whatever your module’s name) init() method:



$this->layoutPath = Yii::getPathOfAlias('admin.views.layouts');

$this->layout = 'main';



  1. Extend your module’s DefaultController from CController instead of Controller (as mentioned by Mr. Luke ).

  2. Finally, customize your layouts by modifying the files in your module’s ‘layouts’ folder.

Sorry to jump on an old thread, and it’s really good advice, but I’d like to add one thing, in case anyuone’s in the situation I’m in where I need a method located in the Controller class. Instead of extending the default controller from CController, you can still extend from Controller (as that extends from CController anyway), only you’ll need to remove the following line from the Controller class;

[PHP]public $layout=’//layouts/column1’;[/PHP]

as this is overwriting the value set in the init() method for the module controller

[size=2]Thank you VladimirV [/size]:)

Wouldn’t setting $layout in your Controller class to ‘/layouts/main’; instead of ‘//layouts/main’; just work?

(after copying the layout files into your module that is)

‘//’ means use the top-most one. while just ‘/’ means the defined in your current module or ‘application’

To have a personalized layout for the module you also can create a components/Controller class in your module and extending it from CController class.

It is not a good idea to overwrite the layout property in the application Controller class because these changes will apply for the entire application, not only for the module.

Defining a Controller class for a specific module you will be able to customize the module’s Controller class, without changing the entire application behaviour.

In fact, it works just using:


public $layout='column1';

in your DefaultController (or XxxxController being Xxxx your module id).

column1.php must be a layout in your module layouts folder.