有没有办法在加载任何东西之前显示树枝模板的原始内容?

Is there a way to display the original content of a twig template once it is loaded, before rendering anything?

有人知道是否有办法在加载 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}}

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

让我知道这是否有意义或者您是否需要更多信息 感谢您的帮助

我相信 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

为了呈现模板,Twig 将 Twig 内容编译成 PHP 代码,所以我认为 Twig 本身不可能做到这一点。你可以看看 Thierry 给你的 the doc or at the presentation of Matthias Noback link.

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

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

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

App\AcmeBundle\Twig\Twig_Environment

首先扩展 \Twig_Environment 并覆盖 loadTemplate 方法并添加一个 setter 用于注入 templateValidator.

loadTemplate 中,我用 $this->validateTemplate($name) 替换了 $this->getLoader()->getSource($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;
    }
}

app/config/config.yml

重写参数 twig.class 所以 DI 使用你的 class 而不是原来的 \Twig_Environment.

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

App\AcmeBundle\DependencyInject\Compiler\TwigEnvironmentInjectCompilerPass

创建一个编译器 class 以将 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'))
        );
    }
}

App\AcmeBundle\AppAcmeBundle

将您的编译器传递添加到包构建

use App\AcmeBundle\DependencyInject\Compiler\TwigEnvironmentInjectCompilerPass;

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

注意这没有经过任何测试,它只是我的头脑,所以它可能都是错误的。