为 Symfony 指定备用回退路径以查找包的树枝模板 [英] Specify alternative fallback paths for Symfony to find twig templates for bundles

查看:24
本文介绍了为 Symfony 指定备用回退路径以查找包的树枝模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Symfony 文档说默认情况下它会在两个位置查找 覆盖 Twig 模板

The Symfony docs say by default it looks in two locations to override a Twig template

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

When the AcmeBlogBundle:Blog:index.html.twig is rendered, Symfony actually looks in two different locations for the template:

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

app/Resources/AcmeBlogBundle/views/Blog/index.html.twig src/Acme/BlogBundle/Resources/views/Blog/index.html.twig

但这是在讨论如何覆盖供应商包.就我而言,我的/src/中有本机包,我想在每个设计模板或特定于客户端的基础上覆盖它们.它需要查看:

But this is discussing how you would override a vendor bundle. In my case, I have native bundles in my /src/ that I want to overwrite on a per Design Template or Client specific basis. It needs to look in:

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

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

Twig Loader has a convenient method to add paths:

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

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

This allows me to register an alternative path to the template resources, so that I can render the template shell like this:

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

{% extends '@template/shell/shell.html.twig' %}

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

But what about when I want to overwrite a bundle template, e.g.

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) 的自定义目录该名称的默认包目录.

How do I register a generic /src/ file so that Symfony looks in there for all references to Vendor Bundle paths, e.g. trying to render @GutensiteMenu/Menu.html.twig will first look in the custom directory for 1) Client , 2) Template, 3) default bundle directory by that name.

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

Because my TemplateBundle/Templates/Admin/Resources/ are in a non-standard location, assetic won't dump them to the public directory (or create symlinks)... so I'm not sure how to dynamically make assetic find these files.

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

I'm also not sure how to load the assets that are in these other locations, e.g. this doesn't work:

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

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

Presumably because it's not dumped.

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

I am building a hosted CMS that is a core vendor which contain various bundles with controllers and templates, e.g. /Gutensite/CmsBundle, Gutensite/ArticleBundle.

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

Based on the selected "Design Template" for a site, a design template is referenced in a TemplateBundle, e.g. /TemplateBundle/Templates/Admin (a template called "Admin"). The TemplateBundle need to be able to override the core controllers or views.

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

I have registered the Gutensite/TemplateBundle/Templates/Admin/src/ folder as an alternative namespace for the Composer app/autoload.php, so that controllers can be overwritten as long as they have the same Gutensite namespace (and this works great):

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

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

推荐答案

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

You can use the path option in the twig configuration, with the same namespace for 2 paths.

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 中查找.

Then, using @templates/Menu.html.twig will first look for Menu.html.twig in MenuBundle, then in TemplateBundle.

这是 TwigExtension 注册路径的方式,因此加载器会在 app/Resources/views 中查找,然后在包的视图中查找.

That's this way that the TwigExtension is registering paths so the loader is looking in app/Resources/views and then in the bundle's views.

这篇关于为 Symfony 指定备用回退路径以查找包的树枝模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