Sébastien
Sébastien

Reputation: 5453

service method as twig global variable

In my symfony2 application, I have a getPorfolioUser method which return a specific user variable.

I am looking forward to be able to call

{% if portfolio_user %}

in twig. I did not understand how I could set this as a global variable as from the documentation I am under the impression I can only set fixed elements or services but not services' methods.

Am I obliged to write an extension or a helper for that ? What the simpler way of doing this ?

Thanks!

Upvotes: 12

Views: 10848

Answers (4)

Craig Wayne
Craig Wayne

Reputation: 5060

I was having some difficult with this as well and finally solved it by doing the following:

 

  1. Setup your bundle (e.g: MyVendor/MyBundle)

    $ app/console generate:bundle
    

 

  1. In your bundle directory, create MyService.php class file in the DependencyInjection folder.

 

  1. In this class file, create the function

    public function getExample(){
        return "it works!!!";
    }
    

 

  1. In app/config/services.yml create a new service like so:

    myvendor.mybundle.myservice
          class: MyVendor\MyBundle\DependencyInjection\MyService
    

 

  1. In app/config/config.yml under the twig configuration section

    twig:
        globals:
            mystuff: '@myvendor.mybundle.myservice'
    

 

  1. Then in your twig templates you can reference the variable like so:

     {{ mystuff.example }}
    

 

DISCLAIMER

this is just how I got it to work....

hope this helps.

Upvotes: -1

Matteo
Matteo

Reputation: 39380

You can define your custom service as twig globals variable as follow:

in the config.yml

# Twig Configuration
twig:
    debug:            "%kernel.debug%"
    strict_variables: "%kernel.debug%"
    globals:
        myGlobaService: "@acme.demo_portfolio_service"  #The id of your service

Use it a Twig file

{% if myGlobaService.portfolio_user() %}

Hope this help

Upvotes: 15

BENARD Patrick
BENARD Patrick

Reputation: 30975

When you look here : http://symfony.com/doc/current/reference/twig_reference.html#app

You can read this :

The app variable is available everywhere and gives access to many commonly needed objects and values. It is an instance of GlobalVariables.

GlobalVariables is Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables

I never do it but I think one way is to overide this class in order to put your special needs in.

Upvotes: 1

Cerad
Cerad

Reputation: 48865

One approach is use a CONTROLLER event listener. I like to use CONTROLLER instead of REQUEST because it ensures that all the regular request listeners have done their thing already.

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ProjectEventListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
    return array
    (
        KernelEvents::CONTROLLER => array(
            array('onControllerProject'),
        ),
    );
}
private $twig;
public function __construct($twig)
{
    $this->twig = $twig;
}
public function onControllerProject(FilterControllerEvent $event)
{
    // Generate your data
    $project = ...;

    // Twig global
    $this->twig->addGlobal('project',$project);    
}

# services.yml
cerad_project__project_event_listener:
    class: ...\ProjectEventListener
    tags:
        - { name: kernel.event_subscriber }
    arguments:
        - '@twig'

Listeners are documented here: http://symfony.com/doc/current/cookbook/service_container/event_listener.html

Another approach would be to avoid the twig global altogether and just make a twig extension call. http://symfony.com/doc/current/cookbook/templating/twig_extension.html

Either way works well.

Upvotes: 8

Related Questions