Set layout from module controller in yii2
Solution 1
There are several options to address this issue.
Create a layout file in the appropriate module directory
An example below shows a canonical directory structure of some subDomain
module, including it's layouts (domain.php):
subDomain/
Module.php the module class file
controllers/ containing controller class files
HomeController.php the home controller class file
models/ containing model class files
views/ containing controller view and layout files
layouts/ containing layout view files
domain.php the domain layout file
home/ containing view files for HomeController
index.php the index view file
Following this simple structure, you can set any layout by its name within the module's controller:
namespace myApp\modules\subDomain\controllers;
class HomeController extends Controller {
public function actionGetDomain() {
$this->layout = 'domain'; // equals 'myApp/modules/subDomain/views/layouts/domain'
}
}
This is the most preferable way, because modules are self-contained software units that consist of its own models, layouts, controllers, etc.
Specify the complete path to the directory that contains your layout file
In some cases you might want to use a layout file that is located outside the module directory:
class HomeController extends Controller {
public function actionGetDomain() {
$this->layout = '@app/views/layouts/main';
}
}
Where @app is the base path of the currently running application, for example:
myApp/frontend
In this situation, be sure that the main.php layout file exists in the following directory:
myApp/frontend/views/layouts/main.php
Solution 2
You can set the variable in the controller.
class DefaultController extends Controller
{
public $layout = 'main.php';
}
Or by passing the complete path
public $layout = '@frontend/modules/idModule/views/layouts/main.php';
Solution 3
If I need different layout in controller, I simple add the following code
public function beforeAction($action)
{
$this->layout = 'layout'; //your layout name
return parent::beforeAction($action);
}
be sure that your layout is exists in appropriate folder
'@app/views/layouts/layout.php'
Solution 4
If you want to set it by default inside the module you can do that by writing
$this->layout = '@frontend/modules/user/views/layouts/main';
inside the init()
function of your module class your complete code will look like following
public function init() {
parent::init();
$this->layout = '@frontend/modules/user/views/layouts/main';
// custom initialization code goes here
}
Solution 5
Another one convenient way of using different layouts in your application is to create an abstract class. For example:
abstract class AdminBaseController extends Controller
{
public function beforeAction($action)
{
$this->layout = '@app/views/admin/layouts/main.php';
return parent::beforeAction($action);
}
...
}
And then just extends
your controller.
class ArticlesController extends AdminBaseController { ... }
Maulana Yusuf
Updated on February 22, 2020Comments
-
Maulana Yusuf over 4 years
I have three layouts in my layouts folder in main views folder. I added a module called subDomain. In my subDomain module I have a Controller called HomeController. In HomeController there is an action called
getDomain()
.In the
getDomain()
action I want to change the main layout togetDomainLayout
. But there is an error when I use a code:$this->layout = "getDomainLayout";
Yii2 throws:
Invalid Parameter – yii\base\InvalidParamException The view file does not exist: \myyii2\modules\subDomain\views\layouts\bersih.php
-
Jannie Theunissen over 4 yearsSetting
$this->layout
in the controller before rendering the template did not work for me. Maybe because it was a .twig template?