【问题标题】:Check if a variable is defined AND truthy at once in Twig检查是否在 Twig 中一次定义了变量并且是真实的
【发布时间】:2018-01-17 13:22:32
【问题描述】:

在 PHP 中我可以做到

<?php if ($someVar): ?>

这会检查变量是否存在并且它的值是否不同于类似零的值,例如 0、null、'' 等。

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

{% if someVar is defined and someVar %}

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

【问题讨论】:

    标签: twig


    【解决方案1】:

    在不扩展 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 %} 显然是falseThe if tag's documentation page 描述了定义变量的边缘情况规则:

    判断一个表达式是true还是false的规则是一样的 和 PHP 一样;以下是边缘情况规则:

    值布尔评估 空字符串假 数字零假 纯空格字符串 true 空数组假 空假 非空数组 true 对象真

    See TwigFiddle 用于演示(strict_variables 在标题中的“更多选项...”链接后面设置为 false)。


    通过扩展 Twig

    (免责声明:我在@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' =&gt; 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|default() %} 怎么样?它也适用于像 {% if someArray.property|default() %} 这样的数组。还是我做错了什么?
    • 经过快速测试,看起来它也可以工作。您可以添加自己的答案,或者我可以将其添加到我的答案中并附上详细信息。
    • 没问题 ;-) 感谢您的支持!
    【解决方案2】:

    以下效果很好:

    {% if someVar ?? false %}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-22
      • 2012-01-20
      • 2021-04-21
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      相关资源
      最近更新 更多