user1032531 user1032531 - 1 month ago 23
PHP Question

How to configure Twig to find templates?

I am using Twig with Slim, and am getting the following error:


Warning: file_get_contents(application/templates/config.html): failed
to open stream: No such file or directory in
/var/www/testing/vendor/twig/twig/lib/Twig/Loader/Filesystem.php on
line 131


The script below is located in
/var/www/testing/html/index.php
, and I have verified that the template exists at
/var/www/testing/application/templates/config.html
.

$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('../application/templates', [
//'cache' => 'path/to/cache' // See auto_reload option
'debug' => true,
'strict_variables'=> true
]);
$view->addExtension(new \Slim\Views\TwigExtension(
$c['router'],
$c['request']->getUri()
));
$view->addExtension(new \Twig_Extension_Debug());
return $view;
};

$app->get('/config', function (Request $request, Response $response) {
return $this->view->render($response, 'config.html',[]);
});


Line 131 is shown below and returns
config.html
.

public function getSource($name)
{
return file_get_contents($this->findTemplate($name));
}


I have used this same script in another similar server (however, maybe different PHP version and php.ini and httpd.conf may be different), and do not have this issue?

Obviously, I have configured something incorrectly. How should I configure Twig to find templates?

Answer

Yes, that's a problem (bug?) I've encountered last week, and @geggleto solved it.

This is because of Twig update from v1.26.1 from 1.24.2.

This is how Twig grabbed in 1.24.2 (method Twig_Loader_Filesystem::normalizeName):

protected function normalizeName($name)
{
    return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
}

And this is how it grabs file in 1.26.1:

private function normalizePath($path)
{
    $parts = explode('/', str_replace('\\', '/', $path));
    $isPhar = strpos($path, 'phar://') === 0;
    $new = array();
    foreach ($parts as $i => $part) {
        if ('..' === $part) {
            array_pop($new);
        } elseif ('.' !== $part && ('' !== $part || 0 === $i || $isPhar && $i < 3)) {
            $new[] = $part;
        }
    }
    return implode('/', $new);
}

See that array_pop($new); line? That's the one that ruins use of relative path.

@geggleto suggested to use absolute path instead of relative, and it worked:

\Slim\Views\Twig(__DIR__.'/../application/templates')

To sum up: this happens because of Twig new version.