Navigation, highlight current page
Asked Answered
P

8

23

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?

Pagoda answered 29/2, 2012 at 9:4 Comment(1)
Possible duplicate of How to get current route in Symfony 2?Tegular
A
17

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>
Arbalest answered 6/9, 2012 at 15:46 Comment(1)
Relying on request.get('_route') isn't officially supported and doesn't always give you the expected result. See this other question: #7097046Mueller
T
39

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?

Taam answered 25/11, 2014 at 18:54 Comment(0)
A
17

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>
Arbalest answered 6/9, 2012 at 15:46 Comment(1)
Relying on request.get('_route') isn't officially supported and doesn't always give you the expected result. See this other question: #7097046Mueller
U
5

Here's what I used (for Symfony 5):

<li class="nav-item{% if (app.request.pathInfo == path('frontend_index')) %} active{% endif %}">
Urbanize answered 12/6, 2020 at 17:4 Comment(0)
O
4

First set a variable in Template its better redable.

{% set page = app.request.get('_route') %}
<li class="nav-item">
            <a class="nav-link {% if page == 'welcome' %}active{% endif %}" href="{{ path('welcome') }}">Home <span class="sr-only">(current)</span></a>
        </li>
Ornstead answered 18/8, 2019 at 18:12 Comment(0)
K
2

Here's what I did:

<a href='{{ path( 'products' ) }}'{% if app.request.attributes.get( '_route' ) starts with 'products' %} class='active'{% endif %}>Products</a>
<ul>
    <li><a href='{{ path( 'products_product1' ) }}'{% if app.request.attributes.get( '_route' ) == 'products_product1' %} class='active'{% endif %}>Product 1</a></li>
    <li><a href='{{ path( 'products_product2' ) }}'{% if app.request.attributes.get( '_route' ) == 'products_product2' %} class='active'{% endif %}>Product 2</a></li>
</ul>
Kyongkyoto answered 16/3, 2014 at 14:30 Comment(0)
T
1

in Silex, I do it like this:

$app->before(function ($request) use ($app) {
    $app['twig']->addGlobal('active', $request->get("_route"));
});

Then in my Twig template file, {{ active }} equals to the current route.

Simple and easy enough!

Tegular answered 10/11, 2016 at 20:32 Comment(0)
S
-1

Easy peasy: PHP 8.1.26, Symfony 6.4.1, Twig 3.0

// add a class to your css file, e.g:
.myNavbar-li {
    border-bottom: border-style border-width border-color;
}

// in your twig template or your xxx.html.twig file
{% if (app.request.pathInfo == path('route_name')) %}
    <li class="nav-item active myNavbar-li">
{% endif %}
Selfabnegation answered 13/12, 2023 at 10:46 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Holloway
M
-6

Create a css class for the highlighted menu item and to each navigation item bind an onClick JS event and when that event is triggered just add the class to the current navigation item and remove it from the others and it should highlight the selected site in the navigation.

Megaera answered 29/2, 2012 at 9:11 Comment(5)
The problem with that attempt is that it loads a new page. It's not ajax, you know?Pagoda
If you can use PHP or JS to determine the url (assuming that the pages have different urls) then you can add the needed highlight class to the appropriate navigation item by the url value.Megaera
Yeah, thats what i want to do. The project is build upon a framework called symfony, and i want to know whats the symfony way of doing this ;)Pagoda
use the framework only when it's really needed and it makes your life easier for the other cases you can use regular PHP or JS. But I guess you can always check the documentation for the framework and see how you get the url or the current file that you are working with.Megaera
I cannot not second your recommendation how to use this framework "only when it's really needed". Instead, make use of the framework of your choice as often as you can!Ruralize

© 2022 - 2025 — McMap. All rights reserved.