LiipThemeBundle
LiipThemeBundle可以让您为您的每个Bundle添加主题。该主题一般位于您的Bundle目录的Resources/themes/<主题名>或正常的 Resources/views(如果没有找到的话)文件夹中。

安装

步骤1:下载 LiipThemeBundle

进入Symfony2.1.x的根目录,打开 composer.json 文件,在"require":选项中添加:
  1. "require": { 
  2.     ... , 
  3.     "liip/theme-bundle""dev-master" 
  4. }, 

然后运行composer脚本,下载 LiipThemeBundle

  1. php composer.phar update 

步骤2:启用 LiipThemeBundle

下载完成后,在内核中启用 LiipThemeBundle

  1. <?php 
  2. // app/AppKernel.php 
  3.  
  4. public function registerBundles() 
  5.     $bundles = array
  6.         // ... 
  7.         new Liip\ThemeBundle\LiipThemeBundle(), 
  8.     ); 

步骤3:导入 LiipThemeBundle 路由文件

  1. # app/config/routing.yml 
  2. liip_theme: 
  3.     resource: "@LiipThemeBundle/Resources/config/routing.xml" 
  4.     prefix: /theme 

配置

在配置文件中需要列出所有的主题列表及当前主题。注意,当前主题必须在主题列表中

  1. # app/config/config.yml 
  2. liip_theme: 
  3.     themes: ['web''tablet''phone'
  4.     active_theme: 'web' 

可选配置项

可以基于 Cookie 来选择当前主题:

  1. # app/config/config.yml 
  2. liip_theme: 
  3.     cookie: 
  4.         name: NameOfTheCookie 
  5.         lifetime: 31536000 # 1 year in seconds 
  6.         path: / 
  7.         domain: ~ 
  8.         secure: false 
  9.         http_only: false 

也可以基于用户代理自动设置主题 Cookie:

  1. # app/config/config.yml 
  2. liip_theme: 
  3.     autodetect_theme: true 

 autodetect_theme 选项也可以设为 DIC 服务 ID,该服务需要实现 Liip\ThemeBundle\Helper\DeviceDetectionInterface 接口。

如果不想让用户自己改变主题,可以停用该 Bundle 的控制器:

  1. # app/config/config.yml 
  2. liip_theme: 
  3.     load_controllers: false 

主题的层级顺序

Bundle 在应用模板时是按以下层级顺序进行的(让我们先假设有一个名为 phone 的主题,其模板文件为 BundleName/Resources/template.html.twig @BundleName/Resources/template.html.twig):

  1. 覆写主题目录: app/Resources/themes/phone/BundleName/template.html.twig
  2. 覆写视图目录: app/Resources/BundleName/views/template.html.twig
  3. Bundle的主题目录: src/BundleName/Resources/themes/phone/template.html.twig
  4. Bundle的视图目录: src/BundleName/Resources/views/template.html.twig

举个例子,如果您想将一些自定义的 TwigBundle 错误页面集成到您的主题架构中,那么您将需要使用这个目录结构: app/Resources/themes/phone/TwigBundle/Exception/error404.html.twig

当使用全局范围的模板时,将使用下列顺序(如模板文件为 ::template.html.twig 的名为 phone 的主题):

  1. 覆写主题目录:  app/Resources/themes/phone/template.html.twig
  2. 覆写视图目录:  app/Resources/views/template.html.twig

改变主题的层级顺序

您可以通过一些配置命令来改变层级顺序: path_patterns.app_resource  、  path_patterns.bundle_resource 和 path_patterns.bundle_resource_dir 。 如:

  1. # app/config/config.yml 
  2. liip_theme: 
  3.     path_patterns: 
  4.         app_resource: 
  5.             - %%app_path%%/themes/%%current_theme%%/%%template%% 
  6.             - %%app_path%%/themes/fallback_theme/%%template%% 
  7.             - %%app_path%%/views/%%template%% 
  8.         bundle_resource: 
  9.             - %%bundle_path%%/Resources/themes/%%current_theme%%/%%template%% 
  10.             - %%bundle_path%%/Resources/themes/fallback_theme/%%template%% 
  11.         bundle_resource_dir: 
  12.             - %%dir%%/themes/%%current_theme%%/%%bundle_name%%/%%template%% 
  13.             - %%dir%%/themes/fallback_theme/%%bundle_name%%/%%template%% 
  14.             - %%dir%%/%%bundle_name%%/%%override_path%% 
层级顺序通配符

占位符 说明 示例
%app_path% 应用程序Path where application located app
%bundle_path% Bundle所在目录 src/Vendor/CoolBundle/VendorCoolBundle
%bundle_name% Bundle名 VendorCoolBundle
%dir% 首先查找的目录  
%current_theme% 当前激活的主题名  
%template% 模板名 view.html.twig
%override_path% 同上,只是带视图目录 views/list.html.twig

切换当前主题

对于这个问题,可参见 ThemeRequestListener.

如果在请求初期没有模板被渲染,您可以使用主题服务,从而主地改变主题:

  1. $activeTheme = $container->get('liip_theme.active_theme'); 
  2. echo $activeTheme->getName(); 
  3. $activeTheme->setName("phone"); 

常见问题

Assetic:dump 不检查 Resources/{theme}/views 目录:

当使用 assetic:dump 命令进行资源转储时, assetic 只检查用以生成资源的 Resources/views 目录,它并不检查 Resources/{theme}/views 目录。

当前最简单的解决办法:既然问题出在 assetic 不扫描主题目录,那么将 assetic 区块放入 Bundle/Ressources/views 目录中的模板,并从主题模板中包含它。