Set layout from module controller in yii2

37,084

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 { ... }
Share:
37,084
Maulana Yusuf
Author by

Maulana Yusuf

Updated on February 22, 2020

Comments

  • Maulana Yusuf
    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 to getDomainLayout. 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
    Jannie Theunissen over 4 years
    Setting $this->layout in the controller before rendering the template did not work for me. Maybe because it was a .twig template?