title: Zf2 changing layout
body: <p>I am trying to change the layout based on my routes, here what I have done until now:</p>
  
  
  
  <pre class="lang-php prettyprint-override"><code>&lt;?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-&gt;getSharedManager();
          $this-&gt;listeners[] = $sharedEvents-&gt;attach(
              'Zend\Mvc\Controller\AbstractController',
              MvcEvent::EVENT_DISPATCH,
              array($this, 'handleLayouts'),
              -99);
      }
  
      public function handleLayouts(MvcEvent $event)
      {
          $viewModel = $event-&gt;getViewModel();
          if (!$viewModel instanceof Model) {
              return;
          }
  
          $routeMatch = $event-&gt;getRouteMatch();
          $resolver = $event-&gt;getApplication()
              -&gt;getServiceManager()
              -&gt;get('Zend\View\Resolver\TemplatePathStack');
  
          if ('Application\Controller\Index' !== $routeMatch-&gt;getParam('controller')) {
              return;
          }
  
          switch ($routeMatch-&gt;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-&gt;getViewModel()
           * and for terminal must use $event-&gt;getResult(), otherwise it won't works
           *
           */
  
          // if template is resolvable, use it, otherwise go terminal
          if ($template &amp;&amp; $resolver-&gt;resolve($template)) {
              $viewModel-&gt;setTemplate($template);
          } else {
              if ($event-&gt;getResult() instanceof Model) {
                  $event-&gt;getResult()-&gt;setTerminal(true);
                  $viewModel-&gt;setTerminal(true);
              }
          }
      }
  }
  </code></pre>
  
  <p><strong>Module.php</strong></p>
  
  <pre class="lang-php prettyprint-override"><code>public function onBootstrap(MvcEvent $e)
  {
      $translator = $e-&gt;getApplication()-&gt;getServiceManager()-&gt;get('translator');
      $translator-&gt;setLocale(\Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']))
          -&gt;setFallbackLocale('en_US');
  
      $eventManager = $e-&gt;getApplication()-&gt;getEventManager();
      $eventManager-&gt;attachAggregate(new LayoutListener());
  
      $moduleRouteListener = new ModuleRouteListener();
      $moduleRouteListener-&gt;attach($eventManager);
  }
  </code></pre>
  
  <p>There is one thing I don't get, if I want to change the layout, I must use </p>
  
  <ul>
  <li><code>$event-&gt;getViewModel()-&gt;setTemplate($template);</code></li>
  </ul>
  
  <p>otherwise it won't work, and if I want to set the viewModel terminal, I must use </p>
  
  <ul>
  <li><code>$event-&gt;getResult()-&gt;setTerminal(true);</code></li>
  </ul>
  
  <p>otherwise it won't work, can someone explain me why ?</p>
  
  <p>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.</p>
  
  <p>Now I want a subpage having a custom layout (custom display) so, based on the route, I set a new layout to the viewmodel.</p>