我知道有不同的方法来选择布局文件。可以办到
- 在配置中
- with
Yii::$app->layout = '...'
- with
Controller::$layout
我有一些使用不同布局文件的控制器,如下所示:
class FirstController extends yii\web\Controller {
public $layout = 'firstLayout';
...
}
class SecondController extends yii\web\Controller {
public $layout = 'secondLayout';
...
}
现在我有了 Yii2 中默认的错误处理。所以有一个配置设置'errorHandler'
to 'site/error'
(这是一个全局错误处理程序)。还有 SiteController
class SiteController extends yii\web\Controller {
public function actions() {
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
];
}
...
}
我的问题错误处理程序默认使用 SiteController 的布局文件。但它应该是实际调用的控制器中的那个。我怎样才能实现这个目标动态地?
它可以在应用程序事件中设置:
$config = [
'id' => 'my-app',
'basePath' => dirname(__DIR__),
'params' => ...
'bootstrap' => ['log'],
'components' => [
...
'errorHandler' => [
'errorAction' => 'site/error',
],
...
],
'on beforeAction' => function (yii\base\ActionEvent $e) {
if ($e->action->id === 'error' && $e->action->controller->id === 'site') {
// this is the second step
if (isset(Yii::$app->params['requested-layout']))
$e->action->controller->layout = Yii::$app->params['requested-layout'];
} else {
// this happens first
Yii::$app->params['requested-layout'] = $e->action->controller->layout;
}
},
];
会发生什么:请注意,如果操作中抛出异常,则 beforeAction 会被调用两次。第二次调用是由错误处理程序引起的。现在,在每个常规请求中,当前布局都会存储在某处(我使用了全局可用的Yii 参数 http://www.yiiframework.com/doc-2.0/guide-structure-applications.html#params为了这)。如果由于某种原因需要调用错误处理程序,则包含错误操作控制器的布局文件将被采用到存储的布局文件中。
开放式问题:
- 不考虑模块。需要更多逻辑。
-
'on beforeAction' http://www.yiiframework.com/doc-2.0/guide-structure-applications.html#beforeAction被呼叫并且
Yii::$app->params['requested-layout']
将被设置only对于现有的操作和控制器(和模块)以及操作方法中引发的异常。
- 如果路由无效或发生其他错误,将直接调用 beforeAction 处理程序
site/error
without之前执行它。因此布局文件没有被采用(可以通过实现来解决'on beforeRequest'
)并且将使用默认布局(可以是真正的默认布局,也可以以不同的方式设置(例如 SiteController 的 $layout 属性)。
- 如果布局文件不在一个文件夹中(在中定义),则可能需要更多逻辑Application::$layoutFiles http://www.yiiframework.com/doc-2.0/yii-base-module.html#%24layoutPath-detail).
我认为通过扩展这条线(未测试)也可以轻松地考虑该模块:
Yii::$app->params['requested-layout'] = $e->action->controller->layout ?:
$this->action->controller->module->layout;
让我知道这是否合理或错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)