Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation, highlight current page

Tags:

twig

symfony

I've got a parent layout and derived from that child sites.

The parent layout has a navigation, each navigation point represents one child site.

How do i highlight in the parent layout the currently viewed child site? How shall the if look like?

like image 878
trampi Avatar asked Feb 29 '12 09:02

trampi


2 Answers

I know it's an old thread, but still you find it among top 3 on Google, so here's a little update to it.

You can take different aproaches on creating a navigation with a "highlighting class" with Symfony.

1. Check route
As @Sebastian J suggested, you can check with an if else for the route.

<li{% if app.request.get('_route') == 'foo_products_overview' %} class="active"{% endif %}>

Problem: It's not officially supported, as @netmikey pointed out: How to get current route in Symfony 2?

1.1. Check route array
I actually use this on my projects, with one adjustment. I use an in array function, to be able to give more than one route.

<li{% if app.request.attributes.get('_route') in [
    'foo_products_overview',
    'foo_products_detail',
    'foo_products_bar'
] %} class="active"{% endif %}>

1.2. Check route start with ...
A third approach would be what @bernland has suggested. Let's asume we want to match all routes starting with foo_products and we'd like to apply this by magic.

<li{% if app.request.attributes.get( '_route' ) starts with 'foo_products' %} class="active"{% endif %}>

As I said, I use this and haven't had an issue, yet.

2. Use a Bundle/function I'm sure there are other Bundles out there, but I'd recomend you this to create your navigation: https://github.com/KnpLabs/KnpMenuBundle

3. Use a macro edit July 2015
My new favorite is to use a macro like

{% macro menuItem(name, url, subitems) %}
    {% spaceless %}
        {% set subitems = subitems|default({}) %}
        {% set currentUrl = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %}
        {% set isActive = currentUrl == url %}

        {% for name, suburl in subitems %}
            {% set isActive = not isActive and currentUrl == suburl %}
        {% endfor %}

        <li{% if isActive %} class="is-active"{% endif %}>
            <a href="{{ url }}"{% if subitems|length > 0 %} class="has-sub-menu"{% endif %}>{{ name|trans() }}</a>
            {% if subitems|length > 0 %}
                <ul class="main-sub-menu">
                    {% for name, url in subitems %}
                        {{ _self.menuItem(name, url) }}
                    {% endfor %}
                </ul>
            {% endif %}
        </li>
    {% endspaceless %}
{% endmacro %}

just add this code somewhere in your twig file (not in a {% block %} thing!)
You then can call it like this for a single item:

{{ _self.menuItem('FooBar', path('foo_foobar')) }}

or for a item with subitems:

{{ _self.menuItem('FooBar', path('foo_foobar'), {
    'Foo': path('foo_baz', {slug: 'foo'}),
    "Bar": path('foo_baz', {slug: 'bar'}),
}) }}

Beautiful, isn't it?

like image 170
wawa Avatar answered Sep 22 '22 12:09

wawa


Probably not the best option but here is some simple approach for Symfony2 based upon the routes name:

<ul class="nav">
  <li{% if app.request.get('_route') == '_adminIndex' %} class="active"{% endif %}>
    <a href="{{ path('_adminIndex') }}">Admin Home</a>
  </li>
</ul>
like image 31
Sebastian J Avatar answered Sep 21 '22 12:09

Sebastian J