parseExpression in Twig - PullRequest
       1

parseExpression in Twig

1 голос
/ 12 февраля 2012

Я интегрирую Twig в существующий проект.

Я пишу синтаксический анализатор токенов для анализа пользовательского тега, аналогичного тегу {% render %}.

Мой тег выглядит следующим образом:

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

, где имя определяется как {% 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, которое я не могу использовать.

Как я могу превратить проанализированное выражение в ассоциативный массив?

1 Ответ

0 голосов
/ 09 апреля 2012

Окей.Я думаю, я смог решить это.Не очень, но должно работать.

$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, который я могу передать в пользовательский узел.1008 *

$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, но, к сожалению, я не нашел решения, чтобы перевернуть его там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...