warpig's avatar
Level 12

ternary operator between Storage::url('path/to/image') and asset('path/to/image')

sometimes i insert data through the seeder or organically (clicking upload button)

i want to place a ternary operator depending on the occasion.

the lines below work, but is there a cleaner way?

@if (Storage::disk('public')->exists($post->image))
			<img src="{{ Storage::url($post->image)  }}"/>
			@else
						<img src="{{ asset($post->image)  }}"/>
			@endif

PostFactory.php

return [
            ...
            'image' => fake()->imageUrl(),
			...
        ];

PostController

        if($request->hasFile('image')) {
            $image = Storage::disk('public')->put('images', $request->file('image'));
        }

I tried using a ternary operator but what am i not doing correctly? depending on what i place after $post->image will be displayed. for, example this would only return the organically saved image and never will it show the thumbnail url from the faker library.

<img src="{{ $post->image ? Storage::url($post->image) : asset($post->image)}}"/>

i asked Lary what to do and said to do this but nothing gets displayed either.

<img src="{{ Str::startsWith($post->image, 'storage/') ? Storage::url($post->image) : asset($post->image) }}" />

this way, the first thing to be placed after $post->image, will be shown:

<img src="@if(isset($post->image)) {{ Storage::url($post->image) }} @else {{ asset($post->image) }} @endif" alt="">
0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

It seems like you're trying to determine the correct URL for an image based on whether it's stored locally or via a public disk. Your ternary operator approach is correct in concept, but it needs a slight adjustment to properly check the existence of the file in the storage.

Here's a cleaner way to handle this using a ternary operator directly within the Blade template. This approach checks if the image exists in the public disk, and if not, it falls back to using the asset() helper. This is assuming that images not in the public disk are accessible directly via the public/ directory.

<img src="{{ Storage::disk('public')->exists($post->image) ? Storage::url($post->image) : asset($post->image) }}" alt="Post Image">

This single line replaces the @if directive block and is more concise. Here’s what it does:

  1. Storage::disk('public')->exists($post->image): This checks if the image exists in the public disk.
  2. Storage::url($post->image): If the image exists, this method generates a URL for it.
  3. asset($post->image): If the image does not exist in the public storage, the asset() helper generates a URL assuming the image is in the public directory.

Make sure that the paths stored in $post->image are relative to the storage disk's root for Storage::url() and to the public directory for asset(). This solution assumes that your images are either stored in the storage/app/public directory (and thus accessible via the public/storage symlink) or directly in the public directory.

gych's avatar

Do you have symlink between your storage public disk and public/storage folder?

If you save the uploaded images in the DB with /storage/ at the beginning of the image path you should be able to use this for both uploaded and seeded images:

<img src="{{ $post->image }}" />

Please or to participate in this conversation.