This bundle provides you the possibility to add themes to each bundle. In your
bundle directory it will look under Resources/themes/<themename>
or fall back
to the normal Resources/views if no matching file was found.
Installation is a quick (I promise!) 3 step process:
- Download LiipThemeBundle
- Enable the Bundle
- Import LiipThemeBundle routing
Run the following composer require command:
$ php composer.phar require liip/theme-bundle
Finally, enable the bundle in the kernel:
<?php
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Liip\ThemeBundle\LiipThemeBundle(),
);
}
Now that you have activated and configured the bundle, all that is left to do is import the LiipThemeBundle routing files.
In YAML:
# app/config/routing.yml
liip_theme:
resource: "@LiipThemeBundle/Resources/config/routing.xml"
prefix: /theme
Or if you prefer XML:
<!-- app/config/routing.xml -->
<import resource="@LiipThemeBundle/Resources/config/routing.xml" prefix="/theme" />
You will have to set your possible themes and the currently active theme. It is required that the active theme is part of the themes list.
# app/config/config.yml
liip_theme:
themes: ['standardTheme', 'winter_theme', 'weekend']
active_theme: 'standardTheme'
You can provide specific themes or even templates for different devices (like: desktop, tablet, phone, plain). Set option autodetect_theme
to true for setting current_device
parameter based on the user agent:
# app/config/config.yml
liip_theme:
autodetect_theme: true
Then in path_patterns
you can use %%current_device%%
parameter (with your device type as value)
# app/config/config.yml
liip_theme:
path_patterns:
app_resource:
- %%app_path%%/themes/%%current_theme%%/%%current_device%%/%%template%%
- %%app_path%%/themes/fallback_theme/%%current_device%%/%%template%%
- %%app_path%%/views/%%current_device%%/%%template%%
Optionally autodetect_theme
can also be set to a DIC service id that implements
the Liip\ThemeBundle\Helper\DeviceDetectionInterface
interface.
If you want to select the active theme based on a cookie you can add:
# app/config/config.yml
liip_theme:
cookie:
name: NameOfTheCookie
lifetime: 31536000 # 1 year in seconds
path: /
domain: ~
secure: false
http_only: false
If your application doesn't allow the user to switch theme, you can deactivate the controller shipped with the bundle:
# app/config/config.yml
liip_theme:
load_controllers: false
The following order is applied when checking for templates that live in a bundle, for example @BundleName/Resources/template.html.twig
with theme name phone
is located at:
- Override themes directory:
app/Resources/themes/phone/BundleName/template.html.twig
- Override view directory:
app/Resources/BundleName/views/template.html.twig
- Bundle theme directory:
src/BundleName/Resources/themes/phone/template.html.twig
- Bundle view directory:
src/BundleName/Resources/views/template.html.twig
For example, if you want to integrate some TwigBundle custom error pages regarding your theme
architecture, you will have to use this directory structure :
app/Resources/themes/phone/TwigBundle/Exception/error404.html.twig
The following order is applied when checking for application-wide base templates, for example ::template.html.twig
with theme name phone
is located at:
- Override themes directory:
app/Resources/themes/phone/template.html.twig
- Override view directory:
app/Resources/views/template.html.twig
You able change cascading order via configurations directives: path_patterns.app_resource
, path_patterns.bundle_resource
, path_patterns.bundle_resource_dir
. For example:
# app/config/config.yml
liip_theme:
path_patterns:
app_resource:
- %%app_path%%/themes/%%current_theme%%/%%template%%
- %%app_path%%/themes/fallback_theme/%%template%%
- %%app_path%%/views/%%template%%
bundle_resource:
- %%bundle_path%%/Resources/themes/%%current_theme%%_%%current_device%%/%%template%%
- %%bundle_path%%/Resources/themes/%%current_theme%%/%%template%%
- %%bundle_path%%/Resources/themes/fallback_theme/%%template%%
bundle_resource_dir:
- %%dir%%/themes/%%current_theme%%/%%bundle_name%%/%%template%%
- %%dir%%/themes/fallback_theme/%%bundle_name%%/%%template%%
- %%dir%%/%%bundle_name%%/%%override_path%%
Placeholder | Representation | Example |
---|---|---|
%app_path% |
Path where application resources are located | app/Resources |
%bundle_path% |
Path where bundle located, for example | src/Vendor/CoolBundle/VendorCoolBundle |
%bundle_name% |
Name of the bundle | VendorCoolBundle |
%dir% |
Directory, where resource should looking first | |
%current_theme% |
Name of the current active theme | |
%current_device% |
Name of the current device type | desktop, phone, tablet, plain |
%template% |
Template name | view.html.twig |
%override_path% |
Like template, but with views directory | views/list.html.twig |
For that matter have a look at the ThemeRequestListener.
If you are early in the request cycle and no template has been rendered you can still change the theme without problems. For this the theme service exists at:
$activeTheme = $container->get('liip_theme.active_theme');
echo $activeTheme->getName();
$activeTheme->setName("phone");
In some situations, a different template is not enough and you need a different controller for a specific theme. We encountered this with A/B testing. Do not abuse this feature and check whether your use case is still to be considered a theme.
This feature is not active by default as there is an additional request
listener involved. Enable it by setting theme_specific_controllers
in your
configuration:
# app/config/config.yml
liip_theme:
# ...
theme_specific_controllers: true
Now you can configure controllers per theme in your routing file:
my_route:
path: /x/y
defaults:
_controller: my_service:fooAction
theme_controllers:
a: my_other_service:fooAction
b: App:Other:foo
As usual, you can use both the service notation or the namespace notation for
the controllers. Just specify the controller by theme under the key
theme_controllers
.
Because of the way the LiipThemeBundle overrides the template locator service, assetic will only dump the assets of the active theme.
In order to dump the assets of all themes enable the assetic_integration
option:
# app/config/config.yml
liip_theme:
# ...
assetic_integration: true
This will override the Twig formula loader and iterate over all of the themes, ensuring that all of the assets are dumped.
Note that this only works with AsseticBundle 2.1 or higher.
It is possible to override the service used for the device detection. Make sure to either
extend DeviceDetection
or implement DeviceDetectionInterface
:
# app/config/config.yml
services:
my_devcice_detection:
class: SomeClass
liip_theme:
# ...
device_detection: my_devcice_detection
Active contribution and patches are very welcome. To keep things in shape we have quite a bunch of unit tests. If you're submitting pull requests please make sure that they are still passing and if you add functionality please take a look at the coverage as well it should be pretty high :)
First install dependencies:
composer.phar install --dev
This will give you proper results:
phpunit --coverage-text