检查是否在 Twig 中一次定义了变量并为真 [英] Check if a variable is defined AND truthy at once in Twig
问题描述
在 PHP 中我可以做到
这会检查变量是否存在以及它的值是否不同于类似零的值,例如 0、null、'' 等.
在 Twig 中有什么方法可以做到这一点,还是我需要为此编写自己的过滤器?此刻,我必须做
{% 如果定义了 someVar 和 someVar %}
当涉及到更复杂的模板时,这很痛苦.
在不扩展 Twig 的情况下,(至少)有两种方法可以做到这一点.第三种选择是通过创建例如扩展 Twig一个 Twig 函数.我可能会选择第一种方式(使用 default
过滤器).
通过使用 default
过滤器
正如@The_Unknown 指出的,您也可以使用 默认
过滤器:
{% if someVar|default(null) %}
您可以省略将默认值传递给过滤器,甚至可以省略括号.然后该值将默认为空字符串(这是 falsey).IE.这两个是相等且有效的:
{% if someVar|default() %}{% if someVar|默认 %}
无论你选择哪种风格(默认为 null
,省略值或省略括号),坚持下去.保持一致.
参见 TwigFiddle 以了解真值求值为 true
和假值求值的演示到 false
(基于下表).
通过将 strict_variables
设置为 false
通过设置环境变量strict_variables
为false
,你可以跳过if someVar is defined
部分,只做{%如果 someVar %}
.如Twig 的文档 中所述:
strict_variables
布尔值
如果设置为 false
,Twig 会默默地忽略无效的变量(不存在的变量和/或属性/方法)并替换它们具有 null
值.当设置为 true
时,Twig 会抛出异常相反(默认为 false
).
在创建 Twig_Environment
实例时将变量设置为 false
:
$twig = new Twig_Environment($loader, ['strict_variables' => false]);
如果someVar
未定义,那么{% if someVar %}
显然是false
.if
标签的文档页面 描述定义变量的边缘情况规则:
判断一个表达式是true
还是false
的规则是一样的就像在 PHP 中一样;以下是边缘情况规则:
参见 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) {返回 array_key_exists($var, $context) &&$context[$var];}, ['needs_context' =>真的]));
['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]) {返回假;}}返回真;}, ['needs_context' =>真的]));
然后在 Twig 中你可以:
{% if istruthy('foo') %} ... {% endif %}{% if istruthy('foo') 或 istruthy('bar') %} ... {% endif %}{# 这两个是一样的:#}{% if istruthy('foo') and istruthy('bar') and istruthy('baz') %} ... {% endif %}{% if istruthy('foo', 'bar', 'baz') %} ... {% endif %}{# 也可以使用三元运算符:#}{{ istruthy('foo') ?'是的':'不'}}
您可能希望检查 istruthy
函数中的参数是字符串还是其他内容,然后相应地采取行动.array_key_exists
期望第一个参数是字符串或整数.
In PHP I can do
<?php if ($someVar): ?>
This checks if a variable exists and if its value is different from a zero-like value like 0, null, '', and so on.
Is there any way to do so in Twig or do I need to write my own filter for that? At the moment, I must do
{% if someVar is defined and someVar %}
which is a pain when it comes to more complex templates.
There are (at least) two ways of doing this without extending Twig. A third option is to extend Twig by creating e.g. a Twig function. I would probably choose the first way (using the default
filter).
By using the default
filter
As @The_Unknown pointed out, you can also use the default
filter:
{% if someVar|default(null) %}
You can omit passing the default value to the filter, and even omit the parentheses. Then the value will default to an empty string (which is falsey). I.e. these two are equal and valid:
{% if someVar|default() %}
{% if someVar|default %}
Whichever style you choose (default to null
, omit the value or omit the parens), stick to it. Be consistent.
See TwigFiddle for a demonstration that truthy values evaluate to true
and falsey values evaluate to false
(based on the table below).
By setting strict_variables
to false
By setting the environment variable strict_variables
to false
, you can skip the if someVar is defined
part and do just {% if someVar %}
. As described in Twig's documentation:
strict_variables
booleanIf set to
false
, Twig will silently ignore invalid variables (variables and or attributes/methods that do not exist) and replace them with anull
value. When set totrue
, Twig throws an exception instead (default tofalse
).
Set the variable to false
when creating a Twig_Environment
instance:
$twig = new Twig_Environment($loader, ['strict_variables' => false]);
If someVar
is undefined, then {% if someVar %}
is obviously false
. The if
tag's documentation page describes the edge case rules for defined variables:
The rules to determine if an expression is
true
orfalse
are the same as in PHP; here are the edge cases rules:Value Boolean evaluation empty string false numeric zero false whitespace-only string true empty array false null false non-empty array true object true
See TwigFiddle for a demonstration (strict_variables
is set to false
behind the "More options..." link in the header).
By extending Twig
(Disclaimer: I wrote this approach before @The_Unknown pointed out that the default
filter can also be used.)
If the idea of setting strict_variables
to false
is too general, you can also extend Twig. I'd argue that it's better to set strict_variables
to true
to avoid accidental errors caused by e.g. typos in variable names, so this approach might be better.
I don't think that you can create a filter to do this, as an undefined variable would still throw an exception. You might be able to create a custom tag, test or extension (see Extending Twig for ways to extend Twig); I'm going to create a custom function as it's probably the simplest approach.
$twig->addFunction(new Twig_Function('istruthy', function($context, $var) {
return array_key_exists($var, $context) && $context[$var];
}, ['needs_context' => true]));
The ['needs_context' => true]
part is essential here, as then you will have access to $context
, which contains the variables present in the current context. (You can e.g. put var_dump($context)
above the return statement to see it yourself.)
If you want istruthy
to support checking multiple variables at once, you can do this:
$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]));
Then in Twig you can do:
{% 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' }}
You might want to check in the istruthy
function whether the arguments are strings or something else and then act accordingly. array_key_exists
expects the first argument to be either a string or an integer.
这篇关于检查是否在 Twig 中一次定义了变量并为真的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!