Mario A
Mario A

Reputation: 3363

How to get current template name in a TWIG function

let's say I have created a custom twig function: templateName.

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

Is there a way to get the name of the current template(s) in php. I imagine something like this:

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

Thanks in advance.

Upvotes: 6

Views: 6612

Answers (3)

user3283047
user3283047

Reputation: 41

The solution proposed by Mario A did not work for me, but using debug_backtrace() is a great idea and a little modification made it work with a recent Twig version:

    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 '';
}

Upvotes: 4

Sergey Lukin
Sergey Lukin

Reputation: 489

$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}";

}));

UPDATE: as mentioned by Leto, this method will NOT work from within cached (compiled) templates. If, however, you use shared memory caching (APC, Memcache) instead of Twig's caching or run this functionality in app that runs in an environment that doesn't have high traffic (think of back-end app for staff or branch of app that is only used to collect information about app's codebase) you can make it work by disabling Twig's caching (e.g. $twig = new Twig_Environment($loader, array('cache' => false));). Make sure to carefully examine your use case though before disabling Twig's cache and using this method and see if you can solve that problem using different approach.

Upvotes: 0

Mario A
Mario A

Reputation: 3363

For everyone who needs an answer to the initial question, I found a solution that twig itself is using in the Twig_Error class.

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();
    }

    /* ... */

best regards!

Upvotes: 4

Related Questions