在yii2中设置模块控制器的布局

时间:2015-08-06 09:19:01

标签: php layout views yii2

我在主视图文件夹的layouts文件夹中有三个布局。我添加了一个名为subDomain的模块。在我的子域模块中,我有一个名为HomeController的Controller。在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

7 个答案:

答案 0 :(得分:20)

有几种方法可以解决这个问题。

在相应的模块目录

中创建布局文件

下面的示例显示了某个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';
    }
}

其中 @app 是当前正在运行的应用程序的基本路径,例如:

myApp/frontend

在这种情况下,请确保 main.php 布局文件存在于以下目录中:

myApp/frontend/views/layouts/main.php

答案 1 :(得分:5)

如果我需要在控制器中使用不同的布局,我只需添加以下代码

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

确保您的布局存在于相应的文件夹中

'@app/views/layouts/layout.php'

答案 2 :(得分:3)

在应用程序中使用不同布局的另一种便捷方法是创建一个抽象类。例如:

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 :(得分:3)

您可以在控制器中设置变量。

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

passport.use('local-login-register', new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function (err, user) {
      if (err) { 
        return done(err); 
      }
      if (!user) {
        var newUser = new User({username: username});
        User.register(newUser, password, function(err, user){
            if(err){
                return done(err);
            }
            return done(null, user);
        });
      } else if (!user.validPassword(password)) {
        return done(null, false, { message: 'Username already exists. Incorrect password.' });
      } else {
        return done(null, user);
      }
    });
  }
));

或通过传递完整路径

app.post('/quiz', function(req, res, next) {
    passport.authenticate('local-login-register', function(err, user, info) {
        var quiz = req.body.quiz;

        if (err) { return next(err); }
        if (!user) { 
          // user needs to reanswer quiz or save user answers in session
          // and redirect user to new page with registraion form
        }

        // save here your quiz answers
    })(req, res, next);
});

答案 4 :(得分:1)

您可以添加$ this-> layout ='main';在模块init方法中。 main.php应该位于layouts下的modules视图文件夹中。

答案 5 :(得分:1)

如果您想在模块内默认设置,可以通过编写

来完成
$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
}

答案 6 :(得分:0)

您也可以在layout中设置construtor属性,如下所示:

class ArticlesController extends Controller
{
  public function __construct($id, $module, $config = array()) {
    parent::__construct($id, $module, $config);
    $this->layout='main4articles';
  }
....