How to design current route in our link's navbar with TWIG ? This is exactly what we are going to see 😀
Our navbar and routes
Let's say we have a blog which display pictures and videos. Our navbar would have 4 links :
- Home
- Pictures
- Vidéos
- Contact
About the routes, we just want the giving name, so :
- Home => "app_home"
- Pictures => "app_picture"
- Vidéos => "app_video"
- Contact => "app_contact"
Right, we have all the information, now have a look on our twig template :
<nav>
<ul>
<li>
<a href="{{ path('app_home') }}">Home</a>
</li>
<li>
<a href="{{ path('app_picture') }}">Pictures</a>
</li>
<li>
<a href="{{ path('app_video') }}">Videos</a>
</li>
<li>
<a href="{{ path('app_contact') }}">Contact</a>
</li>
</ul>
<nav>
Here if we click on a link, we would be redirect to the route but nothing (except the URL) will indicate us that we are on the right route. So let's do some UX.
Twig function
We are going to right a function in twig. We need to install a package :
composer require twig/extensions
Name it as you want and go in the file. Erase all about the filter (except if you want to go further and try some) and go in the public function getFunctions.
Here we are going to create a function for twig named "actual_route" from the current fuction 'getActualRoute'
public function getFunctions(): array
{
return [
new TwigFunction('actual_route', [$this, 'getActualRoute']),
];
}
The getActualRoute will take 2 strings parameters and return active if the current route is equal to the actual :
public function getActualRoute(string $value, string $route): string
{
return $value === $route ? 'active' : '';
}
Back in the navBar
Last step, we are going to modify our template. We want to put an 'active' class to the current route. First let set a route's variable which are going to contain the name of the actual route. In your twig try to dump this : app.request.attributes.get('_route')
. As you can see, you've got the actual route in string. Now let's do it :
{% set route = app.request.attributes.get('_route') %}
<nav>
<ul>
<li>
<a href="{{ path('app_home') }}">Home</a>
</li>
<li>
<a href="{{ path('app_picture') }}">Pictures</a>
</li>
<li>
<a href="{{ path('app_video') }}">Videos</a>
</li>
<li>
<a href="{{ path('app_contact') }}">Contact</a>
</li>
</ul>
<nav>
Then for each link write a class, with our function :
<a href="{{ path('app_home') }}" class="{{ actual_route('app_home',route) }}">Home</a>
So it means, if the 'app_home' === route ( what we just set) then, it will be an active class.
Just try it and inspect your element. Now you just need to write some CSS to customize this. For example with SCSS :
a{
color: black;
transition:0.3s ease-in-out;
&.active{
color:red;
}
}
Conclusion
I hope it helped you and if you have any questions or improvements, just write it 😊
Cheers !
Top comments (3)
Good tip Mickaël.
I think
active_route
is a better function name ;)Function's name is always hard to find. Thanks for your tips
You can even go further injecting the RequestStack service to retrieve the current request and the current route 😉