braunstetter/control-panel-bundle
Installation:
composer require braunstetter/control-panel-bundle
yarn install --force
Ensure BraunstetterControlPanelBundle is enabled in config/bundles.php.
First Use Case:
base.html.twig) by copying it to templates/ControlPanelBundle/base.html.twig.TemplateHooksBundle (install via composer require braunstetter/template-hooks-bundle if needed).sidebar hook in your template.Routing:
Define a route in config/routes.yaml:
control_panel:
resource: "@ControlPanelBundle/Resources/config/routing.yaml"
prefix: /admin
Basic Page:
Create a controller extending AbstractControlPanelController (if available) or use Twig templates directly:
{% extends 'ControlPanelBundle::base.html.twig' %}
{% block content %}
<h1>Welcome to Your Control Panel</h1>
{% endblock %}
Hook-Based Structure: Leverage TemplateHooksBundle hooks (e.g., sidebar, header, footer) to inject content without modifying core templates.
Example:
{% do hook('sidebar') %}
<li><a href="{{ path('app_dashboard') }}">Dashboard</a></li>
Layout Inheritance:
Override base.html.twig to customize the mobile/desktop structure. Key hooks:
content: Main body content.sidebar: Navigation menu.header: Top bar (e.g., user profile, notifications).Custom Form Types: Use pre-built form types (e.g., ControlPanelType) for admin forms.
Example:
// src/Form/OrangePuppyType.php
use Braunstetter\ControlPanelBundle\Form\ControlPanelType;
class OrangePuppyType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('name', ControlPanelType::class, [
'label' => 'Puppy Name',
]);
}
}
CRUD Workflow:
Pair with EasyAdminBundle or SonataAdminBundle for rapid CRUD, but use this bundle for lightweight admin panels.
Controller Structure:
Extend AbstractControlPanelController (if provided) or create custom controllers:
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class AdminController extends AbstractController {
#[Route('/admin/dashboard', name: 'app_dashboard')]
public function dashboard(): Response {
return $this->render('admin/dashboard.html.twig');
}
}
Asset Management:
Use assets/ directory for CSS/JS. Override base.html.twig to include:
{{ parent() }} {# Call parent template first #}
{{ encore_entry_link_tags('admin-app') }} {# Webpack Encore assets #}
UserAdminBundle) for scalability.Hook Naming Collisions:
sidebar) don’t conflict with other bundles. Prefix if needed (e.g., cp_sidebar).{% if hook('sidebar') is defined %} checks.Asset Loading:
{{ parent() }} in extended templates breaks asset inclusion (e.g., Bootstrap CSS).admin-app entry point.Form Type Dependencies:
Resources/public/ for dependencies.ControlPanelType might need select2 for enhanced selects.Routing Conflicts:
/admin prefix may clash with other bundles. Adjust in routing.yaml:
prefix: /app_admin
Template Debugging:
Use Twig’s {% debug %} or Symfony’s profiler to inspect rendered hooks:
{% block content %}
{% debug %}
{% endblock %}
Form Validation: Custom form types may need validation overrides. Extend the base type:
class OrangePuppyType extends ControlPanelType {
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'validation_groups' => ['Default', 'admin'],
]);
}
}
TemplateHooksBundle:
TemplateHooksBundle is installed and configured in bundles.php.php bin/console cache:clear
Yarn Dependencies:
yarn install --force may resolve missing assets, but check package.json for required dev dependencies (e.g., bootstrap, select2).Environment-Specific Assets:
dev vs. prod:
// webpack.config.js
Encore.enableSingleRuntimeChunk()
.setPublicPath('/admin/assets')
.addEntry('admin-app', './assets/admin/app.js');
Custom Templates:
Resources/views/layouts/base.html.twig to templates/ControlPanelBundle/layouts/.sidebar.html.twig) for granular control.Dynamic Hooks:
use Braunstetter\TemplateHooksBundle\Hook\HookManager;
public function __construct(private HookManager $hookManager) {}
public function addDashboardHook() {
$this->hookManager->add('sidebar', '<li>Dynamic Link</li>');
}
Event Listeners:
// src/EventListener/ControlPanelListener.php
use Braunstetter\ControlPanelBundle\Event\ControlPanelEvent;
class ControlPanelListener {
public function onBuildPanel(ControlPanelEvent $event) {
$event->addMenuItem('Settings', 'app_settings');
}
}
Register in services.yaml:
services:
App\EventListener\ControlPanelListener:
tags:
- { name: kernel.event_listener, event: control_panel.build, method: onBuildPanel }
API Integration:
{% block content %}
<div class="api-status">
{% for endpoint, status in api_status %}
<p>{{ endpoint }}: {{ status }}</p>
{% endfor %}
</div>
{% endblock %}
How can I help you explore Laravel packages today?