darvinstudio/darvin-admin-bundle
Installation
composer require darvinstudio/darvin-admin-bundle
Enable the bundle in config/bundles.php:
return [
// ...
DarvinStudio\AdminBundle\DarvinAdminBundle::class => ['all' => true],
];
First Admin Section
Create a basic admin section by defining a YAML config file (e.g., config/admin/books.yml):
darvin_admin:
sections:
books:
label: Books
entity: App\Entity\Book
list:
fields: [id, title, author, createdAt]
Clear cache:
php bin/console cache:clear
First Use Case
Access the admin panel at /admin (or your configured route). The bundle auto-generates CRUD interfaces for App\Entity\Book based on the YAML config.
Entity Management
list.fields in YAML.
list:
fields: [id, title, {property: 'author.name', label: 'Author'}]
form.fields to include/exclude fields or add custom widgets.
form:
fields:
- { property: 'title', type: 'text', options: { label: 'Book Title' } }
- { property: 'coverImage', type: 'dropzone', options: { maxFiles: 1 } }
Dashboard Integration
Add widgets to the dashboard via dashboard.widgets in config:
dashboard:
widgets:
- { type: 'statistic', label: 'Total Books', value: 'entity(Book).count()' }
- { type: 'chart', label: 'Books by Year', data: 'entity(Book).groupByYear()' }
Menu Customization Define menu items in YAML:
menu:
items:
- { label: 'Books', route: 'admin_books_list' }
- { label: 'Users', route: 'admin_users_list', icon: 'fas fa-user' }
CKEditor Integration Enable for a field in YAML:
form:
fields:
- { property: 'description', type: 'ckeditor' }
Dropzone for File Uploads Configure in YAML:
form:
fields:
- { property: 'coverImage', type: 'dropzone', options: { url: '/admin/upload', maxFilesize: 2 } }
Handle uploads in a controller:
#[Route('/admin/upload', name: 'admin_upload', methods: ['POST'])]
public function upload(Request $request): JsonResponse
{
// Handle file upload logic
}
security.configurations to restrict access:
security:
roles:
books:
- ROLE_ADMIN
- ROLE_EDITOR
translations/admin.en.yml:
books:
list:
title: 'Book Title'
author: 'Author Name'
Cache Dependencies
php bin/console cache:clear
debug:config darvin_admin to verify loaded configs.Entity Overrides
DarvinStudio\AdminBundle\Form\Type\AdminEntityType.Route Conflicts
_admin or use unique namespaces:
# config/routes.yaml
admin_upload:
path: /admin/_upload
controller: App\Controller\AdminUploadController::upload
Dropzone Configuration
url option in YAML doesn’t match the controller route.url in YAML matches the exact route path (e.g., /admin/upload vs /admin/_upload).CKEditor Assets
composer require ckeditor/ckeditor5 and ensure the bundle is enabled in config/bundles.php.config/packages/dev/darvin_admin.yaml:
darvin_admin:
debug: true
entity path in YAML matches the fully qualified class name (e.g., App\Entity\Book).list.fields or form.fields and ensure the property exists in the entity.Custom Widgets
Create reusable widgets by extending DarvinStudio\AdminBundle\Widget\AbstractWidget and register them in the bundle’s configuration.
Event Listeners
Hook into lifecycle events (e.g., prePersist, postRemove) via Symfony’s event dispatcher. Example:
// src/EventListener/AdminListener.php
public static function getSubscribedEvents(): array
{
return [
DarvinAdminEvents::PRE_PERSIST => 'onPrePersist',
];
}
public function onPrePersist(PrePersistEvent $event): void
{
$entity = $event->getEntity();
if ($entity instanceof Book) {
$entity->setUpdatedAt(new \DateTime());
}
}
Twig Extensions
Extend Twig templates by creating custom templates in templates/admin/ and overriding bundle templates. Example:
{# templates/admin/Book/list.html.twig #}
<td>{{ book.author.name|default('N/A') }}</td>
API Integration Use the bundle’s underlying services to build custom API endpoints. Example:
$adminSection = $this->container->get('darvin_admin.section.manager')->getSection('books');
$repository = $adminSection->getEntityManager()->getRepository($adminSection->getEntityClass());
$books = $repository->findAll();
// config/packages/darvin_admin.php
$container->loadFromExtension('darvin_admin', [
'debug' => true,
'menu' => [
'items' => [
['label' => 'Dashboard', 'route' => 'admin_dashboard'],
],
],
]);
entity(Book).count() in dashboard widgets. These are resolved at runtime.list config:
list:
fields: [id, title]
pagination: true
list:
fields: [id, {property: 'author.name', label: 'Author'}]
fetch_plan: ['author']
How can I help you explore Laravel packages today?