Skip to content

Conversation

@Zales0123
Copy link
Contributor

Hello there! 👋

Recently I've started a new project based on Sylius Stack. So far so good 😄 But, I miss very much the menu builder event that is present in Sylius. It gives much better extendability: for example I can write multiple menu listeners in multiple bounded contexts in my application, not a single one on the high level. Also code looks a little bit simpler 😅

Let me know how it looks for you 🫡

PS. I don't know if there is any BC policy, but I suppose there is not, as it's still pre-alpha version :)

@Prometee
Copy link
Contributor

Prometee commented Oct 7, 2025

Good idea to revive this feature.

What about a tagged iterator instead of an event ?

@Zales0123
Copy link
Contributor Author

Good idea to revive this feature.

🫡

What about a tagged iterator instead of an event ?

I have no preference one over another 🤷 Maybe the only reason to keep it with event is to make it consistent with what is implemented in Sylius - in the end, that was my initial tension, as I expected the menu builder to work the same way in Sylius/Stack as in Sylius/Sylius, but was surprised it doesn't 😅

@loic425
Copy link
Member

loic425 commented Oct 10, 2025

@Zales0123 You can decorate the service several times for your bounded contexts, return the decorated one when the bounded context decorator does not have the right context. I think that's better than events. Don't you think?

@loic425
Copy link
Member

loic425 commented Oct 24, 2025

@Zales0123 If this event does not have performance issue. I suggest adding it as a decorator.

I've tried this and it works well. The event will be dispatched after our custom menu in user-land application.
Even if decorating system works with plugin, that feature could be useful to facilitate both Sylius/Sylius stack plugins.

And if, at some point, we decide to remove the event system, we will simply need to remove this decorator.

I'd also be in favour to keep the decorating system in the documentation and add a note about the event system.

<?php

/*
 * This file is part of the Sylius package.
 *
 * (c) Sylius Sp. z o.o.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace Sylius\AdminUi\Knp\Menu;

use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;
use Sylius\AdminUi\Knp\Menu\Event\MenuBuilderEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

final class EventMenuBuilder implements MenuBuilderInterface
{
    public const EVENT_NAME = 'sylius_admin_ui.menu.event.main';

    public function __construct(
        private readonly MenuBuilderInterface $menuBuilder,
        private readonly FactoryInterface $menuFactory,
        private readonly EventDispatcherInterface $eventDispatcher,
    ) {
    }

    public function createMenu(array $options): ItemInterface
    {
        $menu = $this->menuBuilder->createMenu($options);

        $this->eventDispatcher->dispatch(
            new MenuBuilderEvent($this->menuFactory, $menu),
            self::EVENT_NAME,
        );

        return $menu;
    }
}
$services->set('sylius_admin_ui.knp.menu_builder.event', EventMenuBuilder::class)
    ->decorate(id: 'sylius_admin_ui.knp.menu_builder', priority: 100)
    ->args([
        service('.inner'),
        service('knp_menu.factory'),
        service('event_dispatcher'),
    ])
;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants