Yii Framework Forum: default layout in CWebModule - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

default layout in CWebModule Rate Topic: ***** 2 Votes

#1 User is offline   Job Kelderman 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 30-March 11

Posted 30 March 2011 - 10:55 AM

Hi all,

I've just started working with Yii nad I've found something that doesn't work like I expected after reading the manual.

I've got an AdminModule, extending CWebModule in modules/admin/AdminModule.php
I've got a layout: modules/admin/views/layout/main.php

I want all controllers in this module to use this layout. So I've added the following property in the class AdminModule (and didn't add anything to the DefaultController):

public $layout = "main";

When I open index.php?r=admin, the default layout from Yii is used.

However, if I set the property mentioned above in the DefaultController in modules/admin/controllers/DefaultController.php, the correct layout is used.

The documentation about CWebModel->layout is:

the layout that is shared by the controllers inside this module. If a controller has explicitly declared its own layout, this property will be ignored. If this is null (default), the application's layout or the parent module's layout (if available) will be used. If this is false, then no layout will be used.

PS: adding $this->layout = "main" in the public function init() from the AdminModule doesn't work either.

Have I misinterpreted the usage of the layout property in the CWebModel?
2

#2 User is offline   PeRoChAk 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 578
  • Joined: 26-November 10
  • Location:Lahore, Pakistan

Posted 31 March 2011 - 06:37 AM

You need to set the layout path by using

Quote

$this->layoutPath="protected/modules/module/views/layouts";

Then set the layout

Quote

$this->layout="my layout";


Please note that
By using
// in the layout will points to protected/views/layouts
using / to use the modules/views/layouts
while using one layout in another layout
Cheers
Perochak
Web Design - Logo Design - Application Development

My Blog | Forums Comparison
0

#3 User is offline   Job Kelderman 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 30-March 11

Posted 31 March 2011 - 10:28 AM

View PostPeRoChAk, on 31 March 2011 - 06:37 AM, said:

You need to set the layout path by using

Then set the layout


Please note that
By using
// in the layout will points to protected/views/layouts
using / to use the modules/views/layouts
while using one layout in another layout

Thank you very much, setting the layoutPath in the Module works!
I don't understand why it works without setting the layoutPath if I define the layout in the Controller, but I'm happy it now works as intended.
0

#4 User is offline   thunderbolt 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 26-March 11

Posted 08 July 2011 - 07:22 AM

Another solution is to edit the $layout declaration in your "protected/components/Controller.php" file to read as follows:

$layout = "column1";


instead of...

$layout = "//layout/column1";


Then your $this->layout declaration in init() in the AdminModule.php file will work.

Like PeRoChAk mentioned in his post, the double forward slash (//) points to protected/views/layouts because you are extending the protected/components/Controller.php class file and in that case it takes protected/views/layouts as the default path to your views instead of the module's view directory.

I guess you can set $this->layoutPath to the module's view path but when I tried it for some reason it could not find the path. If setting $this->layoutPath works for you then PeRoChAk's suggestion is better and cleaner in my opinion. In that case I would recommend going with his advice.

Anyway, here's where I found the solution: code.google.com/p/yii/issues/detail?id=1043

Hope this helps a little.
0

#5 User is offline   Backslider 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 363
  • Joined: 23-July 09

Posted 14 August 2011 - 09:57 PM

Gii does not generate default layouts for modules, so I just copy them over from the main application and remove the extra slash:

<?php $this->beginContent('//layouts/main'); ?>


to:

<?php $this->beginContent('/layouts/main'); ?>


The ONLY solution that I have found that works with the latest Yii is to put the following in your module DefaultController.php:

    public $layout = "column2";


I have looked at a lot of posts and alternative solutions, but this is the only one that works.

I believe its the correct solution, because class DefaultController extends Controller :)
We were all once expert at....... nothing.

yii-language-behavior

My Blog
1

#6 User is offline   VladimirV 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 03-October 11

Posted 07 November 2011 - 08:16 AM

View PostBackslider, on 14 August 2011 - 09:57 PM, said:

Gii does not generate default layouts for modules, so I just copy them over from the main application and remove the extra slash:

<?php $this->beginContent('//layouts/main'); ?>


to:

<?php $this->beginContent('/layouts/main'); ?>


The ONLY solution that I have found that works with the latest Yii is to put the following in your module DefaultController.php:

    public $layout = "column2";


I have looked at a lot of posts and alternative solutions, but this is the only one that works.

I believe its the correct solution, because class DefaultController extends Controller :)


Thanks, this really works.
0

#7 User is offline   stelian 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 06-December 11

Posted 23 December 2011 - 03:17 AM

Quote

Gii does not generate default layouts for modules, so I just copy them over from the main application and remove the extra slash:

<?php $this->beginContent('//layouts/main'); ?>

to:

<?php $this->beginContent('/layouts/main'); ?>

The ONLY solution that I have found that works with the latest Yii is to put the following in your module DefaultController.php:

public $layout = "column2";


Hey,

I have tried to solutions above, but it didn't work for me (yii framework v1.1.8.)
After removing the extra slash, the main layout was not found anymore.

So, the solution was changing the path in the layout:

<?php $this->beginContent('//layouts/main'); ?>


to

<?php $this->beginContent('admin.views.layouts.main'); ?>



where admin is the name of my module.


In the controller file, I also needed to add:


  public $layout='/layouts/column1'; 

0

