想象一下我在我的 twig 模板中有这样的内容
{% block posLeft %}
-----
{%endblock%}
有没有方法可以在不调用以下内容的情况下检查posLeft块是否存在:
block("posLeft")
并检查posBlock的返回值以验证其是否存在。 我是Symfony2 + Twig的新手。
想象一下我在我的 twig 模板中有这样的内容
{% block posLeft %}
-----
{%endblock%}
有没有方法可以在不调用以下内容的情况下检查posLeft块是否存在:
block("posLeft")
并检查posBlock的返回值以验证其是否存在。 我是Symfony2 + Twig的新手。
如果您想仅在块中有内容时显示特定块,则可以像这样解决。希望这是您要寻找的。
示例index.html.twig
{% set _block = block('dynamic') %}
{% if _block is not empty %}
{{ _block|raw }}
{% endif %}
例子 part.html.twig
{% extends "index.html.twig" %}
{% block dynamic %}
Block content goes here.
{% endblock %}
{% if block('posLeft') %}
...
{% endif %}
但如果你需要渲染块的输出结果,这种方式就不够高效。因此,如果你需要块输出结果,你应该首先将其分配给变量,然后进行断言。
这里的其他答案在twig 2.1上不起作用(我没有在~2.0上测试),因此这里提供一个小更新:
{% if block('dynamic') is defined %}
{{ block('dynamic')|raw }}
{% endif %}
请注意,呈现区块的行不是:
{% block dynamic %}
{# this wont work #}
{% endblock %}
这不会起作用,因为块将在编译时呈现,所以测试将返回存在的真值(因为在运行时进行测试)。因此,您需要使用{{ block('dynamic')|raw }}
呈现块,因为它实际上并没有在模板中定义该块。
|raw
是多余的,因为使用 block('dynamic')
已经处理了转义,并且在显示之前没有被设置为变量。 - lookbadgers首先检查一下你在Symfony项目中使用的Twig版本,因为这里的答案仅适用于Twig 1。
如果你正在使用Twig 2,那么你很幸运。根据Twig文档,你可以使用defined测试来检查当前模板上下文中是否存在该块。
{% if block("dynamic") is defined %}
...
{% endif %}
我写了一个小的Twig扩展来检查块是否在if语句中被调用,似乎Twig只会检查块是否存在而不会调用它。
文档链接:https://twig.symfony.com/doc/2.x/functions/block.html。
如果你正在使用Twig 1版本,则旧答案https://dev59.com/JmYr5IYBdhLWcg3wTYq4#13806784仍然正确。Twig 2.x
{{ (block("posLeft")) ?? '' }}
我想提供另一个对我有用的例子。
<body
{% if block('ngapp') is not empty %}ng-app="{% block ngapp %}{% endblock %}"{% endif %}
>
这使得我在子模板中可以声明{% block ngapp 'myApp' %}
并且在父模板中显示。
这是因为在某些页面上,我手动通过(angular.bootstrap('moduleName', rootElement)
)引导Angular,并且Angular不喜欢空的ng-app=''
指令,会出现奇怪的问题。
在Twig 3.3.10中,被接受的答案对我不起作用,抛出一个未定义块的错误。
为了解决这个问题并定义一个块,其内容有条件地包含在容器中,只有在设置任何块内容时才有效,可以使用以下方法:
{# parent.twig #}
<h1>Hello. I am the parent.</h1>
{% if block('sidebar') is not empty %}
<div class="sidebar-container">
{% block sidebar %}{% endblock %}
</div>
{% endif %}
{% extends 'parent.twig' %}
{% block sidebar %}
Sidebar content from child template
{% endblock %}
输出 - 在包装器内的块内容:
<h1>Hello. I am the parent.</h1>
<div class="sidebar-container">
Sidebar content from child template
</div>
{% extends 'parent.twig' %}
{# sidebar block not set in this one... #}
输出 - 没有空的包装元素:
<h1>Hello. I am the parent.</h1>
{% if block('sidebar') is not empty %}
这个代码会在内存中渲染该块。所以当你后续使用 {% block sidebar %}{% endblock %}
时,它会再次执行渲染。这不仅会影响性能(尽管在大多数情况下影响较小),而且如果块 sidebar 渲染了 Symfony 表单类型(因为默认情况下表单类型字段不能被重复渲染),还会抛出错误。 - undefined