Framework agnostic PHP package for marking navigation items active.

Overview

Ekko

Framework agnostic PHP package for marking navigation items active.

Become a Patron

Features

  • Framework agnostic.
  • Can be modified for any custom application and UI.
  • Currently supported frameworks: Laravel (PRs are welcome!).
  • Global helper functions disabled by default.
  • Supports default output value.
  • Backward compatible.
  • Fully tested using table driven testing (data providers in PHPUnit).

Installation

From the command line:

composer require laravelista/ekko

By default Ekko is initialized with these sensible defaults:

  • the default output value is active.
  • it uses GenericUrlProvider ($_SERVER['REQUEST_URI']).
  • global helper functions are disabled.

Laravel

The only dependency for this package is PHP ^8.0, meaning that you can possibly install it on any Laravel version that supports PHP 8 (I think that for now this is only Laravel 8). The service provider is always going to follow the latest Laravel release and try to be as backward compatible as possible.

Laravel 8 will use the auto-discovery function to register the ServiceProvider and the Facade.

If you are not using auto-discovery, you will need to include the service provider and facade in config/app.php:

'providers' => [
    ...,
    Laravelista\Ekko\Frameworks\Laravel\ServiceProvider::class
];

And add a facade alias to the same file at the bottom:

'aliases' => [
    ...,
    'Ekko' => Laravelista\Ekko\Frameworks\Laravel\Facade::class
];

Overview

To mark a menu item active in Bootstrap, you need to add a active CSS class to the <li> tag:

<ul class="nav navbar-nav">
    <li class="active"><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
</ul>

You could do it manually with Laravel, but you will end up with a sausage:

<ul class="nav navbar-nav">
    <li class="@if(URL::current() == URL::to('/')) active @endif"><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
</ul>

With Ekko your code could look like this:

<ul class="nav navbar-nav">
    <li class="{{ Ekko::isActive('/') }}"><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
</ul>

or like this:

<ul class="nav navbar-nav">
    <li class="{{ Ekko::isActiveRoute('home') }}"><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
</ul>

or this:

<ul class="nav navbar-nav">
    <li class="{{ $ekko->isActive('/') }}"><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
</ul>

Default output value

What if you are not using Bootstrap, but some other framework or a custom design? Instead of returning active CSS class, you can make Ekko return anything you want.

<ul class="nav navbar-nav">
    <li class="{{ Ekko::isActive('/', 'highlight') }}"><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
</ul>

You can alse set the default output value if you don't want to type it everytime:

$ekko = new Ekko;
$ekko->setDefaultValue('highlight');
return $ekko->isActive('/');

or in Laravel you can set the default output value in the config config/ekko.php file:

<?php

return [
    'default_output' => 'highlight'
];

To publish the config for Ekko use this in Laravel:

php artisan vendor:publish --provider="Laravelista\Ekko\Frameworks\Laravel\ServiceProvider"

Using boolean true or false is convenient if you need to display some content depending on which page you are in your layout view:

@if(Ekko::isActive('/about', true))
    <p>Something that is only visible on the `about` page.</p>
@endif

Global helper functions

Global helper functions are disabled by default. To enable them use Ekko::enableGlobalHelpers(); or $ekko->enableGlobalHelpers().

In Laravel add this code to your app/Providers/AppServiceProvider.php file in register method:

\Ekko::enableGlobalHelpers();

Usage

When used outside a framework, this package has only one main method of interest called isActive. The function accepts an input which can be a string or an array of strings, and an output which can be anything. The default output is active.

<li class="{{ $ekko->isActive('/') }}"><a href="/">Home</a></li>
<li class="{{ $ekko->isActive(['/', '/home]) }}"><a href="/">Home</a></li>
<li class="{{ $ekko->isActive(['/', '/home, '*home*']) }}"><a href="/">Home</a></li>
<li class="{{ $ekko->isActive('/home*') }}"><a href="/">Home</a></li>
<li class="{{ $ekko->isActive('/home*feature=slideshow*') }}"><a href="/">Home</a></li>
<li class="{{ $ekko->isActive('/index.php?page=*') }}"><a href="/">Home</a></li>

It supports strings, arrays, wildcards and query parameters.

Laravel usage

Use the facade Ekko::, resolve(Ekko::class) or app(Ekko::class) to obtain the Laravel bootstraped instance.

