【发布时间】:2018-01-17 13:22:32
【问题描述】:
在 PHP 中我可以做到
<?php if ($someVar): ?>
这会检查变量是否存在并且它的值是否不同于类似零的值,例如 0、null、'' 等。
在 Twig 中有什么方法可以做到这一点,还是我需要为此编写自己的过滤器?此刻,我必须这样做
{% if someVar is defined and someVar %}
当涉及到更复杂的模板时,这是一种痛苦。
【问题讨论】:
标签: twig
在 PHP 中我可以做到
<?php if ($someVar): ?>
这会检查变量是否存在并且它的值是否不同于类似零的值,例如 0、null、'' 等。
在 Twig 中有什么方法可以做到这一点,还是我需要为此编写自己的过滤器?此刻,我必须这样做
{% if someVar is defined and someVar %}
当涉及到更复杂的模板时,这是一种痛苦。
【问题讨论】:
标签: twig
在不扩展 Twig 的情况下,(至少)有两种方法可以做到这一点。第三种选择是通过创建例如扩展 Twig一个树枝函数。我可能会选择第一种方式(使用default 过滤器)。
default 过滤器正如@The_Unknown 所指出的,您也可以使用default filter:
{% if someVar|default(null) %}
您可以省略将默认值传递给过滤器,甚至可以省略括号。然后该值将默认为空字符串(这是错误的)。 IE。这两个是相等且有效的:
{% if someVar|default() %}
{% if someVar|default %}
无论您选择哪种样式(默认为null,省略值或省略括号),坚持下去。保持一致。
See TwigFiddle 用于演示真值计算为 true 和错误值计算为 false(基于下表)。
strict_variables 设置为false
通过将环境变量strict_variables 设置为false,您可以跳过if someVar is defined 部分而只执行{% if someVar %}。如Twig's documentation中所述:
strict_variables布尔值如果设置为
false,Twig 将默默忽略无效变量 (不存在的变量和/或属性/方法)并替换 它们具有null值。当设置为true时,Twig 会抛出异常 而是(默认为false)。
在创建Twig_Environment 实例时将变量设置为false:
$twig = new Twig_Environment($loader, ['strict_variables' => false]);
如果someVar 未定义,那么{% if someVar %} 显然是false。 The if tag's documentation page 描述了定义变量的边缘情况规则:
判断一个表达式是
值布尔评估 空字符串假 数字零假 纯空格字符串 true 空数组假 空假 非空数组 true 对象真true还是false的规则是一样的 和 PHP 一样;以下是边缘情况规则:
See TwigFiddle 用于演示(strict_variables 在标题中的“更多选项...”链接后面设置为 false)。
(免责声明:我在@The_Unknown 指出default 过滤器也可以使用之前写了这种方法。)
如果将strict_variables设置为false的思路过于笼统,也可以扩展Twig。我认为最好将strict_variables 设置为true 以避免由例如引起的意外错误。变量名中的拼写错误,因此这种方法可能会更好。
我认为您不能创建过滤器来执行此操作,因为未定义的变量仍会引发异常。您也许可以创建自定义标签、测试或扩展(请参阅Extending Twig 了解扩展 Twig 的方法);我将创建一个自定义函数,因为它可能是最简单的方法。
$twig->addFunction(new Twig_Function('istruthy', function($context, $var) {
return array_key_exists($var, $context) && $context[$var];
}, ['needs_context' => true]));
['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]));
然后在 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' }}
您可能希望在istruthy 函数中检查参数是字符串还是其他内容,然后采取相应措施。 array_key_exists 期望第一个参数是字符串或整数。
【讨论】:
strict_variables 设置为true。我用另一种方法更新了我的答案。
以下效果很好:
{% if someVar ?? false %}
【讨论】: