dontdrinkandroot/crud-admin-bundle
Installation
composer require dontdrinkandroot/crud-admin-bundle
Add to config/bundles.php:
return [
// ...
Dontdrinkandroot\CrudAdminBundle\DontdrinkandrootCrudAdminBundle::class => ['all' => true],
];
Basic Configuration
Create a YAML config file (e.g., config/crud_admin.yaml) with a minimal entity definition:
resources:
App\Entity\Product:
fields: [id, name, price]
actions: [new, edit, delete]
First Use Case
Run migrations (if needed) and access the admin panel at /admin. The bundle auto-generates CRUD interfaces for configured entities.
config/crud_admin.yaml (primary config file).src/Entity/ for annotated properties (e.g., @ORM\Column).templates/crud_admin/.App\Entity\Product extends Doctrine\ORM\Mapping\Entity).Entity Configuration
Define CRUD behavior per entity in crud_admin.yaml:
resources:
App\Entity\User:
fields: [username, email, roles] # Columns to display
searchable: [username, email] # Search fields
sortable: [username, createdAt] # Sortable columns
actions: [new, edit, delete, show] # Available actions
filters: [active] # Custom filters
Field Customization Use annotations or YAML to customize fields:
fields:
name:
label: "Product Name"
type: "text"
options:
attr:
placeholder: "Enter product name"
Action Overrides
Extend default actions (e.g., edit) via event listeners or custom controllers:
// src/EventListener/CrudAdminListener.php
use Dontdrinkandroot\CrudAdminBundle\Event\CrudAdminEvent;
public function onPreEdit(CrudAdminEvent $event) {
$entity = $event->getEntity();
// Custom logic before edit
}
Integration with Forms Use Symfony’s form system for complex validation:
form:
type: App\Form\ProductType
options:
validation_groups: [Default, product]
Dynamic Routing Generate routes dynamically via annotations:
// src/Entity/Product.php
use Dontdrinkandroot\CrudAdminBundle\Annotation\CrudAdmin;
/**
* @CrudAdmin\Route(
* name="product_custom_route",
* path="/custom-products"
* )
*/
class Product {}
Batch Actions Enable bulk operations in YAML:
actions:
batch: [publish, archive]
Access Control Restrict access via security voters or annotations:
security:
roles: [ROLE_ADMIN, ROLE_SUPER_ADMIN]
API Integration Expose CRUD endpoints via API Platform or custom controllers:
api:
enabled: true
prefix: /api/products
Entity Mapping Issues
No entity found.@ORM\Entity and use Doctrine\ORM\Mapping as ORM.php bin/console doctrine:schema:validate to check mappings.Caching Problems
php bin/console cache:clear
Field Type Mismatches
fields:
createdAt:
type: "datetime"
format: "yyyy-MM-dd HH:mm"
Event Listener Conflicts
// src/EventListener/CrudAdminListener.php
public static function getSubscribedEvents() {
return [
CrudAdminEvents::PRE_EDIT => 'onPreEdit',
];
}
Enable Debug Mode
Set APP_DEBUG=true in .env to see detailed errors and logs.
Log Events Use Symfony’s event dispatcher to log CRUD actions:
public function onPostSave(CrudAdminEvent $event) {
\Log::info('Entity saved:', [$event->getEntity()->getId()]);
}
Check Twig Templates Override templates to debug rendering:
{# templates/crud_admin/base.html.twig #}
<div class="debug">{{ dump(app) }}</div>
Custom Field Types
Create a custom field type by extending Dontdrinkandroot\CrudAdminBundle\Form\Type\FieldType:
namespace App\Form\Type;
use Dontdrinkandroot\CrudAdminBundle\Form\Type\FieldType;
class CustomFieldType extends FieldType {
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'type' => 'text',
'attr' => ['class' => 'custom-field'],
]);
}
}
Register in services:
# config/services.yaml
App\Form\Type\CustomFieldType: ~
Dynamic Field Loading Use callbacks to load fields dynamically:
fields:
dynamicField:
type: "callback"
callback: "App\Service\DynamicFieldLoader::load"
Custom Actions
Create a custom action by extending Dontdrinkandroot\CrudAdminBundle\Action\Action:
namespace App\Action;
use Dontdrinkandroot\CrudAdminBundle\Action\Action;
class CustomAction extends Action {
public function execute() {
// Custom logic
return $this->redirectToRoute('admin_product_index');
}
}
Register in YAML:
actions:
custom: App\Action\CustomAction
Priority Order
Doctrine vs. Custom Repositories
The bundle defaults to Doctrine’s EntityRepository. For custom repos:
repository:
class: App\Repository\CustomProductRepository
Translation Use Symfony’s translation system for labels:
fields:
name:
label: "crud_admin.product.name"
Define translations in translations/messages.en.yaml:
crud_admin:
product:
name: "Product Name (Translated)"
How can I help you explore Laravel packages today?