【问题标题】:How to check if a block exists in a twig template - Symfony2如何检查树枝模板中是否存在块 - Symfony2
【发布时间】:2025-12-21 02:50:14
【问题描述】:

想象一下我的树枝模板中有这样的东西

{% block posLeft %}
   -----
{%endblock%}

有什么方法可以检查 posLeft 块的存在而不调用:

block("posLeft") 

并检查 posBlock 的返回值以验证是否存在。我是 Symfony2 + Twig 的新手。

【问题讨论】:

  • 您为什么要这样做?在我看来,您正在将逻辑添加到可能属于您的控制器的视图中。如果您想根据某个变量显示某些内容,只需将该变量注入您的视图,然后根据需要显示不同的块。

标签: symfony twig


【解决方案1】:

树枝 2.x

{{ (block("posLeft")) ?? '' }}

如果你想在一行中显示一个块是否已定义。可能有点笨拙,但无需一堆 if..then 逻辑就可以满足我的需求。

【讨论】:

    【解决方案2】:

    这里的其他答案不适用于 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') 已经处理了转义,并且在显示之前不会先将其设置为变量。
    【解决方案3】:

    首先检查您在 symfony 项目中使用的是哪个 Twig 版本,因为这里的答案仅适用于 Twig 1。

    如果您使用的是 Twig 2,那么您很幸运。根据 Twig 文档,您可以使用定义的测试来检查该块是否存在于当前模板上下文中。

    {% if block("dynamic") is defined %}
       ...
    {% endif %}
    

    我写了一个小 TwigExtension 来检查块是否在 if 语句中被调用,看起来 Twig 真的只检查块是否存在而不调用它。

    文档链接:http://twig.sensiolabs.org/doc/2.x/functions/block.html

    如果您使用的是 Twig 1https://*.com/a/13806784/6458657 的旧答案仍然正确。

    【讨论】:

      【解决方案4】:

      只想提供另一个对我有用的例子。

      <body
      {%  if block('ngapp') is not empty  %}ng-app="{% block ngapp %}{% endblock %}"{% endif %}
      >
      

      这允许我在子模板中声明 {% block ngapp 'myApp' %} 并将其显示在父模板中。

      这是必需的,因为在某些页面上我通过 (angular.bootstrap('moduleName', rootElement)) 手动引导 Angular,而 Angular 不喜欢空的 ng-app='' 指令并且以奇怪的方式中断。

      【讨论】:

        【解决方案5】:

        你可以这样做:

        {% if block('posLeft') %}
          ...
        {% endif %}
        

        但如果你需要渲染块的输出,它效率不高。 所以如果你需要块输出,你应该首先将它分配给变量 然后做断言

        【讨论】:

        • 我认为这是最干净的方式!
        • 投反对票。请参阅评论中的链接*.com/questions/13774384/…
        • 对我来说,有时“空”块中有空格(因为格式化)。所以我通过使用来解决它: if block('posLeft') |修剪!=''
        【解决方案6】:

        如果您想仅在某个块有内容时才显示某个块,您可以这样解决。希望,这就是你要找的。​​p>

        示例 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 %}
        

        【讨论】:

        • 没有内置标签吗?获取块值并再次检查一个空字符串需要大量代码。看起来真的很丑。
        • 我认为没有其他方法。正如@lifo 所说,您可能在模板中投入了很多逻辑。请注意不要将这 2 行语句放入单行检查中,因为这可能会导致新的子请求。以下是 Twig Google Group 上的类似讨论:groups.google.com/forum/?fromgroups=#!topic/twig-users/…