cap*_*ica 4 php inheritance bundle symfony twig
我有第三方包OriginalBundle,我想自定义其中的一些模板.
为此,我MyCustomBundle使用Symfony文档中显示的覆盖方法设置了Symfony包.
<?php
namespace My\CustomBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class MyCustomBundle extends Bundle
{
public function getParent()
{
return 'OriginalBundle';
}
}
Run Code Online (Sandbox Code Playgroud)
然后我使用MyCustomBundle从OriginalBundle创建一些Twig模板的重载版本.但是,我希望能够从我的版本访问原始模板(例如扩展它)并且只是覆盖一些块.
但是,如果我尝试做这样的事情:
{# MyCustomBundle:Foo:bar.html.twig #}
{% extends 'OriginalBundle:Foo:bar.html.twig' %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
然后我得到一个白色的死亡屏幕.我猜它会导致某种递归,因为Symfony extends将回调路由回自定义文件?
原始包的模板如下所示:
{# OriginalBundle:Foo:bar.html.twig #}
{% block abc %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
那么问题......
当存在相同模板的过度版本时,有没有办法访问原始模板文件?
我基本上是在寻找相当于Twig /模板的parent::doSomething().
如果没有对父级的这种访问,我发现自己逐字复制整个原始模板文件,然后更新它的一小部分,这只是感觉不对.
有一个解决方案.Symfony默认搜索第一个匹配的资源并返回它.要更改此行为,您需要指定一些其他语法.我用 "!" 达到第二场比赛.
{% extends '!OriginalBundle:Foo:bar.html.twig' %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
覆盖文件可能在 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
并在app/AppKernel.php中使用它
class AppKernel extends \Webility\Bundle\WebilityBundle\HttpKernel\Kernel
Run Code Online (Sandbox Code Playgroud)
小智 3
如果您想保留xyz链接到 的原始捆绑包中的块视图FooController,您必须输入
{{ parent() }}
Run Code Online (Sandbox Code Playgroud)
否则,如果您重新定义内部没有任何内容的块,那么您会得到一个空页面,这是正常的。
| 归档时间: |
|
| 查看次数: |
1667 次 |
| 最近记录: |