检查是否在Twig中一次定义了变量并且是否正确

The*_*own 6 twig

在PHP中我可以做

<?php if ($someVar): ?>
Run Code Online (Sandbox Code Playgroud)

这将检查变量是否存在,以及它的值是否与零类似的值(例如0,null,''等)不同。

在Twig中有什么方法可以这样做,还是我需要为此编写自己的过滤器?此刻,我必须做

{% if someVar is defined and someVar %}
Run Code Online (Sandbox Code Playgroud)

当涉及到更复杂的模板时,这是很痛苦的。

mar*_*ias 8

在不扩展Twig的情况下,有(至少)两种方法。第三种选择是通过创建例如Twig函数来扩展Twig。我可能会选择第一种方式(使用default过滤器)。


通过使用default过滤器

正如@The_Unknown指出的那样,您还可以使用default过滤器

{% if someVar|default(null) %}
Run Code Online (Sandbox Code Playgroud)

您可以忽略将默认值传递给过滤器,甚至省略括号。然后,该值将默认为空字符串(为false)。即,这两个是相等且有效的:

{% if someVar|default() %}
{% if someVar|default %}
Run Code Online (Sandbox Code Playgroud)

无论选择哪种样式(默认为null,忽略值或忽略括号),请坚持使用。始终如一。

请参见TwigFiddle,以获取有关真值评估true和假值评估的演示false(基于下表)。


通过设置strict_variablesfalse

通过将环境变量设置strict_variablesfalse,您可以跳过if someVar is defined零件而仅做{% if someVar %}。如Twig文档中所述

strict_variables 布尔值

如果设置为false,Twig将静默忽略无效变量(变量和/或不存在的属性/方法),并将其替换为null值。设置true为时,Twig会引发异常(默认为false)。

false在创建Twig_Environment实例时将变量设置为:

$twig = new Twig_Environment($loader, ['strict_variables' => false]);
Run Code Online (Sandbox Code Playgroud)

如果someVar未定义,则{% if someVar %}显然是falseif标签的文档页面描述定义的变量的边缘情况的规则:

规则,以确定是否一个表达式是true或者false是相同的PHP中; 以下是边际案例规则:

值布尔值评估

空字符串假
数字零错误
仅空白字符串true
空数组false
空假
非空数组true
真实对象

参见TwigFiddle进行演示(strict_variables设置false在标题中“更多选项...”链接的后面)。


通过扩展树枝

(免责声明:我在@The_Unknown指出default过滤器也可以使用之前编写了这种方法。)

如果设置的理念strict_variables,以false太一般了,你还可以扩展的树枝。我认为最好设置strict_variablestrue避免因变量名中的错字等引起的意外错误,因此这种方法可能更好。

我认为您无法创建过滤器来执行此操作,因为未定义的变量仍会引发异常。您也许可以创建自定义标签,测试或扩展名(有关扩展Twig的方法,请参见扩展 Twig);我将创建一个自定义函数,因为它可能是最简单的方法。

$twig->addFunction(new Twig_Function('istruthy', function($context, $var) {
     return array_key_exists($var, $context) && $context[$var];
 }, ['needs_context' => true]));
Run Code Online (Sandbox Code Playgroud)

['needs_context' => true]部分在这里至关重要,因为您将可以访问$context,其中包含当前上下文中存在的变量。(例如var_dump($context),您可以将它放在return语句上方以自己查看。)

如果要istruthy支持一次检查多个变量,可以执行以下操作:

$twig->addFunction(new Twig_Function('istruthy', function($context, ...$vars) {
     foreach ($vars as $var) {
         if (!array_key_exists($var, $context) || !$context[$var]) {
             return false;
         }
     }

     return true;
 }, ['needs_context' => true]));
Run Code Online (Sandbox Code Playgroud)

然后在Twig中可以执行以下操作:

{% if istruthy('foo') %} ... {% endif %}

{% if istruthy('foo') or istruthy('bar') %} ... {% endif %}


{# These two are the same: #}

{% if istruthy('foo') and istruthy('bar') and istruthy('baz') %} ... {% endif %}

{% if istruthy('foo', 'bar', 'baz') %} ... {% endif %}


{# Ternary operator can also be used: #}

{{ istruthy('foo') ? 'yep' : 'nope' }}
Run Code Online (Sandbox Code Playgroud)

您可能想检查istruthy函数中的参数是否为字符串还是其他,然后采取相应措施。array_key_exists期望第一个参数是字符串或整数。


use*_*662 5

以下效果很好:

{% if someVar ?? false %}
Run Code Online (Sandbox Code Playgroud)