【问题标题】:How to get current template name in a TWIG function如何在 TWIG 函数中获取当前模板名称
【发布时间】:2012-09-29 21:54:36
【问题描述】:

假设我创建了一个自定义 twig 函数:templateName。

$twig = new Twig_Environment($loader);
$twig->addFunction('templateName', new Twig_Function_Function('twig_template_name', array('needs_environment' => true)));

有没有办法在 php.ini 中获取当前模板的名称。我想像这样:

function twig_template_name(Twig_Environment $env, $values = null) {
  return $env->getCurrentTemplateName();
}

提前致谢。

【问题讨论】:

  • 1.这不是您创建树枝函数的方式(请参阅twig.sensiolabs.org/doc/advanced.html#id2)。 2. 如果您在模板中调用它,返回模板名称的函数的值是多少?
  • 嗨。该代码仅用于说明,但感谢您的输入,我更新了问题以便更好地理解。 @2:我想发送一个 ajax 请求,它呈现完全相同的模板。
  • 您计划从 javascript 发送模板名称。由于它在客户端,因此不安全(客户端可以更改要呈现的模板名称)。我认为您应该重新考虑设计控制器/模板的方式。不知何故,您可以决定在生成页面时呈现哪个模板。调用ajax时使用相同的逻辑。
  • 我认为这不是安全问题。如果有人想改变浏览器显示页面的方式,有更简单的方法。但你是对的,它不是一个干净的。也许你可以告诉我一个更好的方法,当我更精确的时候。该函数呈现一些内容和一个编辑链接。用户可以内联编辑内容,并通过 ajax 将其存储在数据库中。现在我希望重新加载这个特殊的内容,而不是重新加载整个页面。我最初的想法是再次渲染相同的模板,剪下修改后的内容并将其发送回去。也许你有更好的想法来实现这一点。

标签: php symfony twig


【解决方案1】:

对于每个需要回答最初问题的人,我找到了 twig 本身在 Twig_Error 类中使用的解决方案。

protected function guessTemplateInfo()
{
    $template = null;
    foreach (debug_backtrace() as $trace) {
        if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
            $template = $trace['object'];
        }
    }

    // update template filename
    if (null !== $template && null === $this->filename) {
        $this->filename = $template->getTemplateName();
    }

    /* ... */

最好的问候!

【讨论】:

  • 请注意,从 CLI(例如在缓存预热期间)调用模板名称的格式与从 fpm/mod_php 调用时不同。 CLI:AppBundle:base.html.twig,FPM:@App/base.html.twig
  • $template->getSourceContext()->getPath() 似乎包含模板文件的绝对路径
【解决方案2】:

Mario A 提出的解决方案对我不起作用,但使用 debug_backtrace() 是个好主意,稍作修改使其适用于最近的 Twig 版本:

    private function getTwigTemplateName()
{
    foreach (debug_backtrace() as $trace) {
        if (isset($trace['object']) 
             && (strpos($trace['class'], 'TwigTemplate') !== false) 
             && 'Twig_Template' !== get_class($trace['object'])
        ) {
            return $trace['object']->getTemplateName() . "({$trace['line']})";
        }
    }
    return '';
}

【讨论】:

    【解决方案3】:
    $twig = new Twig_Environment($loader);
    $twig->addFunction(new Twig_SimpleFunction('twig_template_name', function() use ($twig) {
    
      $caller_template_name = $twig->getCompiler()->getFilename();
    
      echo "This function was called from {$caller_template_name}";
    
    }));
    

    更新:Leto 所述,此方法不适用于缓存(编译)模板。但是,如果您使用共享内存缓存(APC、Memcache)而不是 Twig 的缓存,或者在运行在不具有高流量的环境中的应用程序中运行此功能(想想用于员工或应用程序分支的后端应用程序)仅用于收集有关应用程序代码库的信息)您可以通过禁用 Twig 的缓存使其工作(例如$twig = new Twig_Environment($loader, array('cache' => false));)。在禁用 Twig 的缓存并使用此方法之前,请务必仔细检查您的用例,看看您是否可以使用不同的方法解决该问题。

    【讨论】:

    • 我认为这只适用于模板编译请求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2014-01-15
    • 2013-11-30
    • 2015-05-08
    • 2012-04-25
    相关资源
    最近更新 更多