The admin menu in Pushword is highly customizable through Symfony events. You can add new items, modify existing ones, or completely replace the menu structure.
The AdminMenu class dispatches the AdminItemsEvent event (pushword.admin.menu_items) during menu configuration. This event allows any bundle or custom code to interact with the menu items before they are displayed.
Each menu item has a weight that determines its position in the menu. Items with higher weights appear first in the menu.
To add a new item to the admin menu, create an EventSubscriber that listens to the AdminItemsEvent:
<?php
namespace App\EventSubscriber;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use Pushword\Admin\Menu\AdminItemsEvent;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
#[AutoconfigureTag('kernel.event_subscriber')]
final readonly class AdminMenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
AdminItemsEvent::NAME => 'onMenuItems',
];
}
public function onMenuItems(AdminItemsEvent $event): void
{
$event->addMenuItem(
MenuItem::linkToRoute('My Custom Page', 'fa fa-star', 'my_custom_route'),
500 // weight (higher = appears first)
);
}
}
You can create different types of menu items:
Link to a route:
MenuItem::linkToRoute('Label', 'fa fa-icon', 'route_name')
Link to a CRUD controller:
MenuItem::linkToCrud('Label', 'fa fa-icon', EntityClass::class)
->setController(MyCrudController::class)
Submenu:
MenuItem::subMenu('Label', 'fa fa-icon')
->setSubItems([
MenuItem::linkToRoute('Sub Item', 'fa fa-icon', 'route_name'),
])
Section (separator):
MenuItem::section('Section Title')
Default weights used by Pushword core:
Use values between these to position your items correctly.
If you need to completely customize the menu structure, you can use setItems() to replace all items:
<?php
namespace App\EventSubscriber;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use Pushword\Admin\Menu\AdminItemsEvent;
use Pushword\Core\Entity\Page;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
#[AutoconfigureTag('kernel.event_subscriber')]
final readonly class AdminMenuSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
AdminItemsEvent::NAME => 'onMenuItems',
];
}
public function onMenuItems(AdminItemsEvent $event): void
{
// Get existing items
$items = $event->getItems();
// Filter out items you don't want
$items = array_filter($items, function (array $item) {
// Remove items with weight less than 500
return $item['weight'] >= 500;
});
// Add your custom items
$items[] = [
'weight' => 100,
'item' => MenuItem::linkToRoute('Custom', 'fa fa-cog', 'custom_route'),
];
// Replace all items
$event->setItems($items);
}
}
The conversation bundle adds its menu item when the Message entity exists:
<?php
namespace Pushword\Conversation\EventSubscriber;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use Pushword\Admin\Menu\AdminItemsEvent;
use Pushword\Conversation\Entity\Message;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
#[AutoconfigureTag('kernel.event_subscriber')]
final readonly class MenuItemsSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
AdminItemsEvent::NAME => 'onMenuItems',
];
}
public function onMenuItems(AdminItemsEvent $event): void
{
if (class_exists(Message::class)) {
$event->addMenuItem(
MenuItem::linkToCrud('admin.label.conversation', 'fa fa-comments', Message::class),
600
);
}
}
}
<?php
namespace Pushword\PageScanner\EventSubscriber;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use Pushword\Admin\Menu\AdminItemsEvent;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
#[AutoconfigureTag('kernel.event_subscriber')]
final readonly class MenuItemsSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
AdminItemsEvent::NAME => 'onMenuItems',
];
}
public function onMenuItems(AdminItemsEvent $event): void
{
$event->addMenuItem(
MenuItem::linkToRoute('admin.label.check_content', 'fa fa-check-circle', 'admin_page_scanner'),
400
);
}
}
#[AutoconfigureTag('kernel.event_subscriber')] attribute to automatically register your subscriber