Установить макет из контроллера модуля в yii2


У меня есть три макета в папке "Макеты" в папке "Основные представления". Я добавил модуль под названием поддомен. В моем модуле поддомена у меня есть контроллер под названием HomeController. В HomeController есть действие, называемое getDomain().

В действии getDomain() я хочу изменить основной макет на getDomainLayout. Но есть ошибка, когда я использую код:

$this->layout = "getDomainLayout";

Yii2 бросает:

Invalid Parameter – yii\base\InvalidParamException    
The view file does not exist: \myyii2\modules\subDomain\views\layouts\bersih.php
Author: Oleksandr, 2015-08-06

7 answers

Существует несколько вариантов решения этой проблемы.

Создайте файл макета в соответствующем каталоге модулей

В приведенном ниже примере показана каноническая структура каталогов некоторого модуля subDomain, включая его макеты (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

Следуя этой простой структуре, вы можете задать любой макет по его имени в контроллере модуля:

namespace myApp\modules\subDomain\controllers;

class HomeController extends Controller {
    public function actionGetDomain() {            
        $this->layout = 'domain'; // equals 'myApp/modules/subDomain/views/layouts/domain'
    }
}

Это наиболее предпочтительный способ, поскольку модули являются автономными программными блоками, которые состоят из собственных модели, макеты, контроллеры и т.д.

Укажите полный путь к каталогу, содержащему ваш файл макета

В некоторых случаях может потребоваться использовать файл макета, расположенный за пределами каталога модуля:

class HomeController extends Controller {
    public function actionGetDomain() {
        $this->layout = '@app/views/layouts/main';
    }
}

Где @ приложение является базовым путем текущего запущенного приложения, например:

myApp/frontend

В этой ситуации убедитесь, что main.php файл макета существует в следующем каталоге:

myApp/frontend/views/layouts/main.php
 19
Author: Oleksandr, 2018-02-22 09:21:07

Если мне нужна другая компоновка в контроллере, я просто добавляю следующий код

 public function beforeAction($action)
 {
    $this->layout = 'layout'; //your layout name
    return parent::beforeAction($action);
 }

Убедитесь, что ваш макет существует в соответствующей папке

'@app/views/layouts/layout.php'
 3
Author: zhisme, 2017-02-10 15:33:35

Еще один удобный способ использования различных макетов в вашем приложении - создать абстрактный класс. Например:

abstract class AdminBaseController extends Controller
{
    public function beforeAction($action)
    {
        $this->layout = '@app/views/admin/layouts/main.php';
        return parent::beforeAction($action);
    }
    ...
}

А затем просто extends ваш контроллер.

class ArticlesController extends AdminBaseController { ... }
 3
Author: Russell Sk., 2017-02-18 05:37:52

Вы можете установить переменную в контроллере.

class DefaultController extends Controller
{
     public $layout = 'main.php';
}

Или пройдя полный путь

public $layout = '@frontend/modules/idModule/views/layouts/main.php';
 2
Author: rafaelvaloto, 2017-03-04 21:48:34

Вы можете добавить $this->layout = 'main'; в метод инициализации модуля. Тот main.php должно быть расположено в папке просмотра модулей в разделе "макеты".

 1
Author: Opad, 2016-11-24 07:35:43

Если вы хотите установить его по умолчанию внутри модуля, вы можете сделать это, написав

$this->layout   =   '@frontend/modules/user/views/layouts/main';

Внутри функции init() вашего класса модулей ваш полный код будет выглядеть следующим образом

 public function init() {

    parent::init();
    $this->layout = '@frontend/modules/user/views/layouts/main';
    // custom initialization code goes here
}
 1
Author: Muhammad Omer Aslam, 2017-07-14 12:04:26

Также вы можете задать свойство layout в construtor следующим образом:

class ArticlesController extends Controller
{
  public function __construct($id, $module, $config = array()) {
    parent::__construct($id, $module, $config);
    $this->layout='main4articles';
  }
....
 0
Author: SaidbakR, 2016-07-27 20:32:58