:我发现这个话题,答案在Zend框架2.0的控制器更改布局 :: 回答
我试图做到这一点:
public function loginAction() {
if ($this->zfcUserAuthentication()->hasIdentity()) {
return $this->redirect()->toRoute('zfcadmin');
}
$this->layout('layout/login');
return new ViewModel();
}
但是,这是行不通的。
当然,我有文件MODULE_DIR/view/layout/login.phtml
。
我试过var_dump($this->layout());
它示出了设置布局和其之前和之后,该布局之后改变$this->layout('layout/login');
线。 但事实并非如此。
如何设置控制器不同的布局?
另外, 为什么我没有,如果布局发生变化得到任何消息 ? 为什么非标准布局加载,而不是错误 ?
我想,我一定要建立布局的地方(比如我设置的路线,例如)。 有可能在配置['view_manager']['template_map']
通过添加类似:
$config = array(
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view'
),
'template_map' => array(
'layout/login' => __DIR__ . '/../view/layout/login.phtml',
),
),
);
-喜欢说有 :
当然,你需要定义这些布局,太...只是检查应用模块module.config.php
来看看如何定义布局。
这并没有帮助我:(
更新1
尝试这样:
public function loginAction() {
if ($this->zfcUserAuthentication()->hasIdentity()) {
return $this->redirect()->toRoute('zfcadmin');
}
$layout = $this->layout();
$layout->setTemplate('layout/login');
return new ViewModel();
}
作为@alex建议。 不工作:“(同样的结果没有。 return new ViewModel();
行。
你自己检查文件:
- AdminController.php (在loginAction)
- module.config.php (以确保我加
layout/login
正确
更新2
我试着调试你的建议。
我更新__invoke
功能:
public function __invoke($template = null)
{
var_dump($template);
die();
if (null === $template) {
return $this->getViewModel();
}
return $this->setTemplate($template);
}
有一些情况:
随着代码,你的建议:
$layout = $this->layout();
$layout->setTemplate('layout/login');
它显示为空。 于是方法被调用,但$template
是空的变量。
随着代码,从后 ,我给了我文章的开始:
$this->layout('layout/login');
return new ViewModel();
它显示string(12) "layout/login"
。
没有任何代码(这样的布局layout/admin
加载(默认ZfcAdmin
),它表明: string(12) "layout/admin"
。
如果我加载/
我的网站页面它的加载非标准布局(在这两种情况下,有或没有layout/layout
模块配置。
更新3
我尝试这样做:
$layout = $this->layout();
var_dump($layout->getTemplate());
$layout->setTemplate('layout/login');
var_dump($layout->getTemplate());
die();
在控制器。 它显示: string(13) "layout/layout" string(12) "layout/login"
。 所以布局发生变化。 但是非标准布局layout/layout
呈现,而不是layout/login
。 :(
因为你使用ZfcAdmin
并有use_admin_layout
该模块,你就尝试在设置布局登录路由中启用选项是ZfcAdmin的子路径,管理员布局监听器被踢,过写作模板你”重新尝试在你的控制器动作设定。
这也许最简单的禁用zfcadmin布局,写自己的监听器和处理登录布局的具体情况存在。 你可以做,使用基本上是ZfcAdmin使用在Module.php一两个的调整同样的方法...
一定要禁用ZfcAdmin布局
'zfcadmin' => array(
'use_admin_layout' => false,
),
然后,使用模块名作为配置重点,建立自己的相同配置的版本...
'myzfcadmin' => array(
'use_admin_layout' => true,
'admin_layout_template' => 'layout/admin',
// you could even define a login layout template here
'login_layout_template' => 'layout/login',
),
接下来,在MyZfcAdmin/Module.php
添加侦听器,几乎完全一样,在ZfcAdmin只有它检查myzfcadmin
配置值,而不是...
public function onBootstrap(MvcEvent $e)
{
$app = $e->getParam('application');
$em = $app->getEventManager();
$em->attach(MvcEvent::EVENT_DISPATCH, array($this, 'selectLayoutBasedOnRoute'));
}
public function selectLayoutBasedOnRoute(MvcEvent $e)
{
$app = $e->getParam('application');
$sm = $app->getServiceManager();
$config = $sm->get('config');
if (false === $config['myzfcadmin']['use_admin_layout']) {
return;
}
$match = $e->getRouteMatch();
$controller = $e->getTarget();
if (!$match instanceof \Zend\Mvc\Router\RouteMatch
|| 0 !== strpos($match->getMatchedRouteName(), 'zfcadmin')
|| $controller->getEvent()->getResult()->terminate()
) {
return;
}
if ($controller instanceof \MyZfcAdmin\Controller\AdminController
&& $match->getParam('action') == 'login'
) {
// if you'd rather just set the layout in your controller action just return here
// return;
// otherwise, use the configured login layout ..
$layout = $config['myzfcadmin']['login_layout_template'];
} else {
$layout = $config['myzfcadmin']['admin_layout_template'];
}
$controller->layout($layout);
}
正如你所看到的,我添加了代码检查控制器是特定AdminController实例和登录操作,如果是的话,设置备用模板,否则使用默认的,没有必要现在担心它在你的控制器。
添加您的布局视图管理器在module.config.php模板图
像这样:
// View file paths
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array
'layout/login' => 'path_to_layout_file'
)
)
然后,在你的控制器尝试设置这样的布局,使用setTemplate()方法:
$layout = $this->layout();
$layout->setTemplate('layout/login');
编辑,以下是从Zend库的代码:
里面Zend\Mvc\Controller\Plugin\Layout
通知此方法:
/**
* Invoke as a functor
*
* If no arguments are given, grabs the "root" or "layout" view model.
* Otherwise, attempts to set the template for that view model.
*
* @param null|string $template
* @return Model|Layout
*/
public function __invoke($template = null)
{
if (null === $template) {
return $this->getViewModel();
}
return $this->setTemplate($template);
}
如果你不提供一个模板,它会调用这个方法:
/**
* Retrieve the root view model from the event
*
* @return Model
* @throws Exception\DomainException
*/
protected function getViewModel()
{
$event = $this->getEvent();
$viewModel = $event->getViewModel();
echo '<pre>' . print_r($viewModel, true) . '</pre>';die;
if (!$viewModel instanceof Model) {
throw new Exception\DomainException('Layout plugin requires that event view model is populated');
}
return $viewModel;
}
注意print_r
说法,如果你看它,它会告诉你这一点:
Zend\View\Model\ViewModel Object
(
[captureTo:protected] => content
[children:protected] => Array
(
)
[options:protected] => Array
(
)
[template:protected] => layout/layout
[terminate:protected] =>
[variables:protected] => Zend\View\Variables Object
(
[strictVars:protected] =>
[storage:ArrayObject:private] => Array
(
)
)
[append:protected] =>
)
注意[template:protected] => layout/layout
就是为什么我说我想的Zend默认为布局。
因此,进入该文件,在__invoke
方法和做echo $template;die;
当你与你的设置布局$this->setTemplate('layout/login')
在您的控制器,看看它甚至获得通过那里。 这时,你可能能够跟踪它更好。
编辑:设置多个布局。
这里是你可以设置你的模块布局,努力减少冲突或某事的可能性的一种方式被覆盖。
// where $sm is the service manager
$config = $sm->get('config');
$config = array_merge($config, include '/path_to_config/layouts.config.php');
if (isset($config['module_layouts'][$moduleNamespace]))
{
$controller->layout($config['module_layouts'][$moduleNamespace]);
}
而你的布局配置可能看起来是这样的:
'module_layouts' => array(
'_default' => 'layout/layout',
'admin' => 'layout/admin',
'foo' => 'layout/foo',
'login' => 'layout/login' // etc, etc
),