【问题标题】:Specify alternative fallback paths for Symfony to find twig templates for bundles为 Symfony 指定备用备用路径以查找捆绑包的树枝模板
【发布时间】:2015-01-01 21:16:00
【问题描述】:

基本问题

如何让 symfony 在非标准目录中查找“最佳”(自定义)Twig 模板以加载捆绑视图?

Symfony 文档说默认情况下它会在两个位置查找override a Twig template

当 AcmeBlogBu​​ndle:Blog:index.html.twig 被渲染时,Symfony 实际上在两个不同的位置查找模板:

app/Resources/AcmeBlogBu​​ndle/views/Blog/index.html.twig src/Acme/BlogBu​​ndle/Resources/views/Blog/index.html.twig

但这里讨论的是如何覆盖供应商捆绑包。就我而言,我的 /src/ 中有本机捆绑包,我想根据每个设计模板或客户特定的基础对其进行覆盖。它需要查看:

Client:    /var/www/vhosts/{ID}/src 
Template:  /var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src

Twig Loader有一个方便的添加路径的方法:

$templatePath = '/var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/Resources/views';
$this->container->get('twig.loader')->prependPath($templatePath, 'template');

这允许我注册模板资源的替代路径,以便我可以像这样渲染模板外壳:

{% 扩展 '@template/shell/shell.html.twig' %}

但是当我想覆盖一个包模板时,例如

Original: /var/www/core/cms/src/Gutensite/MenuBundle/Resources/views/Menu.html.twig
Custom:   /var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src/Gutensite/MenuBundle/Resources/views/Menu.html.twig

如何注册一个通用的 /src/ 文件,以便 Symfony 在那里查找对供应商捆绑路径的所有引用,例如尝试渲染 @GutensiteMenu/Menu.html.twig 将首先在自定义目录中查找 1) 客户端2) 模板、3) 该名称的默认捆绑目录。

需要资产

因为我的 TemplateBundle/Templates/Admin/Resources/ 位于非标准位置,assetic 不会将它们转储到公共目录(或创建符号链接)...所以我不确定如何动态地使 assets找到这些文件。

我也不确定如何加载这些其他位置的资产,例如这不起作用:

{% stylesheets '@GutensiteTemplateBundle/Templates/Admin/Resources/public/css/site.css' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}

大概是因为它没有被倾倒。

我为什么需要这个?

我正在构建一个托管 CMS,它是一个核心供应商,其中包含带有控制器和模板的各种捆绑包,例如/Gutensite/CmsBundleGutensite/ArticleBundle

根据为网站选择的“设计模板”,在 TemplateBundle 中引用设计模板,例如/TemplateBundle/Templates/Admin(一个名为“Admin”的模板)。 TemplateBundle 需要能够覆盖核心控制器或视图。

我已将 Gutensite/TemplateBundle/Templates/Admin/src/ 文件夹注册为 Composer app/autoload.php 的替代命名空间,因此只要控制器具有相同的 Gutensite 命名空间(和这很好用):

// in my primary controller:
$loader = $GLOBALS['loader'];
$loader->add('Gutensite', '/var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src', true);

注意:我可以将每个模板注册为一个包,理论上这将允许我使用 symfony 的内置方法覆盖控制器和包。但这会添加很多不是真正传统的捆绑包的“捆绑包”。我还需要上述解决方案来指向替代模板路径,因为我还需要能够指向位于正常 symfony 根目录之外的客户端自定义文件(我成功地使用控制器的命名空间自动加载器路径)。

【问题讨论】:

  • 仅供参考,我最终创建了一个Templates 供应商,因此每个模板都是该供应商中的一个捆绑包。这通过使用默认继承方法解决了其中一个问题。我还注册了自定义客户端/var/www/vhosts/999/src/ 文件夹的替代路径,以便它首先查看客户端的文件。但是,正确加载资产仍然存在问题。无论如何,我们可能会通过外部存储在文件服务器上的资产来克服这个问题。

标签: symfony twig


【解决方案1】:

您可以在 twig 配置中使用 path 选项,为 2 个路径使用相同的命名空间。

twig:
    # ...
    paths:
        "%kernel.root_dir%/../src/Gutensite/MenuBundle/Resources/views": templates
        "%kernel.root_dir%/../src/Gutensite/TemplateBundle/Templates/Admin/src/Gutensite/MenuBundle/Resources/views": templates

然后,使用@templates/Menu.html.twig 将首先在MenuBundle 中查找Menu.html.twig,然后在TemplateBundle 中查找。

这就是TwigExtension 正在注册路径的方式,因此加载程序在app/Resources/views 中查找,然后在包的视图中查找。

【讨论】:

  • 硬编码配置的问题在于这是一个托管的 CMS,因此需要动态加载。幸运的是,我们可以使用我上面提到的代码做到这一点:$this-&gt;container-&gt;get('twig.loader')-&gt;prependPath($templatePath, 'template'); 但是,我们仍然存在从该替代位置加载资产的问题,我们可能会通过完整路径(到另一个文件服务器)来克服。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多