yurba / cmf
YurbaCMF: a lightweight, dependency-free auto-CRUD content management framework for Laravel. Plain Blade and vanilla CSS, no front-end build step.
Requires
- php: ^8.2
- illuminate/console: ^11.0|^12.0
- illuminate/database: ^11.0|^12.0
- illuminate/filesystem: ^11.0|^12.0
- illuminate/http: ^11.0|^12.0
- illuminate/routing: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
- illuminate/validation: ^11.0|^12.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A lightweight, dependency-free auto-CRUD admin panel and content framework for Laravel. The whole interface is plain Blade and vanilla CSS - no front-end build step and nothing extra to compile. Declare a model and its fields, and the panel generates the list, forms, validation and persistence.
Features
- Auto-CRUD: list / create / edit / show / delete from a resource class
- 17 field types, form tabs & sections, conditional fields, validation rules
- List filters, global search, sortable/searchable columns, CSV import/export
- Media library + picker, dependency-free image optimisation (GD) + on-demand thumbnails
- Revisions/versioning, scheduled publishing + signed draft preview
- SEO meta fields (polymorphic) + public XML sitemap (single or multi-file index)
- URL redirect manager with global middleware
- Per-resource, per-action authorization (Laravel policies) + soft-delete trash
- Translatable content: per-locale model fields (
->translatable()) in a translations table - Translatable panel interface (English built in, Russian & Ukrainian bundled)
- Built-in dashboard, settings pages, and generator commands
Requirements
- PHP 8.2+
- Laravel 11+
- GD extension (for image optimisation; without it, uploads are stored as-is)
Install
composer require yurba/cmf php artisan yurba:install # publishes config + assets, creates app/Admin php artisan migrate # media, revisions, seo, redirects, content, translations, optimization-log tables
Gate who may enter the panel (any truthy check) in a service provider:
use Yurba\Cmf\Facades\Yurba; Yurba::authorizeUsing(fn ($user) => $user->is_admin);
The panel lives at /admin (change the prefix in config/yurba.php).
Updating
composer update yurba/cmf php artisan vendor:publish --tag=yurba-assets --force php artisan migrate
Refresh with the yurba-assets tag, not yurba:install --force: the latter also overwrites your config/yurba.php.
Deploy scripts
scripts/ holds two shell scripts that do this on a server. Copy them next to artisan (they work from their own folder, so they can't run from vendor):
cp vendor/yurba/cmf/scripts/*.sh .
| Script | What it does |
|---|---|
deploy.sh |
Applies the code as it is: composer install --no-dev from composer.lock, package discovery, vendor:publish --tag=yurba-assets --force, migrate --force, optimize and storage:link. Run it after every deploy. |
update-cmf.sh |
Updates yurba/cmf to the newest release your composer.json allows, then runs deploy.sh. It also removes an old local copy in packages/yurba-cmf, left by sites that used a path repository. |
sh update-cmf.sh # a new YurbaCMF release sh deploy.sh # anything else
Both use php composer.phar when it sits in the project, composer otherwise, and stop at the first failing step.
Define a resource
namespace App\Admin; use App\Models\Post; use Yurba\Cmf\Fields\Text; use Yurba\Cmf\Fields\Editor; use Yurba\Cmf\Fields\Slug; use Yurba\Cmf\Resources\Resource; class PostResource extends Resource { public static string $model = Post::class; public function fields(): array { return [ Text::make('title')->searchable()->sortable()->rules('required|string|max:255'), Slug::make('slug')->baseUrl(url('/blog')), Editor::make('body')->onlyOnForm(), ]; } }
Register it in config/yurba.php under resources (or scaffold with php artisan yurba:resource Post --from-schema --register).
Icons of your own
Every icon the panel draws can be your own HTML (an inline <svg>, an icon font of the site); the ones left out stay Material Symbols:
// config/yurba.php 'ui' => [ // the panel's icons, by the Material Symbols name they replace 'icon_html' => ['edit' => '<svg viewBox="0 0 24 24" width="20" height="20">…</svg>'], // YurbaPV's icons: left, right, close, zoom, zoomOut, rotate, download 'viewer_icons' => [], ], 'editor' => [ // YurbaEditor's icons, by its own keys 'icons' => [], ],
A row action's icon and a resource's icon() take HTML too, and Yurba::icon('edit') draws an icon the same way in your own views.
Translatable content
Add the HasTranslations trait to a model and mark any field ->translatable(). The form shows a language bar and stores per-locale values in yurba_translations (the base row keeps the default locale); read the current-locale value with $model->tr('field'), which falls back to the base. Enable languages and pick the default in config/yurba.php → multilang.
use Yurba\Cmf\Translations\HasTranslations; class Post extends Model { use HasTranslations; } // in the resource Text::make('title')->translatable(); // on the frontend $post->tr('title');
See the documentation for the full field reference, filters, actions, revisions, SEO, media, authorization and configuration.