PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, May 11, 2022

[FIXED] How to inject global variables into all templates?

 May 11, 2022     php, symfony, symfony4, twig     No comments   

Issue

In my twig template there are some variables that are required on each page like userName, userId or userImage.

What is the best way to inject them into the template?

I already read the article How to Inject Variables into all Templates but how could I write a variable (e.g. current user) into the config/packages/twig.php file?

Right now there is code like this in every controller:

return $this->render('admin/users/index.html.twig', [
   "allUsers" => $allUsers,
   "pageTitle" => "Benutzerübersicht",
   "userName" => "Max Mustermann",
   "userId" => 5,
   "userImage" => "http://i.pravatar.cc/150?img=6"
]);

(These are only example values as I didn't integrate the Authentication yet but wanted to create my template)

Is there any better way than injecting every variable in each controller?


Solution

You have several options, depending exactly on what do you need:

###You could inject this as Twig global variables using an Event Listener.

  1. Create a listener class:
namespace App\Listener;
// src/EventListener/ControllerListener.php

use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Security\Core\Security;
use Twig\Environment;

class ControllerListener {
    /**
     * @var \Twig\Environment
     */
    private $twig;
    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $manager;
    /**
     * @var \Symfony\Component\Security\Core\Security
     */
    private $security;

    public function __construct( Environment $twig, EntityManager $manager, Security $security ) {
        $this->twig     = $twig;
        $this->manager  = $manager;
        $this->security = $security;
    }

    public function onKernelController( FilterControllerEvent $event ): void {
        $results = $this->manager->getRepository( 'SomeClass' )->findBy( [ 'some' => 'criteria' ] );
        $user    = $this->security->getUser();
        $this->twig->addGlobal( 'veryGlobal', $results[0]->getName() );
        $this->twig->addGlobal( 'username', $user->getUsername() );
    }
}

I'm injecting:

  • Twig, so you can add the global variables there.
  • Entity Manager, so you can query the DB if you need to grab info from there
  • Security, to grab information from the user.
  1. After this is created, you need to add this configuration lines:
# config/services.yaml
services:
    App\EventListener\ControllerListener:
        tags:
            - { name: kernel.event_listener, event: kernel.controller }

which will enable the event listener to run on each request.

Use twig configuration to inject a service-as-a-global:

With these configuration lines, as described in the documentation, you tell twig to inject a specific service:

# config/packages/twig.yaml
twig:
    # ...
    globals:
        # the value is the service's id
        users: '@App\Service\UserManagement'

Then it's as simple as creating App\Service\UserManagement:

namespace App\Service:

class UserManagement {

   public function __construct() {
      // use the constructor to inject your dependencies, as usual
   }

   public function getOldestUser() {
      // do your thing
      return $oldestUserName;
   }
}

Then from twig you can do:

{{ users.oldestUser }}

Note that every time you called users.OldestUser the method will be executed, which could be resource intensive depending on what you are doing. Caching the result on a local property for that service would probably be a good idea.

Finally, if you are only interested in logged-in user data

As others mentioned, if you are only interested in data belonging to the logged-in user, you can simply access it through the app variable, which is injected on each request.

The representation of the current user or null if there is none. The value stored in this variable can be a UserInterface object, any other object which implements a __toString() method or even a regular string.

For example:

{{ app.user.userName }}


Answered By - yivi
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing