Damaged Organic
Damaged Organic

Reputation: 8467

Sharing data between embedded controllers in Symfony2

I'm new to Symfony2 and after several tutorials decided to migrate on of my projects to this framework.

In my project I've got few modules that got different templates but share the same data. For example, menu: menu items are lifted from database and used by standart website menu and also by footer menu. I've read that the best practice is to create controller for such task, and embed it straight into main layout, like this:

//Controller
class PageComponentController extends Controller
{
    public function menuAction()
    {
        //get menu items from database...
        $menu_items = ...

        return $this->render('MyProjectBundle:PageComponent:menu.html.twig', [
            'menu_items' => $menu_items
        ]);
    }
}

//Template
{% block body %}
    {% render controller('MyProjectBundle:PageComponent:menu', { 'current_page': current_page }) %}
{% endblock %}

But then I need to pass those $menu_items in footer as well, and render footer from the footerAction() in PageComponentController.

I know that there are ways to do it, but what is the best way to share such mutual data between different embedded controllers in Symfony2?

UPDATE (solution based on oligan's answer):

Service container scope is both accessible from main controller (responsible for page rendering) and from embedded controllers. So it would be pretty clean and dry to write service class with getMenu() method that fetches data from DB, and outputMenu() method that returns existing data. Then, service data is set from main controller and could be retrieved from service container in embedded controllers.

Upvotes: 0

Views: 155

Answers (1)

oligan
oligan

Reputation: 634

I think the wisest is to use a service which would retrieve all the data you want http://symfony.com/doc/current/book/service_container.html (it's more or less like a controller but accessible everywhere )

To give you an idea what it is

class MenuService
{

  public function getMyMenu()
  {
    ... your code to get the menu
  }
}

Then declare it in services.yml in your bundle

services:
    getMenuService:
        class: ..\...\...\MenuService

And then just use it in any controller by doing so

$menu = $this->container->get('getMenuService');



if you have to use template heritage then you can still access to an object in the parent template by doing

{% extends "...Bundle..:myMenu.html.twig" %}

{% set menu = myMenuTwigvar %}

and then myMenu for example menu.button1

Upvotes: 2

Related Questions