TWIG - 如何在子模板中覆盖嵌入块内的块?

15

所以,我有3个模板:1. 带一些参数的嵌入式小部件,2. 适用于每个页面的全局布局,3. 单个页面。

我想在布局中创建一个块,可以被页面覆盖,但是当我想将此块放在嵌入式小部件中时,它无法正常工作。

文件:Widget/awesome.html.twig(嵌入式小部件)

<div id="{{id|default('awesomeWidget')}}">
    {% block widget_body %}
    {% endblock %}
</div>

文件:Layout/layout.html.twig

{% block layout_body %}
    {% embed 'AcmeFoobarBundle:Widget:awesome.html.twig' with 
            {'id':'myAwesomeWidget'} only %}
        {% block widget_body %}
            {% block I_WANT_TO_OVERRIDE_THIS %}
            {% endblock %}
        {% endblock %}
    {% endembed %}
{% endblock %}

文件:Portal/page.html.twig

{% extends 'AcmeFoobarBundle:Layout:layout.html.twig' %}

{% block I_WANT_TO_OVERRIDE_THIS %}
    Hello World
{% endblock %}

有没有办法实现这个想法?

2个回答

24

你不能这样做。嵌入(Embed)的作用类似于包含和扩展(Include and Extends),因此要覆盖的 I_WANT_TO_OVERRIDE_THIS 块实际上在你的“扩展” awesome.html.twig 中。页面是在扩展 layout.html.twig 而不是 awesome.html.twig,因此 page.html 没有 I_WANT_TO_OVERRIDE_THIS 块。

你应该考虑更改为在 page.html.twig 级别上有一个小部件的占位符并将它们嵌入其中。

如果你真的需要这样做,你最终可以像这样做: 在 layout.html.twig 中:

{% set overrideWidgetPart %}
   {% block I_WANT_TO_OVERRIDE_THIS %}{% endblock %}
{% endset %}

{% block layout_body %}
    {% embed 'AcmeFoobarBundle:Widget:awesome.html.twig' with 
            {'id':'myAwesomeWidget', overrideWidgetPart: overrideWidgetPart } only %}
        {% block widget_body %}
            {{ overrideWidgetPart  }}
        {% endblock %}
    {% endembed %}
{% endblock %}

1
这个“overrideWidgetPart: overrideWidgetPart”真的需要吗?我将其应用于类似的问题并删除了该部分,它可以正常工作。谢谢 :) - Diguin
1
@Diguin,就最终结果而言,在这个片段中不需要它们,但是想法是限制不需要的变量出现在您的模板中。考虑到您有许多不同的变量,您更愿意防止它们进入您的模板,以避免名称冲突并简化调试。始终使用“with { ... } only”是一个好习惯。 - ivkremer

4

接受的答案帮助我解决了一个类似的情况,在其中我使用内嵌在内嵌中,并且我想能够在子内嵌块中注入HTML。

如果您查看users.html,您会发现我使用{% set footer %}{% endset %},这允许我将HTML传递到子内嵌 {% block footer %} 块中。

users.html

{% embed 'user_widget.twig'
    with { user: user } only %}        
    {% set footer %}
        <div class='footer'>content here</div>
    {% endset %}
{% endembed %}

user_widget.twig

{% embed 'user_widget.tpl' with {
    open: true,
    id: user.uid
}%}
    <div class='user_header'>{{ user.name }}</div>    
    {% block content %}
        {% embed "user_info.twig" with {
            id: user.id,
            photo: user.picture,
            footer_html: footer} only %}
                {% block footer %}{{ footer_html }}{% endblock %}
        {% endembed %}
    {% endblock %}
{% endembed %}

user_info.twig

<div class='user_info' id='{{ id }}'>
    <img class='user_photo' src='{{ photo }}'>    
    {% block footer %}{% endblock %}
</div>

即使您想从父级-父级访问子范围,这是否有效?假设在users.html中,您想要执行content here for {{ id }},其中iduser_info.twig中可用。 - kuus
实际上,当用户在父级范围内定义时,这是理所当然的。实际上,我感到好奇的是,在最后一个子级中要覆盖的块位于for循环中的情况下,其他不直接从父级范围可访问的数据通常会可用。 - kuus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接