0

I'm using Twig and Slim4 with DI container (the same as this tutorial: https://odan.github.io/2019/11/05/slim4-tutorial.html). I would like to know how can I add a common model to all my twig views, for example user object, general options and something like this.

This is the container Twig initialization:

TwigMiddleware::class => function (ContainerInterface $container) {
    return TwigMiddleware::createFromContainer($container->get(App::class), Twig::class);
},

// Twig templates
Twig::class => function (ContainerInterface $container) {
    $config = $container->get(Configuration::class);
    $twigSettings = $config->getArray('twig');        
    $twig = Twig::create($twigSettings['path'], $twigSettings['settings']);
    return $twig;
},

The twig middleware is the Slim standard one: Slim\Views\TwigMiddleware

Tobia
  • 9,165
  • 28
  • 114
  • 219

1 Answers1

1

You can add global variables to Twig environment, so they are accessible in all template files:

(To be able to provide a sample code, I assumed you have defined a service like user-authentication-service which is capable of resolving current user)

// Twig templates
Twig::class => function (ContainerInterface $container) {
    //...        
    $twig = Twig::create($twigSettings['path'], $twigSettings['settings']);
    $twig->getEnvironment()->addGlobal(
        'general_settings',
        [
            'site_name' => 'my personal website',
            'contact_info' => 'me@example.com'
        ]);
    $twig->getEnvironment()->addGlobal(
        'current_user',
        // assuming this returns current user
        $container->get('user-authentication-service')->getCurrentUser()
    );
    return $twig;
},

Now you have access to general_settings and current_user in all of your template files.

Nima
  • 3,309
  • 6
  • 27
  • 44
  • Thank you for your explanation! But this code when is evaluated? before th route dispatch? – Tobia Apr 09 '20 at 12:59
  • It is evaluated whenever the DI needs resolve an instance of `Twig`. Looking at the code in your question, I'd say that is when you want to add `TwigMiddleware` to your app. This example only demonstrates how to add a globally accessible variable to Twig environment, but if your comment is about _where_ to put this code, I'd probably say in a middleware. That gives you more control over order of middlewares processing each request, so for example you can make sure the `user object` is actually available before trying to define it as a global variable. – Nima Apr 09 '20 at 13:27
  • Any change to put the globals before the rendering of the template instead of inside a middleware? (as far as I know the middleware order is defined by the middleware inserition order). Maybe the business logic of the route can modify the global objects (user data, options, ...) – Tobia Apr 09 '20 at 13:32
  • Yes, the order in which middlewares are executed is related to the order they are added to routes. You have some options to work with middlewares and assign appropriate values to these variables for different routes, but If the business logic of routes affect the value of the variable, maybe they are really not _common_ variables? – Nima Apr 09 '20 at 17:00