如何为Twig定义空合并运算符?

时间:2014-12-02 23:15:52

标签: php twig

我想根据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)
    {
        // ???
    }
}

如何填写这些方法以获得所需的结果?

1 个答案:

答案 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]);

在扩展程序getUnaryOperatorsgetBinaryOperators中使用2个方法会更容易,但无论如何,这都在文档中,所以我们不能因此而责怪它们: - )。