#8 User is offline   kamankily 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 09-August 11

Posted 30 January 2012 - 02:59 PM

This solution worked Yii 1.1.9

in column2.php
<?php $this->beginContent('/layouts/main'); ?>

and in DefaultController of module
 
public $layout='/layouts/column2';

To me, the changes are the chances.
0

#9 User is offline   szaqal83 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 25
  • Joined: 14-September 11

Posted 13 April 2012 - 03:47 AM

I still can't get it to work. In my case it looks like this. I've only one controller in main app "protected/controllers/SiteController" and one module called "admin" with "protected/modules/admin/controllers/DefaultController". I've set "errorAction" for "errorHandler" in protected/config/main.php to "site/error" and this view is being rendered for every error in my app (SiteController and admin module controllers errors) but I want to set diffrent errorHandler for module errors.

I use diffrent layout for "protected/controllers/SiteController":
- SiteController $layout is set to:
public $layout = '//layouts/main';

and "protected/modules/admin/controllers/DefaultController":
- DefaultController $layout is set to:
public $layout = '/layouts/column1';

- "protected/modules/admin/views/layouts/column1" beginContent arg is: "/layouts/main".

- admin module init() looks like this:
public function init()
	{
		$this->setImport(array(
			'admin.models.*',
			'admin.components.*',
		));
		
		$this->setComponents(array(			
			'errorHandler'=>array(
				'errorAction'=>'admin/default/error',
			),
			
			'user' => array(          
                'class' => 'CWebUser',
				'allowAutoLogin' => true,
				'loginUrl' => Yii::app()->createUrl('admin/default/login'),
            )
        ));
}

The problem is:
- if I access www.domain.pl/site/xyz - error view is rendered in "protected/views/layouts/main"

- if I access www.domain.pl/admin/xyz - is also rendered in "protected/views/layouts/main" rather than "protected/modules/admin/views/layouts/column1".

Am I doing something wrong?

UDPATE:
The problem was in the init() function it seems that setting components the way that I've done it isn't working. New init looks like this:
Yii::app()->setComponents(array(
			'errorHandler'=>array(
				'errorAction'=>'admin/default/error',
			)
        ));

setComponents() should be called for Yii::app() not module. Hope it helps somebody else with similar problem.
0

#10 User is offline   msoa 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 258
  • Joined: 15-August 12

Posted 03 June 2013 - 12:31 PM

View PostJob Kelderman, on 30 March 2011 - 10:55 AM, said:

Hi all,

I've just started working with Yii nad I've found something that doesn't work like I expected after reading the manual.

I've got an AdminModule, extending CWebModule in modules/admin/AdminModule.php
I've got a layout: modules/admin/views/layout/main.php

I want all controllers in this module to use this layout. So I've added the following property in the class AdminModule (and didn't add anything to the DefaultController):

public $layout = "main";

When I open index.php?r=admin, the default layout from Yii is used.

However, if I set the property mentioned above in the DefaultController in modules/admin/controllers/DefaultController.php, the correct layout is used.

The documentation about CWebModel->layout is:

the layout that is shared by the controllers inside this module. If a controller has explicitly declared its own layout, this property will be ignored. If this is null (default), the application's layout or the parent module's layout (if available) will be used. If this is false, then no layout will be used.

PS: adding $this->layout = "main" in the public function init() from the AdminModule doesn't work either.

Have I misinterpreted the usage of the layout property in the CWebModel?

I think this is suitable answer for future readers. However is late.
In CController as default public $layout property is commented. and when we extends a Controller from CController, the Controller have not a property named $layout.
Hence when we declare $layout in a class extended from CWebModule for defining default layout for all Controllers, this property have not effect on controllers.

So for defining default layout for all module controllers we need declare the $layout property in the controller. With doing this we can simply define default layout for all controllers. I hope that is helpful.
0

#11 User is offline   alumi 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 04-March 13

Posted 17 August 2013 - 02:28 AM

I found a cleaner solution (well, at least for me).

Firstly, I used Gii to create my Admin module and my module's controllers. It will result a set of controller extending from Controller class (protected/components/Controller.php) -> The problem is here.

As mentioned in the documentation, CWebModule::layout will be used for all controllers within the module, UNLESS the controller wants to use its own layout (by declaring $this->layout).

So, all my controllers of the module inherits $layout property from Controller class, that's why CWebModule::layout is not used.

I was thinking of 2 solutions:

SOLUTION 1

  • Create an AdminController (modules/admin/components/AdminController.php), extending from CController, with $layout = <your admin layout>;
  • All of your module's controllers should extend from this class.
  • Remove all $layout property in your module controller (as Gii automatically created it);

This makes things quite clear and structural: All your front-end controller is using another controller base (Controller), and your module is using another one (AdminController).

SOLUTION 2

  • In your AdminModule::init(), specify your admin layout path.

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

  • In your Controller class, change $layout to 'main':

    public $layout = 'main';

    This will tell the controller to look for the main.php file in the specified layoutPath
  • Now you can use 2 layouts separately.
    • Your front-end layout: views/layouts/main.php
    • Your admin module layout: modules/admin/views/layouts/main.php

    Remember that the filename should be the same.
  • Remove all $layout property in your module controller (as Gii automatically created it);
  • If you want to use column1/2, you need to change the parameter of beginContent method.

There might be limitations to these solutions, but it fits my need, and in any chance it could fit someone's :)
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users