我想根据this RFC为Twig定义null-coalescing运算符。也就是说我应该可以写一个像
这样的表达式{{ x ?? y ?? 5 }}
如果已定义且非空,则返回x
,否则y
如果已定义且非空,则返回5。
如果strict_variables
已启用,则不错误。
我已经开始实施,但我不太了解Twig的内部结构来完成它。
我们可以使用扩展名定义运算符:
class Core extends \Twig_Extension {
public function getName() {
return 'nullcoalesce';
}
public function getOperators() {
return [
[], // I *think* these are where the unary operators go...?
[
'??' => array('precedence' => 20, 'class' => NullCoalesce::class, 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT),
]
];
}
}
接下来是运营商:
class NullCoalesce extends \Twig_Node_Expression_Binary
{
public function compile(\Twig_Compiler $compiler)
{
// ???
}
public function operator(\Twig_Compiler $compiler)
{
// ???
}
}
如何填写这些方法以获得所需的结果?
答案 0 :(得分:2)
由于Twig文件被编译为PHP代码,您需要告诉Twig如何在PHP中转换新的运算符:
public function compile(\Twig_Compiler $compiler)
{
// gives random variable name
$var = $compiler->getVarName();
// compiles: (($var = left) !== NULL ? $var : right)
$compiler
->raw(sprintf('(($%s = ', $var))
->subcompile($this->getNode('left'))
->raw(sprintf(') !== NULL ? $%s : ', $var))
->subcompile($this->getNode('right'))
->raw(sprintf(')'))
;
}
public function operator(\Twig_Compiler $compiler)
{
return $compiler->raw('');
}
关于这个主题的文档有点差,但如果有人需要更多样本,lib/Twig/Node/Expression/Binary
中有很多现有的运算符。
关于您对扩展程序中存储运算符的方式的评论,您是对的。如果你看一下Twig的Environment.php的initExtension
方法,你会看到:
$this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
$this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
在扩展程序getUnaryOperators
和getBinaryOperators
中使用2个方法会更容易,但无论如何,这都在文档中,所以我们不能因此而责怪它们: - )。