【问题标题】:What to use instead of Twig_Loader_String用什么代替 Twig_Loader_String
【发布时间】:2015-06-26 20:47:52
【问题描述】:

我看到 Twig_Loader_String 类已被弃用,并将在 Twig 2.0 中删除。此外,源代码中的 cmets 表明它应该“永远不要使用”。

包含 Twig 模板的字符串有许多有效用例。

问题是:改用什么?

【问题讨论】:

    标签: symfony twig


    【解决方案1】:

    应该使用Twig_Environment#createTemplate,如issue deprecating Twig_Loader_String

    // the loader is not important, you can even just
    // use the twig service in Symfony here
    $twig = new \Twig_Environment(...);
    
    $template = $twig->createTemplate('Hello {{ name }}!');
    echo $template->render(['name' => 'Bob']);
    

    此代码是最简单的方法,并且绕过了完整的缓存系统。这意味着它没有Twig_Loader_String 的缺点(它不会在您每次调用render 时创建一个新的缓存条目;它在引用其他模板时没有问题;等等),但是它仍然不如使用Twig_Loader_Array(如@AlainTiemblo 的回答所示)或Twig_Loader_Filesystem 那样快。

    【讨论】:

    • 这实际上不起作用。首先,Twig_Loader_Array::__construct() 需要一个数组作为其唯一参数。其次,修复该问题后,render() 调用会引发可捕获的致命错误:类 __TwigTemplate_dd0d0e2c37a2d0f8b67dcdcd30ecb79029586ee23cd1c76f343d6878b2fdbb35 的对象无法转换为字符串错误。
    • 对不起,@AlainTiemblo。看起来很快,并认为您只删除了块引用样式。我再次回滚了您的更改,然后用另一个代码替换了它们,这更好一点。
    • 在twig_loader_array的cmets中也有说只能在单元测试环境中使用,不能在生产环境中使用
    【解决方案2】:

    Twig_Loader_Array 加载器将 $templateName => $templateContents 数组作为参数,因此可以使用模板名称完成一些缓存内容。

    所以这个实现有效:

    $templates = array('hello' => 'Hello, {{ name }}');
    $env = new \Twig_Environment(new \Twig_Loader_Array($templates));
    echo $env->render('hello', array('name' => 'Bob'));
    

    或者:

    $env = new \Twig_Environment(new \Twig_Loader_Array(array()));
    $template = $env->createTemplate('Hello, {{ name }}');
    echo $template->render(array('name' => 'Bob')); 
    

    为了澄清谣言,从第一个 Twig 版本开始,Twig_Loader_Array 在其构造函数中采用了一个数组。没有数组初始化Twig_Loader_Array的所有答案都是错误的。

    【讨论】:

      【解决方案3】:
      $tplName = uniqid( 'string_template_', true );
      $env = clone $this->getTwig();
      $env->setCache(false);
      $env->setLoader( new \Twig_Loader_Array( [ $tplName => 'Hello, {{ name }}' ] ));
      $html = new Response( $env->render( $tplName, [ 'name' => 'Bob' ] ));
      
      echo $html; // Hello, Bob
      

      【讨论】:

      • 这正是我最初想做的,而且没有缓存文件的麻烦。谢谢!
      • $twig 来自哪里?这不应该是$env->setCache(false) 吗?
      • 你应该使用 $twig->createTemplate (见@Wouter J 的回答)
      • 是的,createTemplate 比克隆 twig 服务安全得多
      【解决方案4】:

      试试看

      $template = $this->container->get('twig')->createTemplate('hello {{ name }}');
      echo $template->render(array('name' => 'Fabien'));
      

      【讨论】:

        【解决方案5】:
        $environment = new \Twig_Environment(new \Twig_Loader_Array(array()));
        $template = $environment->createTemplate('{{ template }} {{ replacements }}');
        
        echo $template->render([replacements]);
        

        【讨论】:

        • 这个不行,看lib/Twig/Loader/Array.phppublic function __construct(array $templates)
        • 对不起,它应该是构造函数中的一个空数组。 (或您希望设置的任何预定义模板。)我已经编辑了我的答案。
        • 是的,这种方式没问题,但请注意,您没有利用 Twig 缓存系统。无论如何,这对字符串加载器来说是一个真正的答案/解决方法。
        【解决方案6】:

        最好的是: http://twig.sensiolabs.org/doc/2.x/recipes.html#loading-a-template-from-a-string

        作为我使用的示例:

        public function parse($content, $maxLoops = 3, $context = array())
        {
            if (strlen($content) < 1) {
                return null;
            }
        
            for ($i = 0; $i < $maxLoops; $i++) {
                $template = $this->container->get('twig')->createTemplate($content);
                $result = $template->render( $context );
        
                if ($result == $content) {
                    break;
                } else {
                    $content = $result;
                }
            }
        
            return $content;
        }
        

        【讨论】:

          【解决方案7】:

          这实际上似乎按预期工作:

          $tplName = uniqid( 'string_template_', true );
          $env = clone $this->getTwig();
          $env->setLoader( new \Twig_Loader_Array( [ $tplName => 'Hello, {{ name }}' ] ));
          $html = new Response( $env->render( $tplName, [ 'name' => 'Bob' ] ));
          $cacheName = $env->getCacheFilename( $tplName );
          if( is_file( $cacheName ) )
          {
            unlink( $cacheName );
          }
          echo $html; // Hello, Bob
          

          我在这里找到了提示:http://twig.sensiolabs.org/doc/recipes.html#using-different-template-sources

          请注意,如果模板字符串来自数据库或类似的东西,则不希望删除缓存文件。我使用此功能来渲染动态创建且寿命很短的模板,通常在调试和测试时。

          【讨论】:

          • \Twig_Loader_array 应该只用于单元测试
          猜你喜欢
          • 2015-09-19
          • 2013-11-04
          • 2018-06-18
          • 2021-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多