squirrelphp / twig-php-syntax
将常见PHP语法添加到Twig模板中,如 ===、foreach 和 continue/break。
Requires
- php: >=7.2.5
- twig/twig: ^3.9
Requires (Dev)
- bamarni/composer-bin-plugin: ^1.3
- captainhook/plugin-composer: ^5.0
- phpunit/phpunit: ^10.0
README
启用PHP中已知的语法,以便PHP开发者可以更容易地创建和编辑Twig模板。这对于小型项目特别有用,在这些项目中,PHP开发者最终会编写Twig模板,而且模板中的语法略有不同并不值得。
安装
composer require squirrelphp/twig-php-syntax
配置
将PhpSyntaxExtension添加到Twig
$twig = new \Twig\Environment($loader); $twig->addExtension(new \Squirrel\TwigPhpSyntax\PhpSyntaxExtension());
您还可以查看扩展定义并创建自己的扩展类,仅包含一些功能,如果您不喜欢所有功能。
Symfony集成
如果您使用 autoconfigure
(这是默认设置),您只需要在项目的 config
目录中的 services.yaml
文件中加载 PhpSyntaxExtension 类(前四行应该已经存在,只需在文件末尾添加包含 PhpSyntaxExtension 类的行)
services: _defaults: autowire: true autoconfigure: true # Just add the following line, Symfony will register # the extension in Twig for you if Twig is installed Squirrel\TwigPhpSyntax\PhpSyntaxExtension: ~
如果您不使用 autoconfigure
,您可以将twig扩展标签添加到服务定义中
services: Squirrel\TwigPhpSyntax\PhpSyntaxExtension: tags: - { name: twig.extension }
功能
=== / !== 严格比较运算符
Twig有same as
测试,它模仿PHP中的===
,但语法可能难以适应。使用PHP中的严格比较运算符(===
和!==
)可以减少摩擦,更熟悉且更简洁。
{% if 1 === 1 %} This will be shown {% endif %} {% if 1 is same as(1) %} Same as above but with standard Twig syntax {% endif %} {% if 1 === '1' %} This will not be shown, as 1 and '1' have different types (string vs. integer) {% endif %} {% if somevariable === "test" %} somevariable is of type string and equals "test" {% endif %} {% if somevariable !== "test" %} somevariable either is not a string or does not equal "test" {% endif %}
strtotime过滤器
当数据只有(日期)字符串时,在模板中比较时间戳在Twig中有些繁琐,因为没有strtotime
过滤器 - 此库添加了它,与PHP中的完全相同
{% if "2018-05-05"|strtotime > "2017-05-05"|strtotime %} This is always true, as 2018 results in a larger timestamp integer than 2017 {% endif %} {% if post.date|strtotime > otherpost.date|strtotime %} Compares the dates of post and otherpost. strtotime returns an integer or throws an InvalidArgumentException if strtotime returns false {% endif %} {# Sets next thursday as a timestamp variable, but also sets "now" like in strtotime in PHP to define from where the timestamp is calculated if it is a relative date and not an absolute date #} {% set nextThusday = "next Thursday"|strtotime(now=sometimestamp) %}
foreach循环
Twig使用for
来创建循环,其语法与PHP中的foreach
略有不同。使用此库,foreach
在Twig中以与PHP相同的语法可用
{% foreach list as sublist %} {% foreach sublist as key => value %} {% endforeach %} {% endforeach %}
它在内部行为完全相同:for
实际上创建ForNode元素,因此您具有与for
循环相同的功能,包括循环变量和else
。与for
一样,else
的行为相同。
{% foreach list as sublist %} {% foreach sublist as key => value %} {% else %} Array "sublist" is empty / no iteration took place {% endforeach %} {% else %} Array "list" is empty / no iteration took place {% endforeach %}
break和continue
有时在Twig中中断循环可能很方便,但并没有原生支持。此库添加了break
和continue
,并且它们与PHP中的行为完全相同
{% foreach list as entry %} {% if loop.index > 10 %} {% break %} {% endif %} {% endforeach %}
您可以使用break
与一个数字来跳出多个循环,就像在PHP中一样:(continue
不支持此操作)
{% foreach list as sublist %} {% foreach sublist as entry %} {% if loop.index > 10 %} {% break 2 %} {# breaks out of both foreach loops #} {% endif %} {% endforeach %} {% endforeach %}
虽然您通常可以在Twig中规避break
和continue
的使用,但它有时会导致额外的嵌套和更复杂的代码。仅仅一个break
或continue
就可以澄清这些情况中的行为和意图。然而,我建议谨慎使用break
和continue
。
变量类型测试(字符串、数组、true、callable等)
添加了PHP中已知的测试,因此您可以测试一个值是否为
- 数组(如
is_array
) - 布尔值(如
is_bool
) - 可调用(如
is_callable
) - 浮点数(如
is_float
) - 整数(如
is_int
) - 对象(如
is_object
) - 一个标量(整数、浮点数、字符串或布尔值,例如
is_scalar
) - 一个字符串(例如
is_string
) - 真(例如
=== true
) - 假(例如
=== false
)
它内部使用所提到的PHP函数/比较,因此与PHP中的行为相同。
{% if someflag is true %} {# instead of {% if someflag is same as(true) %} #} {% endif %} {% if someflag is false %} {# instead of {% if someflag is same as(false) %} #} {% endif %} {% if somevar is string %} {# no equivalent in Twig %} #} {% endif %} {% if somevar is scalar %} {# no equivalent in Twig %} #} {% endif %} {% if somevar is object %} {# no equivalent in Twig %} #} {% endif %} {% if somevar is integer %} {# no equivalent in Twig %} #} {% endif %} {% if somevar is int %} {# same as integer test above, alternate way to write it %} #} {% endif %} {% if somevar is float %} {# no equivalent in Twig %} #} {% endif %} {% if somevar is callable %} {# no equivalent in Twig %} #} {% endif %} {% if somevar is boolean %} {# no equivalent in Twig %} #} {% endif %} {% if somevar is bool %} {# same as boolean test above, alternate way to write it %} #} {% endif %} {% if somevar is array %} {# no equivalent in Twig %} #} {% endif %}
转换为类型:intval、strval、floatval和boolval过滤器
将变量转换为特定类型不是Twig所鼓励的,如果可能的话,应该避免这样做。然而,有些情况下,你可能只是想将某些内容转换为整数或字符串,以确保比较是类型安全的,或者没有由于类型错误而产生的意外行为。
{% if '5'|intval === 5 %} Convert '5' to an integer - this if block is being executed {% endif %} {% if 5.7|strval === '5.7' %} Convert 5.7 to a string - this if block is being executed {% endif %} {% if 1|boolval === true %} Convert 1 to a boolean - this if block is being executed {% endif %} {% if '5.7'|floatval === 5.7 %} Convert '5.7' to a float - this if block is being executed {% endif %}
这些过滤器的主要行为与PHP中的过滤器类似(并内部使用相应的PHP函数),但有一些额外的行为来检测或避免可能出现的错误。
- 只允许标量值、null和具有__toString方法的对象,因此如果你使用任何这些过滤器与数组或无法转换为字符串的对象,将会抛出异常。
- null对于intval返回0,对于strval返回'',对于boolval返回false,对于floatval返回0.0(就像在PHP中一样)。
- 具有__toString方法的对象将首先被转换为字符串(使用__toString方法),然后才会使用intval、boolval和floatval。
- boolval应该谨慎使用,因为如果你给它任何非数字字符串,它将返回true,而空字符串和"0"将返回false。boolval在这里更多是为了完整性,因为可能是PHP中用途最少的转换函数。建议如果可能的话,使用其他三个函数而不是使用boolval。
&& 和 ||
如果你想使表达式更像PHP,可以使用&&
代替and
,使用||
代替or
。这可能是这个库中最不有用的一部分,因为and
和or
已经很短且清晰,但这是另一个容易解决的 Twig 和 PHP 之间的差异,而且&&
和||
在比较时可能更容易被发现。
{% if someflag === true && otherflag === false %} instead of if someflag === true and otherflag === false {% endif %} {% if someflag === true || otherflag === true %} instead of if someflag === true or otherflag === false {% endif %}