Peter Hoffmann

Highlight the Active Menu Item with Twig and Silex

Twig snippet to define a reusable navigation bar. The active page is set in the inherited template.

This post is from 2012. Some of the content may be outdated.

Using the twig template inheritance it is easy to add a reusable navigation bar with a highlighted active navigation item in all your pages. The idea is based on the Jinja2 Highlighting Active Menu Items Pattern.

The basic template layout.html defines the navigation bar with each an identifier and a link name.

{% set navigation_bar = [['index', 'Home Page'], ['blog', 'Blog'], ['archive', 'Archive']] %}
{% set active_page = active_page|default('index') %}
<html>
<head><title>Test Page</title><head>
<body>
{% block navigation %}
<ul id="navigation">
{% for item in navigation_bar %}
<li{% if item[0] == active_page %} class="active"{% endif%}>
<a href="{{ app.url_generator.generate(item[0]) }}">{{item[1]}}</a></li>
{% endfor %}
</ul>
{% endblock %}
</body>
</html>

The pattern uses the Url Generator Service Provider. The identifiers of each item have to be bound to a route in your application.

In an inherited template you can redefine the active item. E.g in the template blog.twig the active page is set to the blog.

{% extends "layout.twig" %}
{% set active_page = "blog" %}

If you reuse a template in different Controllers set the active_page when you return a response with render-template.

<?php

$app = new Silex\Application();
$app->register(new TwigServiceProvider(), array(
    'twig.path' => __DIR__.'/templates'
));
$app->register(new Silex\Provider\UrlGeneratorServiceProvider());

$app->get('/', function() use ($app){
    return $app['twig']->render('layout.twig');
})->bind('index');

$app->get('/blog', function() use ($app){
    return $app['twig']->render('blog.twig');
})->bind('blog');

$app->get('/archive', function() use ($app){
    return $app['twig']->render('blog.twig', array("active_page" => "archive"));
})->bind('archive');

return $app;