dejwcake/admin-ui
dejwcake/admin-ui is a Laravel package offering reusable admin UI components, layouts, and styling for quickly building dashboards and management screens with Blade. It provides ready-to-use views and configuration-friendly navigation to streamline admin interface development.
composer require <vendor>/<package> and confirm the service provider is auto-discovered (or register it manually in bootstrap/providers.php for Laravel 11+). As of 2.4.0 this pulls intervention/image-laravel ^4.1.1.ImageManager, ->read(, ->gd(, ->imagick(, app('image'), image container binding, and blendingColor.lang/ or resources/lang/) and its service provider's loadTranslationsFrom() / loadViewsFrom() calls. admin.btn.show and admin.btn.back tell you the package renders admin UI chrome through translation keys rather than hardcoded strings — that directory is your customization surface.php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider" --tag=lang (or the config/views tags). If you publish image config, publish to config/intervention-image.php — a legacy config/image.php is still read as a fallback but blendingColor in it is now ignored.lang/vendor/<package>/en/admin.php, mirror only the keys you want to change:
return [
'btn' => [
'show' => 'View details',
'back' => 'Return to list',
],
];
Laravel merges this over the vendor file, so untouched keys keep the package defaults.testbench.yaml: vendor/bin/testbench serve boots a throwaway Laravel app with the package installed.Translation overrides as the primary customization layer. The admin.btn.show / admin.btn.back keys follow the flat-file convention (admin.php containing a btn array), not the nested-directory convention (admin/btn.php). Match whichever the package ships — mismatched structure means your override silently fails to merge rather than throwing an error.
Per-locale overrides. Add lang/vendor/<package>/fr/admin.php alongside the English file and set app.locale. Because Laravel falls back to fallback_locale per-key, a partially translated file is safe: missing French keys render English instead of the raw key string.
Views referencing these keys. If you publish Blade views, keep using {{ __('admin.btn.show') }} rather than inlining copy — that preserves the override path for other developers and for future locales. If you need to swap the button component entirely, publish the button partial and keep the translation call inside it.
Testing against the new keys. With Testbench available, assert on rendered output rather than raw keys:
$this->get('/admin/users/1')
->assertSee(__('admin.btn.show'));
This keeps the test passing when you change the label in a lang file, and fails loudly if a view starts echoing the key literally.
Constructing the image manager in your own code. Since 2.4.0 the image container binding is gone; use intervention.image, or better, inject the interface:
use Intervention\Image\ImageManagerInterface;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;
public function __construct(private ImageManagerInterface $images) {}
// or, in tests / standalone:
$manager = new ImageManager(Driver::class); // was ImageManager::gd()
$image = $manager->decodePath($path); // was $manager->read($path)
$image = $manager->decodeBinary($bytes); // was read() with raw data
The package's own WYSIWYG upload path now uses decodePath() internally, so uploads keep working without your intervention — this is only your work if you wrote image handling yourself.
Config layering. config/intervention-image.php is now the source of truth. A published config/image.php is still read as a fallback for backward compatibility, but blendingColor has been renamed to backgroundColor and the old key is ignored. If you tuned compositing, move the value across; don't keep editing config/image.php for new settings.
CI parity. The package tests against MariaDB 12.3. If you run MySQL 8 locally and MariaDB in production, mirror the CI service definition in your own pipeline — MariaDB differences (JSON handling, ONLY_FULL_GROUP_BY defaults, index prefix limits) are exactly the class of bug that passes locally and fails in prod.
^2.3 will silently pull 2.4.0. This release is minor-versioned but bumps intervention/image-laravel from ^1.5.7 to ^4.1.1, which is a breaking change for anyone using the old Intervention API. Either do the migration or pin "<vendor>/<package>": "2.3.*". Do not assume composer update is safe here — the previous advice that ^2.3 was "appropriate" no longer applies without this caveat.php artisan optimize:clear (or lang:cache re-run under config:cache) — cached translations are the single most common reason a label change "doesn't work." This bites hardest in deployed environments where the cache is warm.image → intervention.image binding rename fails at runtime, not compile time. Any app('image'), container-tagged mock, or $this->app->bind('image', ...) in a test will throw or, worse, resolve something unexpected. Prefer injecting ImageManagerInterface so the binding name stops mattering.blendingColor is dropped without a warning. Compositing output will differ (default background instead of your blend colour) and nothing errors. Move it to backgroundColor in config/intervention-image.php and diff a rendered image before/after.read() splitting into decode() / decodePath() / decodeBinary() is a real behavioural change. Passing a SplFileInfo or string path to decode() may not do what the old read() did — use decodePath() for paths. Check any custom upload, thumbnail, or crop pipeline.vendor/. Patches to vendor lang or config files vanish on the next composer update; the override directory survives. Treat a needed vendor edit as a signal to publish or open an upstream PR.admin.btn.shows renders literally in the UI instead of erroring. If you're heavily overriding, add a smoke test that asserts the literal key isn't present on admin pages.__('admin.btn.show') and __('<package>::admin.btn.show') resolve from different loaders. If translations are loaded with loadTranslationsFrom(), the :: form is required; if the package merges into the app's lang/ directory, it isn't. Check the provider before writing overrides.vendor:publish --force on the config tag now lands you intervention-image.php; if you have a hand-maintained config/image.php, it will keep being read as a fallback and quietly diverge. Consolidate rather than running two configs side by side.config/<package>.php before reaching for CSS or a view override.ONLY_FULL_GROUP_BY and utf8mb4 index-length limits are the usual offenders.How can I help you explore Laravel packages today?