13

According to the Silex documentation:

Symfony provides a Twig bridge that provides additional integration between some Symfony2 components and Twig. Add it as a dependency to your composer.json file.

I include the following in my composer.json file:

{
    "require": {
        "silex/silex": "1.*",
        "twig/twig": ">=1.8,<2.0-dev",
        "symfony/twig-bridge": "2.3.*"
    }
}

I register the TwigServiceProvider() like so:

$app->register(new Silex\Provider\TwigServiceProvider(), array(
    'twig.path' => __DIR__ . '/views'
));

I'm attempting to use the twig path() method like so:

<a href="{{ path('logout') }}">Log out</a>

The error I get is as follows:

Twig_Error_Syntax: The function "path" does not exist

Why am I getting this error?

  • I have tried switching around versions to check if it is a version issue
  • One google groups comment suggested 'registering' the twig bridge provider, but this doesn't exist
  • I don't want to have to use: app.url_generator.generate in all my templates instead

A temporary solution I have found:

Ensure The UrlGeneratorServiceProvider() is registered:

$app->register(new UrlGeneratorServiceProvider());

Create a new function for twig for path():

$app['twig']->addFunction(new \Twig_SimpleFunction('path', function($url) use ($app) {
    return $app['url_generator']->generate($url);
}));

I shouldn't have to do this!! How can I get this working properly?

Jimbo
  • 25,790
  • 15
  • 86
  • 131

3 Answers3

15

Hopefully this will help future viewers as many have posted this question without a solid answer, so here is one.

It is literally that you need UrlGeneratorServiceProvider() registered

$app->register(new UrlGeneratorServiceProvider());

Also, as umpirsky mentions in the comments, you need symfony/twig-bridge installed via composer.

You do not need to add your own function. You need both the TwigServiceProvider() and the UrlGeneratorServiceProvider() registered before loading your twig template. This isn't easily apparent from the documentation.

Jimbo
  • 25,790
  • 15
  • 86
  • 131
  • This is not the only requirement. You should register both the Twig and UrlGenerator before executing anything like `$app['twig']->addGlobal('layout', $app['twig']->loadTemplate('layout.twig'));`. Inserting this before registering UrlGenerator may cause the path() method not registered. – Slava Petrov Oct 01 '13 at 19:23
  • @VyacheslavPetrov Nowhere whatsoever does my codebase use your above described code. I feel it isn't relevant to the issue at hand. Also, it's pretty obvious that before trying to retrieve an object from the pimple DiC, trying to access said object would error. – Jimbo Oct 02 '13 at 08:49
  • Googled for the question asked, this answer doesn't work. I have registered both UrlGeneratorServiceProvider and TwigServiceProvider, but the path function still doesn't exist when rendering twig templates. – Drarok May 06 '14 at 23:10
  • @Drarok You must be doing something different. I suggest starting with a brand new clean version and trying there - it worked for 5 other users. – Jimbo May 07 '14 at 11:55
  • 1
    Note that also `symfony/twig-bridge` need to be installed, because of https://github.com/silexphp/Silex/blob/master/src/Silex/Provider/TwigServiceProvider.php#L54 – umpirsky Sep 26 '14 at 09:49
0

I too had to create a new function for twig for path(), but I improved it a bit to handle a variable number of arguments to allow passing arrays in the twig template:

$app['twig']->addFunction(new \Twig_SimpleFunction('path', function(...$url) use ($app) {
   return call_user_func_array(array($app['url_generator'], 'generate'), $url);
}));
Olivier Berger
  • 1,949
  • 1
  • 11
  • 7
0

Four easy steps.

  1. Create the loader
  2. Create the twig object.
  3. Create you custom function
  4. Add to the Twig object.

    use Twig\Environment;
    use Twig\TwigFunction;
    use Twig\Loader\FilesystemLoader;

    $loader = new FilesystemLoader('/twig/templates');
    $twig = new Environment($loader, []);

    $function = new TwigFunction('url', function () { return 'MyURL'; });
    $twig -> addFunction($function);

Daniel
  • 214
  • 4
  • 9