Acyra
Acyra

Reputation: 16054

Dynamic themes in Symfony2 using Twig

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!

Upvotes: 5

Views: 7964

Answers (3)

Javier Negreira
Javier Negreira

Reputation: 21

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)

Upvotes: 2

Javier Neyra
Javier Neyra

Reputation: 1239

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...

Upvotes: 3

hakre
hakre

Reputation: 198204

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.

Upvotes: 1

Related Questions