如何改变布局控制器ZendFramework2?(How to change layout in c

2019-10-28 09:38发布

:我发现这个话题,答案在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 。 :(

Answer 1:

因为你使用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实例和登录操作,如果是的话,设置备用模板,否则使用默认的,没有必要现在担心它在你的控制器。



Answer 2:

添加您的布局视图管理器在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
),


文章来源: How to change layout in controller in ZendFramework2?