I am currently working on a project using symfony and got to a point where I wanted to add a contextual navigation menu. In other words, I wanted to have a menu that would show a list of pages, but not show the current page. After considering using slots, components, and component slots, I decided on a solution that I like. Read on to find out what it is.
The concept is that I created a component to handle displaying the navigation menu and included the component in the layout. All the component has to do is remove the current page from a list of pages that are retrieved from the global configuration file and display them as a list. To do this, I simply created a component – you can look here to find out how to do that in detail.
What it meant for me is that I created a module in my application called “navigation” (I made a folder called navigation in the modules folder) and then in the navigation/actions folder I created my components file: components.class.php. This is where the logic for your component goes. Then, I created a file (partial) called _navMenu.php in navigation/templates (we’ll get to why you call it that in a second) – this is the template that is displayed for the component.
The component logic
The logic for the component was as follows:
// apps/app_name/modules/navigation/actions/components.class.php
class navigationComponents extends sfComponents
{
/**
* Executes the building of the navigation menu.
*/
public function executeNavMenu()
{
$route = sfContext::getInstance()->getRouting()->getCurrentRouteName();
$this->pages = sfConfig::get('app_navpages');
unset($this->pages[$route]);
}
}
Basically, you’re components.class.php file is what includes all of the components – since mine only includes one component (navMenu) I probably could have just had the class inherit from sfComponent, but I think that this may come in handy later if I ever want to add another component. Now, the name of the method (executeNavMenu) is important – it determines what partial in the templates folder will be displayed (_navMenu.php – I told you we’d get to that) and it determines the name that will be used to include the component in the layout (or whatever view you may want to include the component in). My particular component is very simple – it gets the current route (as defined in routing.yml) and gets a list of my possible navigation menu pages as defined in my app.yml file:
// apps/app_name/config/app.yml - app_name is not the actual name...
all:
.array:
navpages:
homepage: { name: 'Home', route: '@homepage'}
person_index: { name: 'Manage Users', route: '@person_index' }
Once I have these two bits of information, I take the item for the current route out of the list with the line unset($this->pages[$route]). In my routing.yml file, my homepage route is defined as the following:
homepage:
url: /
param: { module: home, action: index }
So, for example, if I am at my homepage (http://example.com/), $route will contain the string ‘homepage’ and the item with the key ‘homepage’ will be removed from the list. Then, the variable $pages will be available in my template (partial) to be displayed.
The Component View
The code for the _navMenu.php partial is even more simple:
<div id="navigation">
<ul id="nav">
<?php foreach ($pages as $page): ?>
<li><?php echo link_to($page['name'], $page['route']); ?></li>
<?php endforeach; ?>
</ul>
</div>
In fact, it’s so simple that I don’t even think it needs explanation.
Including the Component in the Layout
Now all that remains is to include the component in the layout. That can be accomplished with this one-liner:
<?php include_component('navigation', 'navMenu'); ?>
The first argument is the module in which to find the component and the second argument is the name (which I mentioned earlier) of the component itself (the name of the method minus the execute on the front).
As you can see, all of the individual pieces are very simple, and when you put them all together, you get a nice, logical way of building a contextual navigation menu.