Laravel comes with few special methods for named routes and other helper methods. Also, there is a lot of backward compatibility here for v1 of this package.

Methods

Ekko::isActive($input, $output = null) This calls the main Ekko method isActive. Described above.

Ekko::isActiveRoute($input, $output = null) For named routes. Supports arrays and wildcards.

Ekko::areActiveRoutes(array $input, $output = null) For arrays of named routes. Supports wildcards. Backward compatibility. Use isActiveRoute and pass it the same array.

Ekko::isActiveURL($input, $output = null) The same as Ekko::isActive. Backward compatibility. Use Ekko::isActive and pass it the same input.

Ekko::areActiveURLs(array $input, $output = null) The same as Ekko::isActiveURL, but accepts only the array of Urls. Backward compatibility. Use Ekko::isActive and pass it the same array.

Ekko::isActiveMatch($input, $output = null) The same as Ekko::isActive. This method encloses the input with wildcard *. Supports string, array and wildcards as input. Backward compatibility. Use Ekko::isActive and pass it the same input, but with wildcard * at the desired place.

Ekko::areActiveMatches(array $input, $output = null) The same as Ekko::isActiveMatch, but accepts only the array of strings. Backward compatibility. Use Ekko::isActive and pass it the same array.

Development

# Install dependencies
composer install

# Run tests
vendor/bin/phpunit

# Run Psalm
vendor/bin/psalm

# Format code (php-cs-fixer)
vendor/bin/php-cs-fixer

Credits

Many thanks to:

Sponsors & Backers

I would like to extend my thanks to the following sponsors & backers for funding my open-source journey. If you are interested in becoming a sponsor or backer, please visit the Backers page.

Contributing

Thank you for considering contributing to Ekko! The contribution guide can be found Here.

Code of Conduct

In order to ensure that the open-source community is welcoming to all, please review and abide by the Code of Conduct.

License

Ekko is open-source software licensed under the MIT license.

