Installation
composer require codeconsortium/ccdn-gui-bundle
Add to config/bundles.php:
return [
// ...
CodeConsortium\CCDNGuiBundle\CCDNGuiBundle::class => ['all' => true],
];
Basic Usage
Inject the GuiFactory service into your controller/service:
use CodeConsortium\CCDNGuiBundle\Factory\GuiFactoryInterface;
public function __construct(private GuiFactoryInterface $factory) {}
First Renderable UI
Create a simple SidebarListSubMenu in a controller:
public function buildSidebar()
{
$menu = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('Admin Panel')
->setIcon('fas fa-cog');
$menu->addLink('Dashboard', 'dashboard', null, ['class' => 'active']);
$menu->addLink('Users', 'users', null, []);
return $this->render('admin/sidebar.html.twig', ['menu' => $menu]);
}
Twig Integration
Ensure your Twig templates can render the generated objects. The bundle expects Twig extensions to handle these types (check Resources/views/ for examples).
public function buildDynamicMenu(array $items)
{
$menu = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('Dynamic Menu')
->setIcon('fas fa-th');
foreach ($items as $item) {
$menu->addLink(
$item['label'],
$item['route'],
$item['icon'] ?? null,
$item['attributes'] ?? []
);
}
return $menu;
}
public function buildNestedAdminPanel()
{
// Parent menu
$adminPanel = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('Admin')
->setIcon('fas fa-users-cog');
// Child menu (Products)
$productsMenu = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('Products')
->setIcon('fas fa-box');
$productsMenu->addLink('List', 'products.index');
$productsMenu->addLink('Create', 'products.create');
// Child menu (Users)
$usersMenu = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('Users')
->setIcon('fas fa-users');
$usersMenu->addLink('List', 'users.index');
$usersMenu->addLink('Roles', 'users.roles');
// Attach children to parent
$adminPanel->add($productsMenu);
$adminPanel->add($usersMenu);
return $adminPanel;
}
Create a dedicated service for complex UIs:
// src/Service/AdminMenuBuilder.php
class AdminMenuBuilder
{
public function __construct(private GuiFactoryInterface $factory) {}
public function build(): SidebarListSubMenu
{
$menu = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('Admin Panel')
->setIcon('fas fa-tachometer-alt');
$menu->addLink('Dashboard', 'admin.dashboard');
$menu->add($this->buildSettingsSubmenu());
return $menu;
}
private function buildSettingsSubmenu(): SidebarListSubMenu
{
$submenu = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('Settings')
->setIcon('fas fa-cog');
$submenu->addLink('General', 'admin.settings.general');
$submenu->addLink('Users', 'admin.settings.users');
return $submenu;
}
}
public function buildUserMenu(User $user)
{
$menu = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('User Panel')
->setIcon('fas fa-user');
$menu->addLink('Profile', 'user.profile');
if ($user->isAdmin()) {
$menu->addLink('Admin Dashboard', 'admin.dashboard');
}
return $menu;
}
public function buildFormSidebar(FormInterface $form)
{
$sidebar = $this->factory->create(SidebarListSubMenu::getType())
->setLabel('Form Actions')
->setIcon('fas fa-file-alt');
$sidebar->addLink('Submit', 'form.submit', null, ['class' => 'btn-primary']);
$sidebar->addLink('Cancel', 'form.cancel');
return $sidebar;
}
Ensure your Twig templates extend a base template that includes the bundle's Twig extensions:
{# templates/base.html.twig #}
{% block sidebar %}
{{ menu.render() }}
{% endblock %}
Pass route names as strings and use Laravel's route() helper in Twig:
<a href="{{ path('dashboard') }}" class="{{ menu.linkAttributes.class }}">...</a>
Use Laravel Mix/Vite to compile icons/fonts referenced in setIcon():
// Ensure Font Awesome is loaded in your layout
$this->factory->create(SidebarListSubMenu::getType())
->setIcon('fas fa-cog'); // Requires Font Awesome
Cache the generated GUI objects in a service:
public function getCachedMenu(): SidebarListSubMenu
{
return Cache::remember('admin.menu', now()->addHours(1), function () {
return $this->buildAdminMenu();
});
}
Method "render()" does not exist or similar.CCDNGuiBundle.php for load() method and verify Resources/config/services.yaml includes:
services:
CodeConsortium\CCDNGuiBundle\Twig\GuiExtension:
tags: ['twig.extension']
create(SomeType::getType()) throws ClassNotFoundException.$this->factory->registerType(SomeType::class, SomeTypeRenderer::class);
fas fa-cog) don’t render.->setIcon('/assets/icons/cog.svg')
{% if isGranted('ROLE_ADMIN') %}
{{ menu.render() }}
{% endif %}
Inspect the object structure before rendering:
$menu = $this->buildAdminMenu();
dump($menu->toArray()); // If toArray() exists
// OR
dump(get_object_vars($menu));
Enable Twig debugging in config/twig.php:
'debug' => env('APP_DEBUG'),
Wrap factory calls in a decorator to log usage:
public function create(string $type)
{
\Log::debug("Creating GUI type: {$type}");
return $this->factory->create($type);
}
Extend the bundle to support new component types:
// src/Type/CustomCard.php
class CustomCard implements GuiInterface
{
public static function getType(): string { return 'custom_card'; }
public function setTitle(string $title): self { ... }
public function addContent(string $content): self { ... }
public function render(Environment $env): string
{
return $env->render('@CCDNGuiBundle/CustomCard/custom_card.html.twig', [
'title' => $this->title,
'content' => $this->content,
]);
}
}
Register the type in a service:
public function __construct(Gui
How can I help you explore Laravel packages today?