Переменные Twig в переменной веточки

У меня есть переменная html. Чтобы показать это в шаблоне ветки, я {{html}}.

Эта переменная выглядит так:

<div>{{region_top}}</div><div>{{region_center}}</div>

region_* тоже переменная. Когда Twig анализирует мою переменную html, она не анализирует внутренние переменные (регионы).

Что я должен делать?

Ответы

Ответ 1

У меня есть переменная html twig. Чтобы показать его в шаблоне ветки, я {{html}}. Эта переменная выглядит как {{region_top}} {{region_center}}. region_ * тоже переменные. Когда прут анализирует мою переменную html, он не анализирует внутренние переменные (области). Что я могу сделать?

Twig берет ваши строки как литеральную строку, то есть вы увидите содержимое переменной, экранированное. Если вы хотите, чтобы он мог отображать {{region_top}}, я бы рекомендовал что-то вроде этого:

{{html|replace({'{{region_top}}': region_top, '{{region_center}}': region_center})}}

Если содержимое вашей html-переменной также является динамическим (это значит, что оно может содержать не только эти две переменные), я бы написал плагин twig, который может делать то, что вы хотите. Написание плагинов довольно легко сделать.

EDIT: здесь расширение, которое я только что закончил писать.

EDIT 2: расширение теперь использует среду для визуализации строки, поэтому она оценивает строку вместо замены переменных. Это означает, что ваша переменная может содержать все, что может быть в шаблоне, и она будет отображаться и удаляться самим Twig. Я классный.

<?php

/**
* A twig extension that will add an "evaluate" filter, for dynamic evaluation.
*/
class EvaluateExtension extends \Twig_Extension {
    /**
    * Attaches the innervars filter to the Twig Environment.
    * 
    * @return array
    */
    public function getFilters( ) {
        return array(
            'evaluate' => new \Twig_Filter_Method( $this, 'evaluate', array(
                'needs_environment' => true,
                'needs_context' => true,
                'is_safe' => array(
                    'evaluate' => true
                )
            ))
        );
    }

    /**
     * This function will evaluate $string through the $environment, and return its results.
     * 
     * @param array $context
     * @param string $string 
     */
    public function evaluate( \Twig_Environment $environment, $context, $string ) {
        $loader = $environment->getLoader( );

        $parsed = $this->parseString( $environment, $context, $string );

        $environment->setLoader( $loader );
        return $parsed;
    }

    /**
     * Sets the parser for the environment to Twig_Loader_String, and parsed the string $string.
     * 
     * @param \Twig_Environment $environment
     * @param array $context
     * @param string $string
     * @return string 
     */
    protected function parseString( \Twig_Environment $environment, $context, $string ) {
        $environment->setLoader( new \Twig_Loader_String( ) );
        return $environment->render( $string, $context );
    }

    /**
     * Returns the name of this extension.
     * 
     * @return string
     */
    public function getName( ) {
        return 'evaluate';
    }
}

Пример использования:

$twig_environment->addExtension( new EvaluateExtension( ) );

В шаблоне:

{% set var = 'inner variable' %}
{{'this is a string with an {{var}}'|evaluate}}

Ответ 2

См. http://twig.sensiolabs.org/doc/functions/template_from_string.html

Похоже, что это часто пропускается, так как большинство людей думают (и ищут) "eval", ожидая, что фильтр/функция будет оцениваться на текущем языке, который они создают. Шаблон из строки - это не первый поисковый запрос это приходит в голову.

Ответ 3

Один из вариантов - отображать ваши шаблоны в виде строк. Вы можете сделать это вот так:

$env = new \Twig_Environment(new \Twig_Loader_String());
echo $env->render(
  "Hello {{ name }}",
  array("name" => "World")
);

Я оставлю это вам, чтобы решить, как именно структурировать ваш код, чтобы сделать эту работу, но может выглядеть примерно так: 1) Извлеките внутренний текст шаблона, который содержит переменные, которые не заменяются. 2) Измените этот внутренний текст шаблона в переменную $html. Обязательно пройдите в любые вамры. 3) Измените исходный шаблон, содержащий {{html}}. Обязательно перейдите в 'html' = > $html в массиве vars

Ответ 4

Вы также можете передать массив или объект в представление, а затем использовать метод twig attribute(): http://twig.sensiolabs.org/doc/functions/attribute.html

{% if attribute(array, key) is defined %}
    {{ attribute(array, key) }}
{% endif %}