Michaël Perrin
Michaël Perrin

Reputation: 6258

How to serve same functionality with different layouts in a Symfony2 app?

I have in a Symfony2 application the following bundle architecture:

Several features are implemented in the CommonBundle. These features have to be available in the 2 other bundles.

The FirstBundle and SecondBundle have therefore their own features + the ones of the CommonBundle. These bundles each have their own host defined in the main application routing.yml file.

What I'm trying to do:

Features of the CommonBundle should be displayed with the layout of the current bundle.

For instance, if I hit http://firstbundle.myapp.com/common/feature1, I should see the layout of the FirstBundle bundle.

And if I hit http://secondbundle.myapp.com/common/feature1, the layout of the SecondBundle bundle should be used.

How can I do that?

I can't use bundle inheritance as the same bundle can't be extended twice.

In my current implementation, each bundle imports the routes of the CommonBundle in its own host.

Upvotes: 2

Views: 361

Answers (1)

Nicolai Fröhlich
Nicolai Fröhlich

Reputation: 52493

You should create a controller response listener and change the template name depending on the request hostname in there.

A good read is the How to setup before/after filters chapter of the documentation.

You could aswell use a twig extension registering a global variable and decide which template to extend inside your base template:

config.yml

services:
    twig.extension.your_extension:
        class: Vendor\YourBundle\Twig\Extension\YourExtension
        arguments: [ @request ]         
        tags:
            - { name: twig.extension, alias: your_extension }

YourExtension.php

use Symfony\Component\HttpFoundation\Request;

class YourExtension extends \Twig_Extension
{
   protected $request;

   public function __construct(Request $request)
   {
        $this->request = $request;
   }

   public function getGlobals()
   {
       // some logic involving $this->request

       $baseTemplate = ($this->request->getHost() === 'first.host.tld') ? 'FirstBundle::base.html.twig' : 'SecondBundle::base.html.twig';

       return array(
          'base_template' => $baseTemplate,
       );
   }

   public function getName()
   {
       return 'your_extension';
   }

base.html.twig

{% extends base_template %}

Upvotes: 2

Related Questions