rcrowe / TwigBridge

Give the power of Twig to Laravel
MIT License
895 stars 165 forks source link

Twig cache file has path instead of name in laravel view cache for getTemplateName() #438

Open hsingh124 opened 2 months ago

hsingh124 commented 2 months ago

Hi,

I have a laravel app using twigbridge. Whenever a template is rendered for the first time, its view cache file contains its directory path instead of its name in getTemplateName() method. All the sub templates rendered by that template (using include) have correct names in their view cache files. This is causing problems with laravel view composer as it is not being triggered due to the wrong template names.

For example, the cache file has:

public function getTemplateName()
{
    return "/var/www/app-name/resources/views/pages/profile/alternatives.twig";
}

instead of:

public function getTemplateName()
{
    return "pages.profile.alternatives";
}

Is this expected behaviour? Is there a way to use template names instead of path in this case?

Thanks!

hsingh124 commented 2 months ago

I think the issue might be that the load method here: https://github.com/rcrowe/TwigBridge/blob/master/src/Engine/Compiler.php is sending in the path to $this->twig->load($path);:

public function load($path)
{
    // Load template
    try {
        $tmplWrapper = $this->twig->load($path);
    } catch (Exception $e) {
        throw new InvalidArgumentException("Error loading $path: ". $e->getMessage(), $e->getCode(), $e);
    }

    return $tmplWrapper;
}

If we check the load method in twig, it takes in a name: https://github.com/twigphp/Twig/blob/3.x/src/Environment.php

public function load($name): TemplateWrapper
{
    if ($name instanceof TemplateWrapper) {
        return $name;
    }

    return new TemplateWrapper($this, $this->loadTemplate($this->getTemplateClass($name), $name));
}

Should we normalize the path before sending it to twig? Something like this maybe:

public function load($path)
{
    // Load template
    try {
        $path = str_replace(resource_path('views') . '/', '', $path);
        if (substr($path, -5) === ".twig") {
            $path = substr($path, 0, -5);
        }
        $path = ViewName::normalize($path);

        $tmplWrapper = $this->twig->load($path);
    } catch (Exception $e) {
        throw new InvalidArgumentException("Error loading $path: ". $e->getMessage(), $e->getCode(), $e);
    }

    return $tmplWrapper;
}
hsingh124 commented 2 months ago

Found this PR and my issue sounds similar to what is mentioned in this: https://github.com/rcrowe/TwigBridge/pull/424

hsingh124 commented 2 months ago

@barryvdh I've created a PR for this fix: https://github.com/rcrowe/TwigBridge/pull/439

I'm not sure if this is the proper solution for this so please suggest any updates or alternative approaches if required.

Thanks!


Update: Closed the PR as it will not work in all the cases, for example with themes. Could this potentially be a problem with my config? Any help on this is appreciated. Thanks!