Question

In my Symfony2 app, I want to globally fetch a value from my database on each template and don't want to call on each Controller. I know I could define that as a service and inject that service into my twig templates (by defining it as a twig global).

Is that the common and recommended way? Or should I rather create an abstract Controller class where I fetch that value in my constructor and then inherit from all my other Controllers?

Note: It is actually not a static value that is the same for all users, but it is a user specific value which is different for each user.

Was it helpful?

Solution

If this variables are used to render the same spot on your page you can render an embedded controller. Like this:

<div id="sidebar">
    {{ render(controller('YourBundle:User:stats')) }}
</div>

This will inject whole output of YourBundle/UserController/statsAction to the #sidebar div. Inside this action you can extract all inforamtion that you need.

If you need to use this variables in other way maybe you should look at response event.

OTHER TIPS

Are you familiar with event listeners? http://symfony.com/doc/current/cookbook/service_container/event_listener.html

An event listener can be used to inject twig globals.

class ModelEventListener extends ContainerAware implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
    return array(
        KernelEvents::CONTROLLER => array(
            array('doProject',       -1300),
        ),
        KernelEvents::VIEW => array(
            array('doView',          -2100),
        ),
    );
}
public function doProject(FilterControllerEvent $event)
{
    $project = $whatever_is_needed_to_find_the_project();

    if (!$project) throw new NotFoundHttpException('Project not found ' . $projectSearch);

    // Add to request
    $event->getRequest()->attributes->set('project',$project);

    // Give all twig templates access to project
    $twig = $this->container->get('twig');
    $twig->addGlobal('project',$project);
}
# services.yml
cerad_core__model__event_listener:
    class:  '%cerad_core__model__event_listener__class%'
    calls:
        - [setContainer, ['@service_container']]
    tags:
        - { name: kernel.event_subscriber }

If it's a user value like you said you can get app.user.XXX on every twig template you need without processing nothing ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top