symkit / menu-bundle
Menu Bundle for Symkit
Installs: 217
Dependents: 4
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:symfony-bundle
pkg:composer/symkit/menu-bundle
Requires
- php: >=8.2
- doctrine/doctrine-bundle: ^2.11 || ^3.0
- symfony/form: ^7.0 || ^8.0
- symfony/framework-bundle: ^7.0 || ^8.0
- symfony/routing: ^7.0 || ^8.0
- symfony/twig-bundle: ^7.0 || ^8.0
- symfony/validator: ^7.0 || ^8.0
- symkit/crud-bundle: ~0.0.1
- symkit/form-bundle: ~0.0.1
- symkit/metadata-bundle: ~0.0.1
Requires (Dev)
- deptrac/deptrac: ^2.0
- friendsofphp/php-cs-fixer: ^3.0
- infection/infection: ^0.29
- nyholm/symfony-bundle-test: ^3.0
- phpro/grumphp: ^2.0
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
- symkit/bundle-ai-kit: ~0.0.1
README
A flexible, SOLID menu system for Symfony. Manage menus from the database or via PHP builders, with support for complex structures (Mega Menus, advanced dropdowns).
Features
- Database or code: Menus from Doctrine entities (priority) or from tagged builders.
- Configurable: Enable/disable admin, Twig, AssetMapper, Doctrine independently.
- Overridable entities: Configure custom
Menu/MenuItemFQCNs. - Routes in config: Admin routes loaded from a routing file with configurable prefix.
- Public API: Type-hint on
Symkit\MenuBundle\Contract\*interfaces for BC-safe usage.
Installation
composer require symkit/menu-bundle
Register the bundle in config/bundles.php (auto with Flex):
return [ Symkit\MenuBundle\SymkitMenuBundle::class => ['all' => true], ];
Configuration
All features are enabled by default. Example with explicit options:
# config/packages/symkit_menu.yaml symkit_menu: admin: enabled: true route_prefix: admin # prefix for admin routes (default: admin) twig: enabled: true assets: enabled: true # AssetMapper prepend for Stimulus controllers doctrine: enabled: true entities: menu: Symkit\MenuBundle\Entity\Menu menu_item: Symkit\MenuBundle\Entity\MenuItem
Routes
Include the bundle admin routes in your app (e.g. config/routes.yaml):
symkit_menu: resource: '@SymkitMenuBundle/Resources/config/routing.yaml' prefix: '%symkit_menu.admin.route_prefix%'
This registers routes such as admin_menu_list, admin_menu_create, admin_menu_edit, admin_menu_item_*, admin_menu_items_json. Change route_prefix in config to alter the URL prefix (e.g. /back-office/menus).
Overriding entities
To use your own Menu or MenuItem classes (e.g. extended with extra fields):
- Extend the bundle entities:
class App\Entity\Menu extends Symkit\MenuBundle\Entity\Menu. - Configure the FQCNs:
symkit_menu: doctrine: entities: menu: App\Entity\Menu menu_item: App\Entity\MenuItem
- Map your entities in Doctrine (XML/attributes) as usual.
Usage
Admin UI
With admin.enabled: true and symkit/crud-bundle and symkit/metadata-bundle installed, you get CRUD for menus and items (hierarchy, types, icons). Admin controllers use #[Seo] and #[Breadcrumb] from the metadata bundle when available.
PHP builders
Implement the Contract interface and tag the service:
namespace App\Navigation; use Symkit\MenuBundle\Contract\MenuNavigationBuilderInterface; use Symkit\MenuBundle\Contract\MenuItemInterface; use Symkit\MenuBundle\Model\MenuLink; class PrimaryNavigationBuilder implements MenuNavigationBuilderInterface { public function build(): array { return [ new MenuLink('home', 'Home', '/'), // ... ]; } }
services: App\Navigation\PrimaryNavigationBuilder: tags: - { name: 'symkit_menu.menu_builder', alias: 'primary' }
Active menu
Use the #[ActiveMenu] attribute on controllers:
use Symkit\MenuBundle\Attribute\ActiveMenu; #[ActiveMenu('primary', 'home')] public function index(): Response { ... }
Or set it manually:
$menuManager->setActiveId('primary', 'item_id');
Twig
When twig.enabled: true, use the get_menu function:
{% for item in get_menu('primary') %}
{{ include('@SymkitMenu/components/menu/_' ~ (item.type == 'mega' ? 'mega_menu_full' : (item.type == 'advanced_dropdown' ? 'dropdown_advanced' : (item.type == 'dropdown' ? 'dropdown_simple' : 'link'))) ~ '.html.twig', {item: item}) }}
{% endfor %}
Public API (Contract)
For stable, BC-safe integration, type-hint on interfaces under Symkit\MenuBundle\Contract\:
- MenuNavigationBuilderInterface: implement
build(): array(ofMenuItemInterface). - MenuItemMapperInterface: implement
supports(MenuItem $entity): boolandmap(MenuItem $entity, MenuModelFactory $factory): MenuItemInterface. - MenuItemInterface: id, label, active state, type.
Models under Symkit\MenuBundle\Model\ (e.g. MenuLink, MenuDropdown) implement these contracts.
Customization
- Create a model implementing
Symkit\MenuBundle\Contract\MenuItemInterface. - Create a mapper implementing
Symkit\MenuBundle\Contract\MenuItemMapperInterface. - Tag the mapper with
symkit_menu.menu_item_mapper.
The bundle will use your mapper when it meets the corresponding entity type.
Stimulus / AssetMapper
With assets.enabled: true, the bundle prepends its Stimulus controllers to AssetMapper. Register them in your app (e.g. importmap.php and stimulus_bootstrap.js) as needed for dropdown and mobile menu behaviour.
Contributing
make install make cs-fix make phpstan make test make quality # cs-check + phpstan + deptrac + lint + test + infection make ci # security-check + quality
License
MIT.