5
votes

I'm designing a multi-tenant application for Symfony2, where each tenant can have a theme that overrides the default application templates. So a theme will have a unique base.html.twig file, and may or may not include other files that override the default template files.

Symfony2 already checks app/Resources/views for templates that override the bundle templates. But Symfony2 assumes app/Resources/views has just one set of templates that can override the default templates. I want to dynamically check a tenant's custom theme folder for various overriding templates, e.g.:

  1. Theme:
    • app/Resources/views/theme1/base.html.twig
  2. Theme:
    • app/Resources/views/theme2/base.html.twig
    • app/Resources/views/theme2/SomeBundle/Resources/views/page.html.twig

I'm not sure the best way to structure this in Symfony2 and to configure it in Twig. Should I pile all of the different themes into folders in app/Resources/views? Or should I create some kind of ThemeBundle that handles everything? Thanks!

3
What did your tests reveal so far?hakre
I'm leaning towards putting the themes in the app/Resources/views directory, but I'm not sure how to dynamically check the correct theme. Also, in the future, we may want to allow users to edit the theme twig files...so that makes me think they should be a bundle.Acyra

3 Answers

3
votes

i have a bad time trying to do something like this... i i looked at the code of liipthemebundle and it need to much configuration... i looked over the internet a lot... and then i started to think... and what i saw was this:

http://symfony.com/doc/current/book/templating.html#overriding-bundle-templates

there a lot of usefull info in that page... but what took me to a simple solution was this fact: symfony look in app/Resources/[MyBundle] for templates and things... and i found out that the service responsible for that is this the file_locator service...

so, if you define a parameter, lets say skin in parameters.yml

and add this lines to your app/config/config.yml

file_locator:
        class: %file_locator.class%
        arguments: [@kernel,%kernel.root_dir%/Resources/skins/%skin%]

you have yours skins...

2
votes

i had the same problem, and i used LiipThemeBundle to solve it. it took me a few minutes to configure:

  • install the bundle with composer, and activate it.
  • config the bundle (app/config/config.yml)


    liip_theme:
        themes: ['theme1', 'theme2', 'theme3']
        active_theme: 'theme1'

  • copy three lines to app/config/routing.yml


    liip_theme:
        resource: "@LiipThemeBundle/Resources/config/routing.xml"
        prefix: /theme

  • move the files from Resources\views\ to Resources\themes\theme1\

and ready !!

after that, when i render a template in the controller:



    return $this->render('AcmeDemoBundle:Demo:index.html.twig');

it uses the file located in "Resources\themes\theme1\Demo\index.html.twig". when i need to switch to another theme, in my case, because some entities of my model have custom themes, i can do it with one line of code:

 

    $this->get('liip_theme.active_theme')->setName('theme2');
    return $this->render('AcmeDemoBundle:Demo:index.html.twig');

and now uses the file located in "Resources\themes\theme2\Demo\index.html.twig"

that easy !! (and clean)

1
votes

Learn about bundles: Symfony2 Bundle Structure, a use case - Bundles support themes.

Learn about theme resolution & cascade: LiipThemeBundle - comes with code to read and should have everything you're looking for.