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

1.0.0 2025-10-28 07:25 UTC

This package is not auto-updated.

Last update: 2025-10-28 07:33:16 UTC


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:

Credits

Developed by Denis Juroszek (PhpLion)