Php 从Symfony/Twig中的过度版本访问父模板
我有一个第三方bundlePhp 从Symfony/Twig中的过度版本访问父模板,php,symfony,inheritance,twig,bundle,Php,Symfony,Inheritance,Twig,Bundle,我有一个第三方bundleOriginalBundle,我想定制其中的一些模板 为了实现这一点,我使用设置了一个Symfony bundleMyCustomBundle 然后我得到一个白色的死亡屏幕。我猜这会导致某种递归,因为Symfony正在将extends回调路由回自定义文件 原始捆绑包的模板如下所示: {# MyCustomBundle:Foo:bar.html.twig #} {% extends 'OriginalBundle:Foo:bar.html.twig' %} {% bl
OriginalBundle
,我想定制其中的一些模板
为了实现这一点,我使用设置了一个Symfony bundleMyCustomBundle
然后我得到一个白色的死亡屏幕。我猜这会导致某种递归,因为Symfony正在将extends
回调路由回自定义文件
原始捆绑包的模板如下所示:
{# MyCustomBundle:Foo:bar.html.twig #}
{% extends 'OriginalBundle:Foo:bar.html.twig' %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
{# OriginalBundle:Foo:bar.html.twig #}
{% block abc %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
{% endblock %}
{# MyCustomBundle:Foo:bar.html.twig #}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
所以问题是
当同一模板存在过度使用的版本时,是否有办法访问原始模板文件
我基本上是在寻找相当于parent::doSomething()
的细枝/模板
没有这种对父级的访问,我发现自己逐字复制了整个原始模板文件,然后更新了其中的一小部分,这感觉不对劲。如果要保留链接到
FooController
的原始捆绑包中的xyz
块的视图,必须键入
{{ parent() }}
否则,如果重新定义块时内部没有任何内容,则会得到一个空页面,这是正常的。在中,您希望保留对原始包的“扩展”,您必须使用方法a)因此创建app/Resources/original bundle/views/layout.html.twig和/或app/Resources/original bundle/views/Foo/bar.html.twig,但粘贴这些模板供应商文件的整个代码,因为您希望重用它们(默认情况下供应商视图会覆盖这些路径)然后你可以使用你的“扩展” 如果您还希望覆盖供应商的控制器,则使用方法b):但即使在这种情况下,您也必须粘贴要重用的代码(并且必须在新捆绑包上进行“扩展”)
因为我习惯于覆盖控制器,所以我使用方法b。抱歉,这是不可能的。如果你计划覆盖控制器,请始终使用方法a)和方法b。实际上,我正在搜索相同的内容。 我的用例如下所示: 我有一个带有仪表板的网站。我想用捆绑包中的新数据扩展仪表板。 每个包都有自己的数据,我想放在仪表板的某些块中。 仪表板模板未绑定到任何捆绑包,因此应该可以访问 我想知道如何在不重载任何路由的情况下将块注入模板
编辑:导航栏也一样,例如-应该有一种方法可以毫无问题地扩展块,这样就可以轻松地从捆绑包中扩展主网站导航…您是否尝试过这样做:
{# MyCustomBundle:Foo:bar.html.twig #}
{% extends 'OriginalBundle:Foo:bar.html.twig' %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
{# OriginalBundle:Foo:bar.html.twig #}
{% block abc %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
{% endblock %}
{# MyCustomBundle:Foo:bar.html.twig #}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
没有扩展部分?有一个解决方案。
默认情况下,Symfony搜索第一个匹配的资源并返回它。
要更改此行为,需要指定一些附加语法。我用“!”进入第二场比赛
{% extends '!OriginalBundle:Foo:bar.html.twig' %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
覆盖文件可以位于app/Resources/OriginalBundle/views/Foo/bar.html.twig
要激活此系统,您需要将原始内核覆盖到:
<?php
namespace Webility\Bundle\WebilityBundle\HttpKernel;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
abstract class Kernel extends BaseKernel
{
public function getBundle($name, $first = true)
{
$get_next = false;
if($name[0] == '!' && $first){
$name = substr($name, 1);
$first = false;
$get_next = true;
}
$bundles = parent::getBundle($name, $first);
if($get_next){
return isset($bundles[1]) ? $bundles[1] : $bundles[0];
} else {
return $bundles;
}
}
public function locateResource($name, $dir = null, $first = true)
{
$get_next = false;
if($name[0] == '@' && $name[1] == '!' && $first){
$name = '@'.substr($name, 2);
$first = false;
$get_next = true;
}
$files = parent::locateResource($name, $dir, $first);
if($get_next){
return isset($files[1]) ? $files[1] : $files[0];
} else {
return $files;
}
}
}
此问题是由于Symfony将对
原始bundle
的模板引用解释为ChildBundle
,这是由于bundle继承导致函数嵌套级别异常
您可以使用以下符号引用父级的捆绑包模板文件:
{% extends "@Original/Foo/bar.html.twig" %}
代替:
{% extends "OriginalBundle:Foo:bar.html.twig" %}
Twig的
文件系统加载器
将引用字符串拆分为名称空间(原始)和路径(Foo/bar.html.Twig)。Namespace是不带bundle后缀的bundle名称。通过将默认的/Resources/views/
与提供的路径连接,可以解析每个命名空间的完整路径 你也可以显示你扩展的原始模板吗?当然-我已经编辑了这个问题,添加了一个example@caponica,我想您正在寻找“嵌入”细枝功能。这对我来说是新功能-我明天会看一看。但我不确定这是否有帮助,因为我正在尝试覆盖(第三方)捆绑包的模板。我认为嵌入也没有帮助。。。此场景是一个Symfony bundle覆盖,它将OriginalBundle:Foo:bar.html.twig
的使用路由到同一文件的自定义版本。我想知道的是,是否有办法访问原始文件(从我的自定义模板),也就是说,有选择地忽略孩子自己模板中的过度使用。我不认为是这样。。。我想扩展模板并重新定义其中的一个块,但对其他所有内容都使用父块定义parent()
用于渲染父块,这不是我要做的。(另外,我重新定义的块不是空的-请注意,白色屏幕是由于symfony崩溃造成的。)您能显示原始和自定义控制器以及细枝文件的路径吗。。。里面有密码吗?我觉得没关系。。。引用是正确的,如果我不尝试扩展原始文件,或者如果我只是扩展一个模板而不使用Symfony的getParent()
bundle override系统,它就可以工作。但当我尝试使用这两种方法时,我被卡住了。。。这就是问题所在。我已经更新了它,用getParent()调用显示over ride类。路径是:project\src\My\CustomBundle\MyCustomBundle.php
,project\src\My\CustomBundle\Resources\views\Foo\bar.html.twig
和project\vendor\third-party\original bundle\Resources\views\Foo\bar.html.twig
对不起,这不是解决方案。这说明了问题所在。如果我使用方法(a),那么我必须粘贴源代码的整个代码。这个问题是关于如何扩展原始文件并在我的版本中添加新的位。Ohhh..我从来没有见过这样做的文档…我想你不能,因为正如fosuserbundle文档和symfony文档中所解释的那样,当你扩展模板时,默认情况下它会首先在app/Resources中显示,然后在捆绑包的src中显示,不在供应商中。。。您可以在应用程序/资源中尝试,而无需使用“扩展”到di