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
Laravel 8 Export Buttons In Datatables Example
Laravel 8 Export Buttons In Da...

In this article, we will see an example of laravel 8 export buttons in datatables. If you want to export data...

Read More

Oct-14-2020

Laravel 9 Image Upload Example
Laravel 9 Image Upload Example

In this tutorial, I will explain the laravel 9 image upload example. image or file upload is the most common task in web...

Read More

Feb-28-2022

Laravel whereDate and whereDay Example
Laravel whereDate and whereDay...

In this article, we will see laravel whereDate and whereDay examples. As you all know laravel provides many in...

Read More

Jan-21-2021

Vue Js Get Array Of Length Or Object Length
Vue Js Get Array Of Length Or...

In this tutorial, we will see you example of vue js get an array of length or object length. we will learn about vu...

Read More

Jan-07-2022