Installation:
composer require draw/sonata-extra-bundle
Add to config/bundles.php:
return [
// ...
Draw\SonataExtraBundle\DrawSonataExtraBundle::class => ['all' => true],
];
First Use Case:
UserAdmin) to omit the hardcoded entity class in YAML:
# config/packages/sonata_admin.yaml
App\Sonata\Admin\UserAdmin:
arguments: [~, ~, ~] # No need to repeat User::class
Define the default in the constructor:
public function __construct($code, $class = User::class, $baseControllerName = null) {
parent::__construct($code, $class, $baseControllerName);
}
Verify Compiler Pass: Clear cache to trigger the compiler pass:
php bin/console cache:clear
Refactor Existing Admins:
PostAdmin:
App\Sonata\Admin\PostAdmin:
arguments: [~, ~, ~] # No Post::class hardcoded
public function __construct($code, $class = Post::class, $baseControllerName = null) {
parent::__construct($code, $class, $baseControllerName);
}
Order Matters:
sonata_admin extension).// src/DependencyInjection/Compiler/ExtraAdminPass.php
use Draw\SonataExtraBundle\DependencyInjection\Compiler\AdminArgumentPass;
public function process(ContainerBuilder $container) {
$container->addCompilerPass(new AdminArgumentPass());
}
Enable Feature:
Add to config/packages/draw_sonata_extra.yaml:
draw_sonata_extra:
fix_menu_depth: true
Customize Logic: Extend the menu builder to add conditions:
// src/Twig/Extension/SonataMenuExtension.php
public function getMenuDepthFix($menu, $depth = 1) {
if ($depth === 1 && count($menu->getChildren()) === 1) {
return $this->getMenuDepthFix($menu->getChildren()[0], $depth + 1);
}
return $menu;
}
Template Integration: Override Sonata’s base template to use the new menu structure:
{# templates/sonata_admin/layout.html.twig #}
{% block sonata_menu %}
{{ sonata_menu.render('level1', { 'depthFix': true }) }}
{% endblock %}
Extend Default Assets:
Add custom JS/CSS to the extra_javascripts or extra_stylesheets blocks:
{# templates/sonata_admin/layout.html.twig #}
{% block sonata_admin_assets_extra_javascripts %}
{{ parent() }}
<script src="{{ asset('bundles/sonataextra/js/custom.js') }}"></script>
{% endblock %}
Create Custom Template Types:
Register new template types in services.yaml:
sonata.admin.template.type:
sonata_extra_custom:
path: '@DrawSonataExtraBundle/Resources/views/'
context: sonata.admin.template.type.custom
Compiler Pass Timing:
php bin/console debug:container draw_sonata_extra.admin_argument_pass
Menu Depth Overrides:
fix_menu_depth feature only applies to top-level menus (depth = 1).sonata.menu.twig template:
{# templates/sonata_admin/sonata_menu.html.twig #}
{% if menu.children|length == 1 and depth == 1 %}
{{ render_menu(menu.children[0], depth + 1) }}
{% else %}
{{ render_menu(menu, depth) }}
{% endif %}
Template Type Conflicts:
sonata_admin).sonata_extra_custom).Constructor Argument Issues:
php bin/console debug:config draw_sonata_extra
Menu Rendering:
fix_menu_depth temporarily to isolate issues:
draw_sonata_extra:
fix_menu_depth: false
dump():
{{ dump(sonata_menu.menu) }}
Custom Compiler Pass:
Extend the AdminArgumentPass to support additional logic:
// src/DependencyInjection/Compiler/CustomAdminPass.php
use Draw\SonataExtraBundle\DependencyInjection\Compiler\AdminArgumentPass;
class CustomAdminPass extends AdminArgumentPass {
protected function getDefaultArgument($reflection, $argument) {
// Custom logic here
return parent::getDefaultArgument($reflection, $argument);
}
}
Dynamic Menu Depth: Add a dynamic condition to the menu fix:
draw_sonata_extra:
fix_menu_depth:
enabled: true
exclude_routes: ['sonata_admin_dashboard']
Asset Management: Override the asset block to conditionally load resources:
{% block sonata_admin_assets_extra_javascripts %}
{% if app.user.isGranted('ROLE_SUPER_ADMIN') %}
{{ parent() }}
{% endif %}
{% endblock %}
How can I help you explore Laravel packages today?