php-lion / navigation
PhpLion Symfony Navigation
Installs: 8
Dependents: 3
Suggesters: 0
Security: 0
Stars: 0
Forks: 0
Type:symfony-bundle
pkg:composer/php-lion/navigation
Requires
- php: >=8.3
- composer/semver: ^3.0
- symfony/deprecation-contracts: ^2.1|^3
- symfony/filesystem: ^7.1
- symfony/http-client: ^6.4|^7.0
- symfony/webapp-pack: ^1.3
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^9.6
- symfony/asset: ^6.4|^7.0
- symfony/browser-kit: ^6.4|^7.0
- symfony/console: ^6.4|^7.0
- symfony/event-dispatcher-contracts: ^3.0
- symfony/finder: ^6.4|^7.0
- symfony/framework-bundle: ^6.4|^7.0
- symfony/http-foundation: ^6.4|^7.0
- symfony/http-kernel: ^6.4|^7.0
- symfony/web-link: ^6.4|^7.0
Conflicts
- symfony/framework-bundle: <6.4
README
A Symfony bundle for managing navigation structures using PHP attributes. This bundle provides a declarative way to define navigation menus directly in your controllers.
Description
The PhpLion Navigation Bundle enables developers to define navigation menus using modern PHP 8 attributes, keeping navigation logic close to controller routes. It supports hierarchical menus, navigation groups, automatic active state detection, and flexible rendering.
Features
- PHP 8 Attributes - Declarative navigation definition using attributes
- Hierarchical Navigation - Multi-level menu structures with parent-child relationships
- Navigation Groups - Organize menus into groups (frontend, backend, admin, etc.)
- Auto-Detection - Automatically mark current/active navigation items
- Priority System - Control menu item order with configurable priorities
- Flexible Rendering - Full control over navigation rendering in Twig
- Type-Safe - Leverages PHP's type system for better IDE support
Requirements
- PHP >= 8.3
- Symfony >= 6.4 or 7.0+
- Composer
Installation
Use Composer to install the package:
composer require php-lion/navigation
Usage
// src/Controller/IndexController.php
namespace App\Controller;
use PhpLion\NavigationBundle\Attribute\Navigation;
use PhpLion\NavigationBundle\Attribute\NavigationGroup;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Attribute\Route;
#[NavigationGroup(name: '_default')]
final class IndexController extends AbstractController
{
    #[Route('/index', name: 'app_index')]
    #[Template('index.html.twig')]
    #[Navigation(path: 'Home')]
    public function index(): array
    {
        return [
            'title' => 'Home',
        ];
    }
{% block navigation %}
    {% for item in  navigation.current %}
        {% if item.children is empty %}
            <a class="nav-link" href="{{ path(item.name) }}">{{ item.label }}</a></li>              
        {% else %}
            {# Do stuff with nested nodes. This nodes will have the same structure as the parent #}
        {% endif %}
    {% endfor %}
{% endblock %}
Keep in mind: The navigation var will be injected to the twig template by ViewEvent. This means your controller hast to returns an array as response. A Symfony\Component\HttpFoundation\Response does not trigger the ViewEvent.
[
    'tree' => [
        '_default' => [
        
        ]    
        'my_navigation_group' => [
            0 => [
                'label' => 'Home',
                'name' => 'app_index',
                'tags' => [],
                'children' => [], /** nested navigation items/nodes */
                'selected' => true, /** is set true if named controller action was called */
                'priority' => 1000, /** order of the items (higher priority items appear first) */
                'link' => true,
                'hide' => [],
                'style' => []
            ]
        ]    
    ],
    'groups' => [
        0 => '_default',
        1 => 'my_navigation_group',
    ],
    'currentGroup' => 'my_navigation_group', /** the navigation group of the currently called controller */
    'currentName' => '' /** name of the current called controller action */
    'current' => [] /** content of tree item named in currentGroup */
]
NavigationGroups
You can use NavigationGroups to create different navigation collections for example for backend and frontend use. If NavigationGroup is not set the NavigationGroup ist set to __default_.
Navigation
Navigation implements the tree in the navigation. You have different options you can use. The only necessary one is the path attribute.
Path
You can separate the level of the tree by a '|' delimiter. It is possible to use the attribute multiple times to place the item on different points in you navigation.
Root path in navigation:
    #[Navigation(path: 'Home')]
    #[Navigation(path: 'Contact')]
 ├── Home  
 └── Contact
Nested nodes in navigation:
    #[Navigation(path: 'Home|Products')]
    #[Navigation(path: 'Home|Portfolio')]
    #[Navigation(path: 'Contact')]
 ├── Home  
 │   ├── Products                      
 │   └── Portfolio  
 └── Contact
Link
You can force the navigation item has a link or not.
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
License
MIT License - see LICENSE file for details
Support
For issues and questions:
- Homepage: https://www.php-lion.de
- Email: info@php-lion.de
Credits
Developed by Denis Juroszek (PhpLion)