visual-ideas/moonshine-spatie-medialibrary
Installation:
composer require visual-ideas/moonshine-spatie-medialibrary
Ensure spatie/laravel-medialibrary is also installed and configured in your Laravel app.
Publish Config (if needed):
php artisan vendor:publish --provider="MoonShine\Providers\MoonShineServiceProvider" --tag="moonshine-config"
Update moonshine.php to include the new field in your fields configuration.
First Use Case: Register the field in a MoonShine resource:
use VisualIdeas\MoonShineSpatieMediaLibrary\Fields\MediaLibrary;
public function fields(): array
{
return [
MediaLibrary::make('Gallery')
->collection('gallery') // Spatie collection name
->disk('public') // Disk where files are stored
->maxFiles(5), // Optional: Limit uploads
];
}
Basic Media Upload:
MediaLibrary::make('Field Name') to create a field tied to a Spatie collection.->maxFiles(3)).Dynamic Collections:
MediaLibrary::make('Avatar')
->collection(fn (Model $model) => $model->avatar_collection)
Nested Media Handling:
MediaLibrary::make('Cover')
->collection('covers')
->model($parentModel) // Explicitly set parent model
Integration with Spatie Events:
MediaStoringEvent or MediaDeletingEvent to trigger custom logic:
use Spatie\MediaLibrary\Events\MediaStoringEvent;
event(new MediaStoringEvent($model, $collection, $path));
Custom Thumbnails:
class CustomMediaLibrary extends MediaLibrary
{
public function thumbnailUrl(): string
{
return $this->model->getFirstMediaUrl('custom_thumbnail');
}
}
Conditional Fields:
MediaLibrary::make('Hero Image')
->visible(fn (Model $model) => $model->is_published)
Bulk Operations:
->multiple() for multi-select uploads (requires Spatie v3+):
MediaLibrary::make('Documents')
->collection('documents')
->multiple()
API-Driven Uploads:
axios.post('/moonshine/api/upload', { file, collection: 'gallery' });
Disk Mismatch:
disk in the field matches the Spatie MediaLibrary config. Defaults to public; verify in config/filesystems.php.Collection Not Found:
$mediaable trait, the field will fail silently. Add:
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Post extends Model implements HasMedia
{
use InteractsWithMedia;
protected $mediaableType = 'posts';
}
Permission Issues:
Media model requires proper storage permissions. Run:
chmod -R 775 storage/app/public
MoonShine Version Lock:
>= v3.0.0 for MoonShine v3).Log Media Events: Add a listener to debug uploads/deletions:
Spatie\MediaLibrary\Events\MediaStoringEvent::class => [
\App\Listeners\LogMediaUpload::class,
],
Check Network Requests:
/moonshine/api/upload-media). Ensure CORS is configured if using a SPA.Validate Collections:
php artisan vendor:publish --tag="spatie-media-library-config" to inspect config/media-library.php for collection names.Custom Validation:
resolveRules() in a custom field class to add rules:
public function resolveRules(): array
{
return [
'required_if:is_featured,true',
];
}
Presets for Thumbnails:
registerMediaConversions to define presets, then reference them in the field:
MediaLibrary::make('Profile Pic')
->preset('avatar') // Uses a registered conversion
Localization:
'moonshine' => [
'fields' => [
'media_library' => [
'labels' => [
'en' => 'Media Library',
'ru' => 'Медиабиблиотека',
],
],
],
],
Custom UI Components:
view method:
public function view(): string
{
return 'moonshine-spatie-medialibrary::custom-upload';
}
How can I help you explore Laravel packages today?