Twig 中的解析表达式

发布于 2025-01-05 05:53:17 字数 1444 浏览 1 评论 0原文

我正在将 Twig 集成到现有项目中。

我正在编写一个令牌解析器来解析类似于 {% render %} 标签的自定义标签。

我的标签如下所示:

{% mytag 'somestring' with { 'name': name, 'color': 'green' } %}

其中 name 由 {% set name = 'foo' %} 定义

我能够毫无问题地解析 somestring

这是用于解析 with{ } 中的内容的代码:

$Stream = $this->parser->getStream();

if ( $Stream->test( \Twig_Token::NAME_TYPE, 'with' ) )
{
    $Stream->next();

    $parsedParameters = $this->parser->getExpressionParser()->parseExpression();
    $parameters       = $this->parser->getEnvironment()->compile( $parsedParameters );

    var_dump( $parameters ); //string 'array( "name" => $this->getContext( $context, "name" ), "color" => "green" )' (length=72)

    foreach ( $parsedParameters->getIterator() as $parameter )
    {
        //var_dump($ parameter->getAttribute('value') );
    }
}

我的目标是将 'name': name, 'color': 'green' 转换为关联令牌解析器中的数组:

array(
   'name' => 'foo',
   'color': 'green',
)

由于文档非常稀疏并且库中的代码未注释,我不知道如何执行此操作。如果我循环遍历 $parsedParameters,我会得到 4 个由数组键和数组值组成的元素。但是,由于 name 是一个类型为 Twig_Node_Expression_Name 的变量,我不确定如何编译它以获得编译值。目前,我已经找到了一种编译该节点的方法,但它给我的只是一个包含我无法使用的 PHP 表达式的字符串。

如何将解析的表达式转换为关联数组?

I am integrating Twig in an existing project.

I am writing a token parser to parse a custom tag that is similiar to the {% render %} tag.

My tag looks like:

{% mytag 'somestring' with { 'name': name, 'color': 'green' } %}

where name is defined by {% set name = 'foo' %}

I am able to parse somestring without any issues.

This is the code used to parse the stuff in the with{ }:

$Stream = $this->parser->getStream();

if ( $Stream->test( \Twig_Token::NAME_TYPE, 'with' ) )
{
    $Stream->next();

    $parsedParameters = $this->parser->getExpressionParser()->parseExpression();
    $parameters       = $this->parser->getEnvironment()->compile( $parsedParameters );

    var_dump( $parameters ); //string 'array( "name" => $this->getContext( $context, "name" ), "color" => "green" )' (length=72)

    foreach ( $parsedParameters->getIterator() as $parameter )
    {
        //var_dump($ parameter->getAttribute('value') );
    }
}

My goal is to turn 'name': name, 'color': 'green' into an associative array within the token parser:

array(
   'name' => 'foo',
   'color': 'green',
)

As the documentation is quite sparse and the code in the library is uncommented, I am not sure how to do this. If I loop through $parsedParameters, I get 4 elements consisting of the array key and an array value. However, as name is a variable with a type Twig_Node_Expression_Name, I am unsure as to how I can compile it to get the compiled value. Currently, I have found a way to compile that node, but all it gives me is a string containing a PHP expression which I can't use.

How can I turn the parsed expression into an associative array?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哎呦我呸! 2025-01-12 05:53:17

好的。我想我能够解决这个问题。不漂亮,但应该有用。

$Stream = $this->parser->getStream();

if ( $Stream->test( \Twig_Token::NAME_TYPE, 'with' ) )
{
    $Stream->next();

    $parsedParameters = $this->parser->getExpressionParser()->parseExpression();
    $parameters       = $this->parser->getEnvironment()->compile( $parsedParameters );

    var_dump( $parameters ); //string 'array( "name" => $this->getContext( $context, "name" ), "color" => "green" )' (length=72)

    $index = null;
    $value = null;

    foreach ( $parsedParameters->getIterator() as $parameter )
    {
        if ( $parameter->hasAttribute( 'value' ) )
        {
            $index = $parameter->getAttribute( 'value' );
        }
        elseif ( $parameter->hasAttribute( 'name' ) )
        {
            $value = $parameter->getAttribute( 'name' );
        }

        if ( isset( $index, $value ) )
        {
            $params[ $index ] = $value;

            $index = null;
            $value = null;
        }
    }
}

所以这里我有数组params,我可以将其传递给自定义节点。

$params = var_export( $properties['params'], true );
unset( $fieldProperties['params'] );

现在我只是做了以下事情:

$Compiler
    ->write( "\$params = array();\n" )

    ->write( "foreach ( {$params} as \$searchFor => \$replaceWith )\n" )
    ->write( "{\n" )
    ->write( "\t\$params[ \$searchFor ] = str_replace( \$replaceWith, \$context[\$replaceWith], \$replaceWith );\n" )
    ->write( "}\n" )

    ->write( "var_dump( \$params );\n" );

应该是这样。

我还看到,您在谈论 TokenParser,但遗憾的是我还没有找到将其移交给那里的解决方案。

Okey. I guess I was able to solve that. Not to pretty, but should work.

$Stream = $this->parser->getStream();

if ( $Stream->test( \Twig_Token::NAME_TYPE, 'with' ) )
{
    $Stream->next();

    $parsedParameters = $this->parser->getExpressionParser()->parseExpression();
    $parameters       = $this->parser->getEnvironment()->compile( $parsedParameters );

    var_dump( $parameters ); //string 'array( "name" => $this->getContext( $context, "name" ), "color" => "green" )' (length=72)

    $index = null;
    $value = null;

    foreach ( $parsedParameters->getIterator() as $parameter )
    {
        if ( $parameter->hasAttribute( 'value' ) )
        {
            $index = $parameter->getAttribute( 'value' );
        }
        elseif ( $parameter->hasAttribute( 'name' ) )
        {
            $value = $parameter->getAttribute( 'name' );
        }

        if ( isset( $index, $value ) )
        {
            $params[ $index ] = $value;

            $index = null;
            $value = null;
        }
    }
}

So here I have array params, that I can pass to Custom node.

$params = var_export( $properties['params'], true );
unset( $fieldProperties['params'] );

Now I just did following:

$Compiler
    ->write( "\$params = array();\n" )

    ->write( "foreach ( {$params} as \$searchFor => \$replaceWith )\n" )
    ->write( "{\n" )
    ->write( "\t\$params[ \$searchFor ] = str_replace( \$replaceWith, \$context[\$replaceWith], \$replaceWith );\n" )
    ->write( "}\n" )

    ->write( "var_dump( \$params );\n" );

This should be it.

Also I see, that you where talking about TokenParser, but sadly I haven't found the solution to turn it over there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文