Twig token parser:如何用前缀解析标签?

时间:2014-11-10 11:43:22

标签: php symfony twig

我的模板包含描述页面的Twig“标签”。这些是简单的名称/值对,如

{% role "editor" %}
{% title "Foobar" %}

我可以使用Twig扩展和自定义令牌解析器很好地处理它们,如下所示:

class RoleTokenParser extends \Twig_TokenParser
{
    public function parse(\Twig_Token $Token)
    {
        $TokenStream = $this->parser->getStream();
        $role = $TokenStream->expect(\Twig_Token::STRING_TYPE)->getValue();
        $TokenStream->expect(\Twig_Token::BLOCK_END_TYPE);
        return new RoleNode(['role' => $role], $Token->getLine(), $this->getTag());
    }

    public function getTag()
    {
        return 'role';
    }
}

但现在我想在这个名称部分“加上”前缀“

{% myapp.role "editor" %}

我知道myapprole之间的点是一个单独的标记。我不能上班的是告诉TokenParser期待什么。我尝试了以下方法:

// ...
$prefix = $TokenStream->expect(\Twig_Token::STRING_TYPE)->getValue();
$dot = $TokenStream->expect(\Twig_Token::PUNCTUATION_TYPE)->getValue();
$role = $TokenStream->expect(\Twig_Token::STRING_TYPE)->getValue();
// ...

......但这导致例外:

当我的Twig_TokenParser::getTag()返回myapp.role时,我得到:

[Twig_Error_Syntax]
Unknown tag name "myapp". Did you mean "myapp.role" at line 3

当我的Twig_TokenParser::getTag()仅返回myapp时,我得到:

[Twig_Error_Syntax]                                                        
Unexpected token "punctuation" of value "." ("string" expected) at line 3  

所以,问题是:当模式为Token_Parser时,如何告诉{% myapp.role "editor" %}期望哪些令牌?

(顺便说一下,一个适用于类似语法的解决方案(如{% myapp role "editor" %})也是可以接受的。)

2 个答案:

答案 0 :(得分:2)

您无法在标记名称中添加标点符号。

在您的令牌解析器中,STRING_TYPE可以引用标记名称的第一个参数,而不是标记名称本身。

可以使用以下内容解析{% role myapp "editor" %}之类的内容:

$prefix = $TokenStream->expect(\Twig_Token::NAME_TYPE)->getValue(); // myapp
$role = $TokenStream->expect(\Twig_Token::STRING_TYPE)->getValue(); // editor

答案 1 :(得分:1)

除了Wouter J's answer

可能在标签中有一个点,但Twig不会将整个事物视为标签名称,而是使用点启动令牌流。但这很好,因为这正是理想的行为。

你只需要用点开始解析:

// works for {% myapp.key "value" %}
$dot = $TokenStream->expect(\Twig_Token::PUNCTUATION_TYPE, '.')->getValue();
$key = $TokenStream->expect(\Twig_Token::NAME_TYPE)->getValue();
$value = $TokenStream->expect(\Twig_Token::STRING_TYPE)->getValue();

getTag()函数必须仅返回myapp才能生效。