As you can see I have a user module under common directory and it has some controllers which one of them is profileController:
class profileController extends Controller
{
public function actionEdit()
{
//doing something
$this->render('edit', $params);
}
}
That controller should be able to be accessed from frontend and backend, and should follow the layout from where it is called (if it’s called from frontend, it should use frontend’s layout, so does for backend).
What I have done is creating a Controller in /frontend/components:
class Controller extends CController
{
public $layout = '//layouts/frontend1';
}
So the profileController actually extends Controller class from frontend or backend (determined by separate config in frontend/backend) to inherit the layout name. I don’t specify it in the profileController since it’s in the module, where I think we shouldn’t hardcode the frontend/backend’s layout name there.
This approach does work, however if I have some layouts, I need to create many Controller classes just for specifying the layout name! So… is there any better solution for this?
I don’t know how the Yii boilerplate structure works but how about tried putting the following code in the beforeControllerAction function in your UserModule.php file?
public function beforeControllerAction($controller, $action)
{
if(parent::beforeControllerAction($controller, $action))
{
$controller->layout='//layouts/<layoutname>';
// this method will be called before any controller action in that module takes place.
return true;
}
else
return false;
}
You can use beforeControllerAction function in your UserModule.php but your have to set a session or cookie or in GET method to specify from where the action comes from.
Say in your url add url?layout=admin or url?layout=frontend
public function beforeControllerAction($controller, $action)
{
if(parent::beforeControllerAction($controller, $action))
{
if(Yii::app()->request->getQuery('layout') == 'admin')
$controller->layout='//layouts/<layoutname>'; //Admin layout name
else
$controller->layout='//layouts/<layoutname>'; //Front End layout name
// this method will be called before any controller action in that module takes place.
return true;
}
else
return false;
}
Even the above code not works just create a cookie and set the layout as follows
Yii::app()->request->cookies['layout'] = new CHttpCookie('layout', 'admin'); //When accessing from admin
Yii::app()->request->cookies['layout'] = new CHttpCookie('layout', 'frontend'); //When accessing from frontend
then change the beforeControllerAction accordingly…
If above all does’t works better go with session and use if condition with beforeControllerAction
Great, both of you enlightened me I didn’t know about beforeControllerAction before. I think I can use it combined with application parameter, which in YiiBoilerplate I can specify parameter in separated config for frontend and backend, so I’ll put the layout name there and read it in beforeControllerAction method.