如何在Symfony2环境中注册另一个(自定义)Twig加载器?

时间:2013-01-15 17:34:31

标签: templates symfony twig

我想在我的Symfony2应用程序中从数据库加载某些Twig模板,同时仍然保留使用本机加载器在标准文件系统位置呈现模板的可能性。怎么做到这一点?

据我所知,没有可能在Twig环境中注册多个加载器。我一直在想两种方式(现在):

  • Replace the default loader带有自定义代理类。当使用标准@Bundle-notation引用模板时,代理会将请求传递给默认加载器。在其他情况下,请求将传递给我的自定义(数据库)加载器; OR
  • 构建一个全新的Twig环境。此方法需要向两个环境注册自定义Twig扩展,并且不允许来自不同来源的交叉引用模板(一些来自@Bundles,一些来自数据库)

更新1:

似乎Twig支持可以在我的第一个选项中使用的Twig_Loader_Chain类。尽管如此,默认加载器应该是可访问的,并作为第一个选项传递给链。

2 个答案:

答案 0 :(得分:6)

要使用Twig_Loader_Chain,您需要Symfony 2.2 https://github.com/symfony/symfony/pull/6131
然后你可以简单地配置你的装载机:

services:
    twig.loader.filesystem:
        class: %twig.loader.filesystem.class%
        arguments:
            - @templating.locator
            - @templating.name_parser
        tags:
            - { name: twig.loader }
    twig.loader.string:
        class: %twig.loader.string.class%
        tags:
            - { name: twig.loader }

更新:
看起来仍然存在一些问题(文件系统加载器无法找到模板)但我发现了这一点:
http://forum.symfony-project.org/viewtopic.php?t=40382&p=131254

似乎工作得很好!

答案 1 :(得分:1)

这是一种廉价而愉快的方式来临时更改标准环境中的加载程序:

    // Keep the current loader
    $oldLoader = $env->getLoader();

    // Temporarily set a string loader   
    $env->setLoader(new \Twig_Loader_String());

    // Resolve the template - but don't render it yet.
    $template = $env->resolveTemplate($template);

    // Restore the old loader
    $env->setLoader($oldLoader);

    // Render the template. This will pass the old loader into any subtemplates and make sure your string based template gets into the cache.
    $result = $template->render($context);

我想这可以与其他自定义加载器一起使用。