PHPackages                             owl-concept/menu-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. owl-concept/menu-bundle

ActiveSymfony-bundle[Utility &amp; Helpers](/categories/utility)

owl-concept/menu-bundle
=======================

Bundle Symfony pour la navigation dynamique — sidebar repliable, topbar, breadcrumbs, groupes accordion, badges, icônes, filtrage par rôles, détection active automatique.

00PHP

Since Mar 6Pushed 3mo agoCompare

[ Source](https://github.com/Jaecko/owl-menu-bundle)[ Packagist](https://packagist.org/packages/owl-concept/menu-bundle)[ RSS](/packages/owl-concept-menu-bundle/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (0)

OWL Menu Bundle
===============

[](#owl-menu-bundle)

[![PHP](https://camo.githubusercontent.com/3e41095f4ad1c6ad78f988bd1c107f87972f334143c3ba814165a03e1f43a63c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/3e41095f4ad1c6ad78f988bd1c107f87972f334143c3ba814165a03e1f43a63c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)[![Symfony](https://camo.githubusercontent.com/535d441eb72e052f085beb20c298850a907064fde523cdd591b21cbdf015cbac/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d362e34253230253743253230372e782d3030303030303f6c6f676f3d73796d666f6e79266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/535d441eb72e052f085beb20c298850a907064fde523cdd591b21cbdf015cbac/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d362e34253230253743253230372e782d3030303030303f6c6f676f3d73796d666f6e79266c6f676f436f6c6f723d7768697465)[![License](https://camo.githubusercontent.com/ed136854385794cebde5bfca44606d6ccb3c4de9dd7a2511481a27052d49562f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d70726f70726965746172792d626c7565)](https://camo.githubusercontent.com/ed136854385794cebde5bfca44606d6ccb3c4de9dd7a2511481a27052d49562f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d70726f70726965746172792d626c7565)

---

🇫🇷 Français
-----------

[](#-français)

Bundle Symfony pour la **navigation dynamique** — sidebar repliable, topbar horizontale, breadcrumbs auto-générés, groupes accordion, badges, icônes, filtrage par rôles, détection active automatique.

### Fonctionnalités

[](#fonctionnalités)

- **Sidebar repliable** — largeur 260px → 60px (icônes seules) avec transition fluide
- **Topbar horizontale** — alternative navbar avec dropdowns
- **Breadcrumbs auto-générés** — fil d'Ariane basé sur la hiérarchie du menu
- **Groupes accordion** — sous-menus pliables avec animation
- **Badges / Compteurs** — notifications visuelles sur les items
- **Icônes** — préfixe configurable (Bootstrap Icons, FontAwesome, etc.)
- **Filtrage par rôles** — masque les items selon les rôles Symfony
- **Détection active automatique** — highlight basé sur l'URL courante
- **Anti-flash** — script inline lit localStorage avant le premier rendu
- **Responsive** — burger menu sur mobile ≤ 768px
- **Variables CSS** — fonctionne avec ou sans `owl-theme-bundle`
- **Zéro dépendance JS** — vanilla JS, pattern IIFE

### Installation

[](#installation)

```
composer require owl-concept/menu-bundle
```

### Configuration

[](#configuration)

```
# config/packages/owl_menu.yaml
owl_menu:
    css_class_prefix: 'owl-menu'          # Préfixe BEM
    collapse_storage: 'localStorage'       # localStorage | settings
    active_detection: 'auto'               # auto | manual
    icon_prefix: 'bi bi-'                  # Préfixe CSS des icônes
```

### Utilisation

[](#utilisation)

#### Créer un menu dans un contrôleur ou service

[](#créer-un-menu-dans-un-contrôleur-ou-service)

```
use OwlConcept\MenuBundle\Builder\MenuBuilder;

class AppController extends AbstractController
{
    public function index(MenuBuilder $menuBuilder): Response
    {
        $menu = $menuBuilder->create('sidebar')
            ->addItem('dashboard', 'Tableau de bord', '/dashboard', [
                'icon' => 'house',
            ])
            ->addGroup('crm', 'CRM', ['icon' => 'people'], function ($group) {
                $group->addItem('clients', 'Clients', '/clients', [
                          'badge' => 5,
                          'badge_color' => 'danger',
                      ])
                      ->addItem('contacts', 'Contacts', '/contacts');
            })
            ->addDivider()
            ->addItem('settings', 'Paramètres', '/settings', [
                'icon' => 'gear',
                'position' => 'bottom',
                'roles' => ['ROLE_ADMIN'],
            ])
            ->setCollapsible(true)
            ->setActiveAuto(true)
            ->build();

        return $this->render('base.html.twig', ['menu' => $menu]);
    }
}
```

#### Templates Twig

[](#templates-twig)

```
{# Sidebar #}
{% include '@OwlMenu/sidebar.html.twig' with { menu: menu } %}

{# Topbar (alternative) #}
{% include '@OwlMenu/topbar.html.twig' with { menu: menu } %}

{# Breadcrumb #}
{% include '@OwlMenu/breadcrumb.html.twig' with { menu: menu } %}
```

#### Fonctions Twig

[](#fonctions-twig)

```
{# Récupérer un menu enregistré par ID #}
{% set menu = owl_menu('sidebar') %}

{# Breadcrumb depuis l'ID #}
{% set crumbs = owl_menu_breadcrumb('sidebar') %}

{# Vérifier si un item est actif #}
{% if owl_menu_is_active('clients') %}...{% endif %}

{# Icône HTML #}
{{ owl_menu_icon('house') }}  {# →  #}

{# Préfixe CSS #}
{{ owl_menu_prefix() }}  {# → owl-menu #}
```

### Options des items

[](#options-des-items)

OptionTypeDéfautDescription`icon``string``null`Nom de l'icône (sans préfixe)`badge``int|string``null`Texte ou compteur du badge`badge_color``string``null`Couleur : `danger`, `warning`, `success``roles``string[]``[]`Rôles Symfony requis (OR)`position``string``default``default` ou `bottom``target``string``null`Attribut target du lien`css_class``string``null`Classe CSS supplémentaire`divider_before``bool``false`Séparateur avant l'item`divider_after``bool``false`Séparateur après l'item### Détection active (scoring URL)

[](#détection-active-scoring-url)

Le bundle compare l'URL courante avec chaque item :

URL couranteItem `/dashboard`Item `/clients`Item `/contacts``/dashboard`**100** (exact)00`/clients/123/edit`0**8** (prefix)0`/contacts`00**100** (exact)L'item avec le score le plus élevé est marqué actif, et son groupe parent est auto-déplié.

### Intégrations optionnelles

[](#intégrations-optionnelles)

- **owl-theme-bundle** — les variables CSS `var(--owl-*)` sont automatiquement utilisées
- **owl-settings-bundle** — `collapse_storage: settings` persiste l'état via DBAL

### Assets

[](#assets)

```
{# CSS #}

{# JS (en fin de body) #}

```

Installer les assets :

```
php bin/console assets:install public
```

### API JavaScript

[](#api-javascript)

```
// Accéder à l'API
window.OwlMenu.init();  // Ré-initialiser (après AJAX)

// Écouter les événements
document.addEventListener('owl-menu:collapse', function(e) {
    console.log(e.detail.id, e.detail.collapsed);
});

document.addEventListener('owl-menu:mobile', function(e) {
    console.log(e.detail.id, e.detail.open);
});
```

---

🇬🇧 English
----------

[](#-english)

Symfony bundle for **dynamic navigation** — collapsible sidebar, horizontal topbar, auto-generated breadcrumbs, accordion groups, badges, icons, role-based filtering, automatic active detection.

### Features

[](#features)

- **Collapsible sidebar** — 260px → 60px (icons only) with smooth transition
- **Horizontal topbar** — alternative navbar with dropdowns
- **Auto-generated breadcrumbs** — breadcrumb trail based on menu hierarchy
- **Accordion groups** — collapsible sub-menus with animation
- **Badges / Counters** — visual notifications on items
- **Icons** — configurable prefix (Bootstrap Icons, FontAwesome, etc.)
- **Role-based filtering** — hides items based on Symfony roles
- **Automatic active detection** — highlight based on current URL
- **Anti-flash** — inline script reads localStorage before first paint
- **Responsive** — burger menu on mobile ≤ 768px
- **CSS variables** — works with or without `owl-theme-bundle`
- **Zero JS dependencies** — vanilla JS, IIFE pattern

### Installation

[](#installation-1)

```
composer require owl-concept/menu-bundle
```

### Configuration

[](#configuration-1)

```
# config/packages/owl_menu.yaml
owl_menu:
    css_class_prefix: 'owl-menu'          # BEM prefix
    collapse_storage: 'localStorage'       # localStorage | settings
    active_detection: 'auto'               # auto | manual
    icon_prefix: 'bi bi-'                  # Icon CSS prefix
```

### Usage

[](#usage)

#### Create a menu in a controller or service

[](#create-a-menu-in-a-controller-or-service)

```
use OwlConcept\MenuBundle\Builder\MenuBuilder;

class AppController extends AbstractController
{
    public function index(MenuBuilder $menuBuilder): Response
    {
        $menu = $menuBuilder->create('sidebar')
            ->addItem('dashboard', 'Dashboard', '/dashboard', [
                'icon' => 'house',
            ])
            ->addGroup('crm', 'CRM', ['icon' => 'people'], function ($group) {
                $group->addItem('clients', 'Clients', '/clients', [
                          'badge' => 5,
                          'badge_color' => 'danger',
                      ])
                      ->addItem('contacts', 'Contacts', '/contacts');
            })
            ->addDivider()
            ->addItem('settings', 'Settings', '/settings', [
                'icon' => 'gear',
                'position' => 'bottom',
                'roles' => ['ROLE_ADMIN'],
            ])
            ->setCollapsible(true)
            ->setActiveAuto(true)
            ->build();

        return $this->render('base.html.twig', ['menu' => $menu]);
    }
}
```

#### Twig Templates

[](#twig-templates)

```
{# Sidebar #}
{% include '@OwlMenu/sidebar.html.twig' with { menu: menu } %}

{# Topbar (alternative) #}
{% include '@OwlMenu/topbar.html.twig' with { menu: menu } %}

{# Breadcrumb #}
{% include '@OwlMenu/breadcrumb.html.twig' with { menu: menu } %}
```

#### Twig Functions

[](#twig-functions)

```
{# Get a registered menu by ID #}
{% set menu = owl_menu('sidebar') %}

{# Breadcrumb from ID #}
{% set crumbs = owl_menu_breadcrumb('sidebar') %}

{# Check if an item is active #}
{% if owl_menu_is_active('clients') %}...{% endif %}

{# Icon HTML #}
{{ owl_menu_icon('house') }}  {# →  #}

{# CSS prefix #}
{{ owl_menu_prefix() }}  {# → owl-menu #}
```

### Item Options

[](#item-options)

OptionTypeDefaultDescription`icon``string``null`Icon name (without prefix)`badge``int|string``null`Badge text or counter`badge_color``string``null`Color: `danger`, `warning`, `success``roles``string[]``[]`Required Symfony roles (OR logic)`position``string``default``default` or `bottom``target``string``null`Link target attribute`css_class``string``null`Additional CSS class`divider_before``bool``false`Divider before item`divider_after``bool``false`Divider after item### Active Detection (URL scoring)

[](#active-detection-url-scoring)

The bundle compares the current URL against each item:

Current URLItem `/dashboard`Item `/clients`Item `/contacts``/dashboard`**100** (exact)00`/clients/123/edit`0**8** (prefix)0`/contacts`00**100** (exact)The item with the highest score is marked active, and its parent group is auto-expanded.

### Optional Integrations

[](#optional-integrations)

- **owl-theme-bundle** — CSS variables `var(--owl-*)` are automatically used
- **owl-settings-bundle** — `collapse_storage: settings` persists state via DBAL

### Assets

[](#assets-1)

```
{# CSS #}

{# JS (at end of body) #}

```

Install assets:

```
php bin/console assets:install public
```

### JavaScript API

[](#javascript-api)

```
// Access the API
window.OwlMenu.init();  // Re-initialize (after AJAX)

// Listen to events
document.addEventListener('owl-menu:collapse', function(e) {
    console.log(e.detail.id, e.detail.collapsed);
});

document.addEventListener('owl-menu:mobile', function(e) {
    console.log(e.detail.id, e.detail.open);
});
```

---

License
-------

[](#license)

Proprietary — All rights reserved.

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance53

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/d9c48f4a438b587779711c9b1619fc238d635817cadc99091820d553700abcca?d=identicon)[Jaecko](/maintainers/Jaecko)

### Embed Badge

![Health badge](/badges/owl-concept-menu-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/owl-concept-menu-bundle/health.svg)](https://phpackages.com/packages/owl-concept-menu-bundle)
```

###  Alternatives

[otgs/multilingual-tools

Set of tools related to WPML plugin bundle. Created with tendency to ease WPML compatibility testing process.

39167.2k](/packages/otgs-multilingual-tools)[johndwells/craft.minimee

A Craft CMS port of the popular Minimee add-on for ExpressionEngine.

664.5k](/packages/johndwells-craftminimee)[leaphly/price

466.5k](/packages/leaphly-price)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
