Reputation: 8467
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
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