Comments
  • Support route wildcards?

    Support route wildcards?

    Resource model routes have a bunch of predefined route names that follow a pattern. For example, to administer a user, you may define the user resource route like this:

    Route::resource('users', 'UserController');
    

    That generates the routes users.index, users.show, users.create etc.

    Instead of having to list all these routes in an array, it would be great to be able to use a wildcard. a simple globbling approach would be work well, without the overhead of REs:

    class="{{ Ekko::isActiveRoute('users.*') }}"
    

    Maybe this is already supported in some way?

    opened by judgej 10
  • BadMethodCallException

    BadMethodCallException

    After adding to composer.json file and doing composer update, I get this when the command of php artisan clear-compiled gets called.

    [2015-05-22 15:14:01] local.ERROR: exception 'BadMethodCallException' with message 'Call to undefined method [package]' in /Users/iolson/Projects/laravel-project/vendor/compiled.php:4476
    Stack trace:
    #0 /Users/iolson/Projects/laravel-project/vendor/laravelista/ekko/src/Laravelista/Ekko/EkkoServiceProvider.php(21): Illuminate\Support\ServiceProvider->__call('package', Array)
    #1 /Users/iolson/Projects/laravel-project/vendor/laravelista/ekko/src/Laravelista/Ekko/EkkoServiceProvider.php(21): Laravelista\Ekko\EkkoServiceProvider->package('laravelista/ekk...')
    #2 [internal function]: Laravelista\Ekko\EkkoServiceProvider->boot()
    #3 /Users/iolson/Projects/laravel-project/vendor/compiled.php(925): call_user_func_array(Array, Array)
    #4 /Users/iolson/Projects/laravel-project/vendor/compiled.php(1526): Illuminate\Container\Container->call(Array)
    #5 /Users/iolson/Projects/laravel-project/vendor/compiled.php(1518): Illuminate\Foundation\Application->bootProvider(Object(Laravelista\Ekko\EkkoServiceProvider))
    #6 [internal function]: Illuminate\Foundation\Application->Illuminate\Foundation\{closure}(Object(Laravelista\Ekko\EkkoServiceProvider), 26)
    #7 /Users/iolson/Projects/laravel-project/vendor/compiled.php(1519): array_walk(Array, Object(Closure))
    #8 /Users/iolson/Projects/laravel-project/vendor/compiled.php(1837): Illuminate\Foundation\Application->boot()
    #9 /Users/iolson/Projects/laravel-project/vendor/compiled.php(1314): Illuminate\Foundation\Bootstrap\BootProviders->bootstrap(Object(Illuminate\Foundation\Application))
    #10 /Users/iolson/Projects/laravel-project/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(195): Illuminate\Foundation\Application->bootstrapWith(Array)
    #11 /Users/iolson/Projects/laravel-project/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(92): Illuminate\Foundation\Console\Kernel->bootstrap()
    #12 /Users/iolson/Projects/laravel-project/artisan(36): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
    #13 {main}  
    
    
    opened by iolson 5
  • Laravel 5.5 auto-discovery

    Laravel 5.5 auto-discovery

    This adds Laravel 5.5 auto-discovery

    Also changed:

    • Changed Readme to include comment about Laravel 5.5
    • Remove HHVM from Travis
    • Added php7 + php7.1 to Travis
    opened by it-can 2
  • helpers.php

    helpers.php

    Hi. There is a bug on file: helpers.php line 53:

    Replace: return app(Ekko::class)->areActiveRoutes($string, $output); with return app(Ekko::class)->areActiveRoutes($routeNames, $output);

    opened by elnurxf 2
  • Implement helpers

    Implement helpers

    Hi,

    I've added a helpers file for this. I dislike using Facades/Static methods within blade files, so using helpers solve this issue.

    Thought I'd offer to make a PR for this so that people who also dislike facades can use it too, but I would also understand if you do not like this PR.

    Thanks.

    opened by Jono20201 2
  • Wildcard on nested routes

    Wildcard on nested routes

    Wildcard feature does not work on nested routes.

    route = cars.makes.show

    Using either of the following fails.

    areActiveRoutes(['cars.*', ... ]) 
    areActiveRoutes(['cars.makes.*', ... ]) 
    
    opened by olds463 2
  • how to use it with ARCANEDEV/Localization

    how to use it with ARCANEDEV/Localization

    Ekko works great but now im using ARCANEDEV/Localization this works if i dont use Localization

    <li class="{{ Ekko::isActiveURL('dashboard') }}">

    now my urls are changed based on a language /en/dashboard /nl/dashboard etc and <li class="{{ Ekko::isActiveURL('dashboard') }}"> is not working anymore

    opened by ghost 2
  • Ekko::areActiveMatch and helper

    Ekko::areActiveMatch and helper

    if (!function_exists('are_active_match')) {
        /**
         * Detects if the given string array is found in the current URL.
         *
         * @param array  $matches
         * @param string $output
         *
         * @return string
         */
        function are_active_match($matches, $output = "active")
        {
            foreach($matches as $match){
                if(isActiveMatch($match)){
                    return $output;
                }
            }
    
            return null;
        }
    }
    
    enhancement 
    opened by Turboveja 1
  • Support route actions

    Support route actions

    Laravel provides route lookup by URL, name or action, but only the two first are currently supported by Ekko. Would be useful if Ekko could also support action based route matching:

    • Matching a single route action: isActiveAction('controllerName@action')
    • With wildcard: isActiveAction('controllerName@*')
    opened by danmichaelo 1
  • Support URL wildcards

    Support URL wildcards

    Would be useful to be able to do isActiveURL('/events/*'). The isActiveMatch method is too limiting, since you might not want to match e.g. users/1/events/123.

    I could prepare a PR for this, but before I do so I'd like to know if it's likely that it would be accepted?

    opened by danmichaelo 1
  • Wildcard nested route detection not going deep enough

    Wildcard nested route detection not going deep enough

    If you have route frontend.users.show.stats using Ekko isActiveRoute('frontend.users.*) does not return active, but it returns active for route frontend.users.show.

    Need to locate the problem and fix it.

    bug 
    opened by mabasic 1
Releases(4.0.1)
Owner
Laravelista
Specialized in building Web & Mobile Apps
Laravelista
PHP phonebook with map (Active Directory, LDAP -> MySQL, PHP)

LDAP phonebook ???? ???? Development ветка Вопросы предпочтительнее задавать в Issues, а не по почте Корпоративный телефонный справочник с отображение

null 47 Nov 30, 2022
Active State Helper for Laravel Blade

laravel-activehelper Active State Helper for Laravel Blade Lightweight and simple Introduction Basically we do like this. <li class="sidebar {{ Reques

Ahmad Irsyadul Ibad 4 Sep 25, 2022
Add Active Campaign API v3 to your Laravel application.

Laravel ActiveCampaign (WIP) This package provides a simple interface to the ActiveCampaign API v3. Currently the packages only supports the endpoints

Label84 10 Nov 28, 2022
Navigator is a package to create headless navigation menus for use in Laravel applications

Navigator Navigator is a package to create headless navigation menus for use in Laravel applications: // In a Service Provider Nav::define(fn ($user)

Sam Rowden 36 Oct 30, 2022
Build structured navigation menus in Filament.

Build structured navigation menus in Filament. This plugin for Filament provides a Navigation resource that allows to build structural navigation menu

Ryan Chandler 61 Dec 30, 2022
Build structured navigation menus in Filament.

Build structured navigation menus in Filament. This plugin for Filament provides a Navigation resource that allows to build structural navigation menu

HappyToDev 0 Jun 29, 2022
Collection of agnostic PHP Functions and helpers with zero dependencies to use as foundation in packages and other project

Collection of agnostic PHP Functions and helpers This package provides a lot of very usefull agnostic helpers to use as foundation in packages and oth

padosoft 54 Sep 21, 2022
This tool gives you the ability to set the default collapse state for Nova 4.0 menu items.

Nova Menu Collapsed This tool gives you the ability to set the default collapse state for Nova 4.0 menu items. Requirements php: >=8.0 laravel/nova: ^

Artem Stepanenko 10 Nov 17, 2022
Plugin for Filament Admin that adds a dropdown menu to the header to quickly create new items.

Filament Quick Create Plugin for Filament Admin that adds a dropdown menu to the header to quickly create new items from any page. Installation Instal

Adam Weston 45 Dec 27, 2022
A simple PHP package to show SweetAlerts with the Laravel Framework

Easy Sweet Alert Messages for Laravel Installation Require the package using Composer. composer require uxweb/sweet-alert If using laravel < 5.5 inclu

Uziel Bueno 824 Jan 7, 2023
Framework - 🙃 Phony. Real-like Fake Data Generation Framework

?? Framework This repository contains the ?? Phony Framework. ?? Start generating fake data with ?? Phony Framework, visit the main Phony Repository.

Phonyland 5 Oct 31, 2022
Stapler-based file upload package for the Laravel framework.

laravel-stapler Laravel-Stapler is a Stapler-based file upload package for the Laravel framework. It provides a full set of Laravel commands, a migrat

Code Sleeve 565 Dec 9, 2022
This package wraps up the standalone executable version of the Tailwind CSS framework for a Laravel application.

Tailwind CSS for Laravel Introduction This package wraps the standalone Tailwind CSS CLI tool. No Node.js required. Inspiration This package was inspi

Tony Messias 240 Nov 19, 2022
Stapler-based file upload package for the Laravel framework.

laravel-stapler Laravel-Stapler is a Stapler-based file upload package for the Laravel framework. It provides a full set of Laravel commands, a migrat

Code Sleeve 565 Dec 9, 2022
Joomla Framework Filter Package

The Filter Package Installation via Composer Add "joomla/filter": "~2.0.*@dev" to the require block in your composer.json and then run composer instal

Joomla! Framework 10 Dec 16, 2022
Jetstrap is a lightweight laravel 8 package that focuses on the VIEW side of Jetstream / Breeze package installed in your Laravel application

A Laravel 8 package to easily switch TailwindCSS resources generated by Laravel Jetstream and Breeze to Bootstrap 4.

null 686 Dec 28, 2022
This package provides extended support for our spatie/enum package in Laravel.

Laravel support for spatie/enum This package provides extended support for our spatie/enum package in Laravel. Installation You can install the packag

Spatie 264 Dec 23, 2022
A Laravel chat package. You can use this package to create a chat/messaging Laravel application.

Chat Create a Chat application for your multiple Models Table of Contents Click to expand Introduction Installation Usage Adding the ability to partic

Tinashe Musonza 931 Dec 24, 2022
GeoLocation-Package - This package helps you to know the current language of the user, the country from which he is browsing, the currency of his country, and also whether he is using it vpn

GeoLocation in PHP (API) ?? ?? ?? This package helps you to know a lot of information about the current user by his ip address ?? ?? ?? This package h

Abdullah Karam 4 Dec 8, 2022