有没有办法在渲染之前显示树枝模板的原始内容?

时间:2015-01-09 07:44:55

标签: php symfony twig

有人知道在渲染任何内容之前是否有方法显示树枝模板的原始原始内容?

假设我有一个根模板:

{# templates/template.txt.twig #}
This is my root template
{{arg1}}
{{ include('other/internal.txt.twig') }}

另一个来自根源:

{# templates/other/internal.txt.twig #}
This is my included template
{{arg2}}

如果我用arg1 ='foo'和arg2 ='bar'渲染template.txt.twig,结果将是

This is my root template
foo
This is my included template
bar

有没有办法在任何变量评估之前检索加载的模板? 我期望得到这样的东西:

This is my root template
{{arg1}}
This is my included template
{{arg2}}

背后的想法是利用所有树枝加载机制(加载路径,命名空间......) 因为我需要对树枝代码本身进行一些自定义自动检查(与树枝语法无关,但与树枝无关的高级模型的一致性)

如果这有意义,或者您需要更多信息,请告诉我 谢谢你的帮助

3 个答案:

答案 0 :(得分:1)

为了渲染模板,Twig将Twig内容编译成PHP代码,所以我不认为这可以通过Twig本身实现。您可以查看Thierry为您提供的the docthe presentation of Matthias Noback链接。

我认为您唯一的解决方案是使用file_get_contents阅读该文件,但您不会像在您的例子中那样将所包含的模板放在正确的位置。

答案 1 :(得分:1)

如果您想在呈现模板之前使用某种服务处理模板,那么您可以覆盖树枝环境并使用loadTemplate方法运行检查。

例如,在这里我将注入一个templateValidator,然后在每个模板加载时运行它。

应用\ AcmeBundle \枝条\ Twig_Environment

首先展开\Twig_Environment并覆盖loadTemplate方法,并添加一个用于注入templateValidator的setter。

loadTemplate中,我已将$this->getLoader()->getSource($name)的{​​{1}}替换为$this->validateTemplate($name),它们执行相同的操作,但也在您希望添加的操作之前(在这种情况下$this->templateValidator->validate($source)

namespace App\AcmeBundle\Twig;

use \Twig_Environment as BaseEnvironment;

class Twig_Environment extends BaseEnvironment
{
    protected $templateValidator;

    public function setTemplateValidator(TemplateValidator $templateValidator)
    {
        $this->templateValidator = $templateValidator;
    }

    public function loadTemplate($name, $index = null)
    {
        $cls = $this->getTemplateClass($name, $index);

        if (isset($this->loadedTemplates[$cls])) {
            return $this->loadedTemplates[$cls];
        }

        if (!class_exists($cls, false)) {
            if (false === $cache = $this->getCacheFilename($name)) {
                //eval('?>'.$this->compileSource($this->getLoader()->getSource($name), $name));
                eval('?>'.$this->compileSource($this->validateTemplate($name), $name));
            } else {
                if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) {
                    //$this->writeCacheFile($cache, $this->compileSource($this->getLoader()->getSource($name), $name));
                    $this->writeCacheFile($cache, $this->compileSource($this->validateTemplate($name), $name));
                }

                require_once $cache;
            }
        }

        if (!$this->runtimeInitialized) {
            $this->initRuntime();
        }

        return $this->loadedTemplates[$cls] = new $cls($this);
    }

    /**
     * Validate template and return source
     *
     * @param string $name
     * @return string
     */
    private function validateTemplate($name)
    {
        $source = $this->getLoader()->getSource($name);

        if (null !== $this->templateValidator) {
            $this->templateValidator->validate($source);
        }

        return $source;
    }
}

应用程序/配置/ config.yml

覆盖参数twig.class,以便DI使用您的课程而非原始\Twig_Environment

parameters:
    twig.class: App\AcmeBundle\Twig\Twig_Environment

应用\ AcmeBundle \ DependencyInject \编译\ TwigEnvironmentInjectCompilerPass

创建一个编译器类,将templateValidator注入到新创建的TwigEnvironment中(仅当它具有'setTemplateValidator'方法时才会正确降级)

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;

class TwigEnvironmentInjectCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('twig') || 
                !$container->hasDefinition('acme.template_validator'))
        {
            return;
        }

        $twig = $container->getDefinition('twig');

        if (!$twig->hasMethodCall('setTemplateValidator')) {
            return;
        }

        $twig->addMethodCall(
            'setTemplateValidator',
            array(new Reference('acme.template_validator'))
        );
    }
}

应用\ AcmeBundle \ AppAcmeBundle

将编译器传递添加到bundle build

use App\AcmeBundle\DependencyInject\Compiler\TwigEnvironmentInjectCompilerPass;

class AppAcmeBundle extends Bundle
{
    /**
     * {@inheritdoc}
     */
    public function build(ContainerBuilder $container)
    {
        $container->addCompilerPass(new TwigEnvironmentInjectCompilerPass());
    }
}

注意这不是以任何方式进行测试的,它只是我的头脑,所以它可能都是错的。

答案 2 :(得分:0)

我相信Elao/WebProfilerExtraBundle位于:

https://github.com/Elao/WebProfilerExtraBundle

可能会为您提供您在上述示例中寻求的其他详细信息。

另见:

http://qpleple.com/webprofilerbundleextra-a-must-have-tool-for-symfony2-developers/
http://www.slideshare.net/matthiasnoback/diving-deep-into-twig