bugo / moonshine-title-with-slug
Title + slug field for MoonShine with auto-slug generation, live permalink preview, and inline editing.
Package info
github.com/dragomano/moonshine-title-with-slug
pkg:composer/bugo/moonshine-title-with-slug
0.1
2026-04-22 04:15 UTC
Requires
- php: ^8.2
- moonshine/moonshine: ^4.0
Requires (Dev)
- laravel/pint: ^1.29
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
- rector/rector: ^2.4
Conflicts
- moonshine/moonshine: <4.0
README
This package adds a title + permalink field group for MoonShine 4.
Features
TitleSlug::make(...)helper for building a title + slug fieldsetSlugfield with permalink preview- automatic slug generation from title
- manual slug editing with edit/reset/cancel controls
- auto-slug stops after manual slug editing
- create/edit context detection from the current model
- optional visit link with custom label or custom route URL
- configurable host/path visibility in permalink preview
- configurable title and slug labels
- configurable slug postfix
- custom slugifier callback
titleAfterStateUpdatedandslugAfterStateUpdatedcallbacks- custom title field wrapper callback
- package config with default title field, slug field, and host
- translations and publishable assets/config
Installation
composer require bugo/moonshine-title-with-slug
Optionally publish config and assets:
php artisan vendor:publish --tag=moonshine-title-with-slug-config php artisan vendor:publish --tag=moonshine-title-with-slug-assets
Basic usage
use Bugo\MoonShine\TitleWithSlug\TitleSlug; TitleSlug::make( titleColumn: 'custom_title', slugColumn: 'custom_slug', );
Example options
TitleSlug::make( titleColumn: 'custom_title', slugColumn: 'custom_slug', ) ->titleOptions(label: 'Title') ->slugOptions( label: 'Permalink', labelPostfix: '.html', ) ->urlOptions( path: '/posts/', hostVisible: false, visitLinkLabel: 'Open', );
Validation
Use MoonShine page validation rules for server-side checks.
use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Stringable; use Illuminate\Validation\Rule; use MoonShine\Contracts\Core\TypeCasts\DataWrapperContract; protected function rules(DataWrapperContract $item): array { return [ 'title' => ['required'], 'slug' => [ 'required', 'regex:/^[a-z-]+$/', Rule::unique($item->getOriginal()::class, 'slug') ->ignoreModel($item->getOriginal()), ], ]; }