【问题标题】:Twig variables in twig variable树枝变量中的树枝变量
【发布时间】:2012-06-08 08:09:41
【问题描述】:

我有一个树枝变量 html。为了在树枝模板中显示它,我使用{{html}}。

那个变量看起来像:

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

region_* 也是一个变量。当 Twig 解析我的 html 变量时,它不会解析内部变量(区域)。

我该怎么办?

【问题讨论】:

  • 首先接受您之前问题的答案...

标签: twig


【解决方案1】:

我有 twig 变量 html。为了在树枝模板中显示它,我使用 {{html}}。该变量看起来像 {{region_top}}{{region_center}}。 region_* 也是变量。当 twig 解析我的 html 变量时,他没有解析内部变量(区域)。我该怎么办?

Twig 将您的字符串作为文字字符串,这意味着您将看到已转义的变量内容。如果您希望它也能够显示 {{region_top}},我建议您这样做:

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

如果您的 html 变量的内容也是动态的(意味着它可以包含的不仅仅是这两个变量),我会编写一个可以执行您想要的操作的 twig 插件。编写插件很容易做到。

编辑:这是我刚刚写完的扩展。

编辑 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}}

【讨论】:

  • 也许替换过滤器可以使用preg_replace等占位符?像这样 {{html|replace({'{{$1}}': $1})}} 我不知道插件应该做什么:(
  • @Meliborn 我的意思是扩展。我刚刚检查过,但奇怪的是,我似乎无法从扩展中获取变量的值。我会继续寻找:我自己可能需要这样的东西。
  • @Meliborn 刚刚添加了一个扩展,它可以做你想做的事情:)
  • @Meliborn 刚刚更新了扩展:它现在使用环境来解析字符串,因此您可以获得普通模板中的所有好处。
  • 很棒,但是如何禁用自动转义?原始过滤器和自动转义表达式不起作用:(可能是您的扩展程序中的 render() 方法有问题?
【解决方案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}} 的原始模板。一定要在 vars 数组中传入 'html' => $html

    【讨论】:

      【解决方案4】:

      也可以将数组或对象传递给视图,然后使用twig的attribute()方法:http://twig.sensiolabs.org/doc/functions/attribute.html

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

      【讨论】:

      • 这正是我所需要的,又好又简单。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2013-08-08
      • 1970-01-01
      相关资源
      最近更新 更多