简体   繁体   中英

Zf2 changing layout

I am trying to change the layout based on my routes, here what I have done until now:

<?php namespace Application\Listener;

use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;
use Zend\View\Model\ModelInterface as Model;

class LayoutListener extends AbstractListenerAggregate
{
    /**
     * Attach one or more listeners
     * Implementors may add an optional $priority argument; the EventManager
     * implementation will pass this to the aggregate.
     * @param EventManagerInterface $events
     * @return void
     */
    public function attach(EventManagerInterface $events)
    {
        $sharedEvents = $events->getSharedManager();
        $this->listeners[] = $sharedEvents->attach(
            'Zend\Mvc\Controller\AbstractController',
            MvcEvent::EVENT_DISPATCH,
            array($this, 'handleLayouts'),
            -99);
    }

    public function handleLayouts(MvcEvent $event)
    {
        $viewModel = $event->getViewModel();
        if (!$viewModel instanceof Model) {
            return;
        }

        $routeMatch = $event->getRouteMatch();
        $resolver = $event->getApplication()
            ->getServiceManager()
            ->get('Zend\View\Resolver\TemplatePathStack');

        if ('Application\Controller\Index' !== $routeMatch->getParam('controller')) {
            return;
        }

        switch ($routeMatch->getParam('action')) {
            case 'index':
                $template = 'layout/layout';
                break;
            case 'home':
                $template = 'layout/home';
                break;
            default:
                $template = null;
                break;
        }

        /**
         *
         * Don't know why, but to set a template must use $event->getViewModel()
         * and for terminal must use $event->getResult(), otherwise it won't works
         *
         */

        // if template is resolvable, use it, otherwise go terminal
        if ($template && $resolver->resolve($template)) {
            $viewModel->setTemplate($template);
        } else {
            if ($event->getResult() instanceof Model) {
                $event->getResult()->setTerminal(true);
                $viewModel->setTerminal(true);
            }
        }
    }
}

Module.php

public function onBootstrap(MvcEvent $e)
{
    $translator = $e->getApplication()->getServiceManager()->get('translator');
    $translator->setLocale(\Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']))
        ->setFallbackLocale('en_US');

    $eventManager = $e->getApplication()->getEventManager();
    $eventManager->attachAggregate(new LayoutListener());

    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
}

There is one thing I don't get, if I want to change the layout, I must use

  • $event->getViewModel()->setTemplate($template);

otherwise it won't work, and if I want to set the viewModel terminal, I must use

  • $event->getResult()->setTerminal(true);

otherwise it won't work, can someone explain me why ?

What I'm trying to achieve it's the following: I have one template for index/ that initialize an iFrame loading the content of any other route, so in the index layout I have set up the menu and any other pages don't need to have a layout, as the index/ one is used.

Now I want a subpage having a custom layout (custom display) so, based on the route, I set a new layout to the viewmodel.

You can add child-views to your view-model (if you are in a Controller) - if you make an own controller for your subview (or subpage):

$view = new ViewModel(array(
    // parameters
));

$view->addChild($this->forward()->dispatch('SubpageController', array(
    'action' => 'index',
)), 'contentOfSubpage');

return $view;

in the template, you can access the contents of the SubpageController like this:

<?php echo $contentOfSubpage; ?>

at least, thats how you can combine multiple controllers, therefore different layouts

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM