Laravel 11 Spatie Media Library Example

Websolutionstuff | Jul-05-2024 | Categories : Laravel

Hello, laravel web developers! In this article, we'll see how to install spatie media library in laravel 11. Here, we'll use spatie/laravel-medialibrary composer package. Also, you can handle upload with Livewire and vue js in laravel 11.

Additionally, you can crop and resize the image, display a placeholder when the image is missing, sort the image, and display based on the device size.

Laravel 11 Spatie Media Library using spatie/laravel-medialibrary

Laravel 11 Spatie Media Library

 

Image Cropping and Resizing

We'll crop and resize the image using spatie laravel media library. We'll use the fit() method.

Model:

public function registerMediaConversions(Media $media = null): void
{
    $this->addMediaConversion('thumbnail')
        ->fit(Manipulations::FIT_MAX, 250, 250)
        ->nonQueued();
}

Manipulations::FIT_MAX approach ensures that the image adapts to the specified maximum width and height without any cropping.

Manipulations::FIT_CONTAIN: Keeps the whole image within the set size without cutting anything off, keeping its original shape.

Manipulations::FIT_MAX: Resizes the image to fit within the given size without stretching or cutting, keeping its original shape.

Manipulations::FIT_FILL: Resizes the image to fit the given size and fills any extra space with a background color (usually white). The image is not cut or stretched.

Manipulations::FIT_FILL_MAX: Works like FIT_FILL but will make the image bigger if it's smaller than the set size.

Manipulations::FIT_STRETCH: Stretches the image to fill the given size, ignoring the original shape.

Manipulations::FIT_CROP: Resizes the image to the given size and cuts off any extra parts, giving you exact control over the final size.

 

Displaying alt Image When the Main Image is Missing

In this, when the image is not found and the image is missing then it will display the default image.

PostController.php:

public function store(StorePostRequest $request)
{
    $post = Post::create($request->validated());

    if ($request->hasFile('images')) {
        foreach ($request->file('images', []) as $image) {
            $post->addMedia($image)->toMediaCollection();
        }
    } else {
        // Attach a default image
        $post->addMedia(storage_path('defaults/default.png'))
             ->preservingOriginal()
             ->toMediaCollection();
    }

    return redirect()->route('posts.index');
}

Model:

public function registerMediaConversions(Media $media = null): void
{
    $this->addMediaConversion('thumbnail')
         ->fit(Manipulations::FIT_FILL, 200, 200)
         ->nonQueued();
}

public function registerMediaCollections(): void
{
    $this->addMediaCollection('default')
         ->useFallbackUrl(asset('fallback/fallbackImage.png'))
         ->useFallbackUrl(asset('fallback/fallbackImage.png'), 'thumbnail')
         ->useFallbackPath(public_path('fallback/fallbackImage.png'))
         ->useFallbackPath(public_path('fallback/fallbackImage.png'), 'thumbnail');
}

Now, in your view, instead of:

<img src="{{ $post->getFirstMedia()?->getUrl('thumbnail') }}" class="object-contain" alt="{{ $post->title }}"/>

Use:

<img src="{{ $post->getFirstMediaUrl('default', 'thumbnail') }}" class="object-contain" alt="{{ $post->title }}"/>

 

Sort Images

Now, we'll sort the images and rearrange and organize the image collection.

Controller

use Spatie\MediaLibrary\MediaCollections\Models\Media;
//...

public function adjustImageOrder() {
    Media::setNewOrder([3, 2, 1]);
}

posts/show.blade.php

<div class="p-4">
    @foreach($post->getMedia() as $media)
    <div class="flex flex-rows space-x-4">
        <div class="flex flex-col justify-center">
            @if($media->order_column !== $post->getMedia()->min('order_column'))
            <a href="{{ route('posts.shiftImage', [$post, $media, 'up']) }}"
               class="text-blue-500 hover:text-blue-600 underline">Move up</a>
            @endif
            @if($media->order_column !== $post->getMedia()->max('order_column'))
            <a href="{{ route('posts.shiftImage', [$post, $media, 'down']) }}"
               class="text-blue-500 hover:text-blue-600 underline">Move down</a>
            @endif
        </div>
        <div>
            <span>Current position: {{ $media->order_column }}</span>
        </div>
        <div>
            <img src="{{ $media->getUrl('thumbnail') }}" alt="{{ $media->name }}">
        </div>
    </div>
    @endforeach
</div>

web.php

use App\Http\Controllers\PostController;
//...

Route::resource('posts', PostController::class);
Route::get('posts/{post}/shift/{media}/{direction}', [PostController::class, 'shiftImage'])->name('posts.shiftImage');

PostController.php

use Spatie\MediaLibrary\MediaCollections\Models\Media;
//...

public function shiftImage(Post $post, Media $media, string $direction)
{
    $targetMedia = ($direction === 'up') 
        ? $post->media()->where('order_column', '<', $media->order_column)->orderByDesc('order_column')->first() 
        : $post->media()->where('order_column', '>', $media->order_column)->orderBy('order_column')->first();
    list($media->order_column, $targetMedia->order_column) = [$targetMedia->order_column, $media->order_column];
    
    $media->save();
    $targetMedia->save();
    return back();
}

 

Flexible Images Based on Device Size

Now, we'll display flexible images based on the device size using the withResponsiveImages() function.

PostController.php

public function saveImage(StorePostRequest $request) {
    $newPost = Post::create($request->validated());

    foreach ($request->file('images', []) as $img) {
        $newPost->addMedia($img)
            ->withResponsiveImages()  // This magic line creates responsive versions
            ->toMediaCollection();
    }

    return redirect()->route('posts.listing');
}

posts/listing.blade.php:

<img src="{{ $post->getFirstMedia()?->getUrl('thumbnail') }}"
     srcset="{{ implode(', ', $post->getFirstMedia()?->getResponsiveImageUrls()) }}"
     class="object-contain"
     alt="{{ $post->title }}"/>

 


You might also like:

Recommended Post
Featured Post
How to Create Login and Registration in Laravel 11
How to Create Login and Regist...

Hello developers! In this guide, We'll see how to create a login and registration page in laravel 11 using the larav...

Read More

Apr-15-2024

How To Install Yajra Datatable In Laravel 10
How To Install Yajra Datatable...

In this article, we will see how to install datatable in laravel 10. Here, we will learn about the laravel 10 yajra data...

Read More

Mar-01-2023

How To Convert HTML To PDF using JavaScript
How To Convert HTML To PDF usi...

In this example we will see how to convert html to pdf using javaScript. PDF file format is very useful to dow...

Read More

Aug-23-2021

Laravel 11 Unique Validation on Update
Laravel 11 Unique Validation o...

In Laravel 11, when you're updating a resource (like a user or product) in your database, you might want to ensure t...

Read More

Feb-06-2025