Camron Cade

Artisan web development, mostly using Laravel.

.active classes in menus with Blade templates

In many of my projects, I have a layout blade file that each page extends. As part of the layout, there is a menu bar that has has a different style for a link if you are currently on that page. If you are using bootstrap or foundation, if you apply the css class .active to any <li> menu element, it changes the styling so it is obvious to the user what page they are on.

If you are using a template system and have your navigation partial in it's own file, like I do, you run into a problem of being unable to define the .active class to the correct element. Other solutions I've seen are either not super elegant, or accomplish too much (like managing the entire navigation bar for you). I needed something simple and lightweight that I could use in any of my projects. Here's what I came up with:

Create a class called Menu, I put mine behind a Helpers namespace:

<?php

namespace App\Helpers;

class Menu  
{
    public static function active($page)
    {
        $path = app('request')->path();

        if (str_contains($path, $page))
            return 'active';

        return '';
    }
}

Because I am using Lumen, I grabbed the Request using the IOC container, if you are using Laravel, you could just use the Request facade (or turn them on in Lumen!).

To make things a bit easier to use, I wanted to use an Alias so I could type Menu::active('home') rather than App\Helpers\Menu::active('home'). If you are using Laravel, you can go ahead and add this to the aliases array in your config/app.php file. Because I am using Lumen I don't have any built in config files.

After a little bit of digging, I found that Laravel defines aliases with the class_alias() function. Turns out this is a native PHP function. I threw this in AppServiceProvider:

    public function register()
    {
        class_alias('App\Helpers\Menu', 'Menu');
    }

If you are using Lumen, and are using the above function, make sure you uncomment the AppServiceProvider from the bootstrap/app.php file or that service provider will not be called.

Ok. Now that it's all setup, I can manage my navigation .active classes what I think is a fairly elegant way. Here's an example:

<ul class="nav">  
    <li class="nav-element {{ Menu::active('about') }}">
        <a href="about">About</a>
    </li>
    <li class="nav-element {{ Menu::active('contact') }}">
        <a href="contact">Contact</a>
    </li>
</ul>  

What do you guys think? Know of a better way to handle this? I'd love to have your feedback.