sbs/symfony-adminlte-bundle
A Symfony bundle that integrates the AdminLTE admin template into Symfony applications, providing ready-to-use layouts, UI components, and assets to quickly build responsive dashboards and back-office interfaces with minimal setup.
This is a Symfony bundle, not a Laravel package. There is no service provider, no config/adminlte.php, and no Blade views in the box. If you're coming from a Laravel codebase, the realistic "getting started" is deciding whether you want to port the Twig views into Blade (they're just HTML chrome around {% block %}) or ignore the package and pull AdminLTE's static theme directly. For a genuine Symfony app, the flow is short:
composer require sbs/symfony-adminlte-bundle — expect to pin or downgrade Symfony/PHP constraints, because the archived repo predates Symfony 6/7.new Sbs\AdminLTEBundle\SbsAdminLTEBundle() in AppKernel.php (Symfony 3/4) or config/bundles.php (Symfony 4/5).bin/console assets:install public --symlink (use plain copy or --relative where symlinks break in Docker/CI).Resources/views/ before the README. The layout, partials, and menu templates are the actual contract — they tell you which blocks exist and what's overridable, which is more than the docs do.{# templates/dashboard/index.html.twig #}
{% extends '@SbsAdminLTE/layout.html.twig' %}
{% block page_title %}Dashboard{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-3">
{{ include('@SbsAdminLTE/Widgets/small-box.html.twig', {
title: 'Users', value: userCount, icon: 'users', color: 'bg-aqua'
}) }}
</div>
</div>
{% endblock %}
Verify the shell renders cleanly before wiring menus and widgets. Most problems at this stage are asset path issues, not template logic.
One intermediate base template. The bundle's whole value is a base layout with blocks (content, page_title, breadcrumb, stylesheets, javascripts, plus sidebar/navbar slots). Don't extend the vendor layout from every page. Create templates/base_admin.html.twig that extends @SbsAdminLTE/layout.html.twig once, and have all app templates extend that. You get a single place to swap in your own nav, auth-aware sidebar, and asset tags without touching bundle internals — and a single file to change when you eventually replace the bundle.
Menus. AdminLTE's sidebar is where people burn time. Depending on bundle version this is either a YAML tree (label / route / icon / children) or a menu-builder service. Prefer the builder when it exists: active-state highlighting and role-filtered items are painful in static YAML because you can't see the current route or the current user. If it's YAML-only, build the menu in a Twig extension or a controller-passed array rather than editing bundle YAML in vendor/.
Widgets as parameterised includes. small-box, info-box, box, and timeline partials map to include ... with { ... }. Wrap them in your own macros so a metrics dashboard is a loop over data, not copy-pasted markup:
{% for metric in metrics %}
{{ include('@SbsAdminLTE/Widgets/small-box.html.twig', {
title: metric.label, value: metric.value, icon: metric.icon, color: metric.color
}) }}
{% endfor %}
Forms need a form theme. Symfony forms render inside box-body fine, but unstyled unless you apply Bootstrap/AdminLTE classes. Register a custom form theme wrapping rows in form-group and inputs in form-control. Without it, forms look broken and it's easy to misdiagnose as a bundle bug.
DataTables via the javascripts block. AdminLTE 2.x ships jQuery DataTables integration. Your <table> either needs the data-table convention the bundle expects, or an explicit $('#id').DataTable() init appended to the javascripts block. Put page-specific JS there rather than inline in content — it keeps the include order after jQuery/AdminLTE scripts.
Asset strategy: treat bundled CSS/JS as a starting point. These bundles typically vendor circa-2016 AdminLTE 2.x, Bootstrap 3, and jQuery 1.x/2.x. Override the stylesheets / javascripts blocks with your own Encore/Webpack/Vite output as soon as you're past prototyping — that removes your dependence on assets:install behaviour in CI and lets you patch frontend CVEs independently of the PHP package.
Porting to Laravel (the realistic path for a Laravel team). Copy Resources/views/ into resources/views/vendor/adminlte/, then translate mechanically:
| Twig | Blade |
|---|---|
{% extends '@SbsAdminLTE/layout.html.twig' %} |
@extends('vendor.adminlte.layout') |
{% block content %} |
@section('content') |
{% include x with {...} %} |
@include(x, [...]) |
{{ path('route_name') }} |
{{ route('name') }} |
{% if %} / {% for %} |
@if / @foreach |
The HTML structure transfers 1:1 — only templates and routing calls change. Replace the menu builder with a view composer or a config/adminlte.php tree, and put the assets through Vite. This is genuinely a day's work, and it's the only way this package helps a Laravel app.
composer.json constraints before you start, and prefer --dry-run on a branch.@SbsAdminLTE. Overrides go in templates/bundles/SbsAdminLTEBundle/ (Symfony 4+) or app/Resources/SbsAdminLTEBundle/views/ (Symfony 3). If you override by name and nothing changes, the bundle name casing or the path is wrong — bin/console debug:twig shows the resolved paths.assets:install. --symlink is fastest locally and breaks in Docker images built without the source tree. Use copy in deploy pipelines, and add the install step to your build script or assets silently 404 in production only.javascripts, keep the vendor block plus your additions rather than replacing it wholesale; otherwise DataTables and sidebar collapse break with no console error worth reading.app.request.attributes.get('_route') (or the Laravel request()->routeIs() after porting) rather than trusting the bundle's matching.config/packages/twig.yaml for form_themes first.How can I help you explore Laravel packages today?