Sage: Displaying images in assets / images folder

I’m not sure how http://example.dev/assets/images/image.jpg would work if that image is in your theme.

Regarding the watch error… not sure but I started over with a fresh setup of Sage and it’s working now.

Is it just me, or when you build production, the images get random numbers appended to them, making the url dynamic at the point of building so swapping to /dist/ doesn’t really fix the issue?

This thread is two years old and as a result is referencing a previous version of Sage. The most recent version of Sage, version 9, appends a hash to assets as you’ve mentioned. Previous versions did not.

The relevant part of the docs for Sage 9 can be found here: https://github.com/roots/docs/blob/sage-9/sage/theme-development-and-building.md#images-in-template-files.

In summary, you use:

<img src="@asset('images/example.jpg')">

This will ensure the referenced assets get the hash appended within your templates.

16 Likes

What if you want to use the image assets inside CSS? @nathobson

If I’m using an SVG for a background image, will it still register the hash in CSS?

What have you tried? Please don’t ask just to ask, please try :slight_smile:

1 Like

SVG images will get the hash on build if used as background images in CSS.

Also, it confused me for a little while how to get the hash for SVGs used inside PHP. The trick is to use the asset_path() function like so:

<img src="<?= asset_path("images/image.svg"); ?>">

1 Like

Thanks, works perfectly.

Should asset_path() be available in Sage 9? don’t see it anywhere …

Hey @trainoasis - check helpers.php. :wink:

1 Like

Indeed, ty, but somehow not callable in front-page.php? (function does not exist). I guess I’m doing something wrong? :slight_smile:

Quite possibly! Can’t say without your code, but my guess is that you aren’t referencing the right namespace.

Default new Sage install, not referencing anything, am on front-page.php, just calling {{ asset_path() }}. But same happens on other pages :slight_smile:

Sounds like you’re actually in front-page.blade.php?

In your Blade templates, use the @asset directive instead of calling asset_path().

Check out the docs here: https://roots.io/sage/docs/theme-development-and-building/#images-in-template-files

BTW the docs have a new search field in the sidebar powered by Algolia, so finding references to things like this is much quicker now–definitely encourage everyone to take advantage of it!

2 Likes

Nice!! Never used this before, awesome :slight_smile: Will check the new search as well, thank you.

1 Like

Related to asset_path(), that’s why I did not open a new ticket: is there an option to check for file existence first? Similar to @includeif directive for example?

The use case is, we have certain video files that we put in a theme location and they are based on language, say video_en.mp4, video_es.mp4, video_fr.mp4 and so on …

What I’d like to do is check for file existence and use default EN language file if the file does not exists.
I tried with PHP’s file_exists() but it returns false when I pass in my asset_path().

Thanks for any tips

Not as part of asset_path() no, I don’t believe so. You can check out the code behind it right here: https://github.com/roots/sage-lib/blob/master/Assets/JsonManifest.php

I’ve never needed to determine existence of an asset, but I have needed to get the absolute path (i.e. for embedding SVGs), and I used the following technique:

// in /theme/config/assets.php add the following to the array:

'path' => get_theme_file_path().'/dist',

// in `app/helpers.php` add the following:

/**
 * Get the absolute path to an asset.
 *
 * @param string $asset
 * @return string
 */
function locate_asset($asset)
{
    return trailingslashit(config('assets.path')) . sage('assets')->get($asset);
}

// Now you can do something like this:

/**
 * Determine if asset exists.
 *
 * @param string $asset
 * @return bool
 */
function asset_exists($asset)
{
    return file_exists(locate_asset($asset));
}
2 Likes

thanks @alwaysblank :hugs: Unfortunately my file_exists still returns false every time even though the path is okay (using assets.uri instead of .path, probably Sage 9 difference…).

I needed to pass local path without the domain to file_exists …

So what works is:

Add to app/config/assets.php:

'relative_path' => get_theme_file_path().'/dist'

then use where you need to check for file existence (say, in one of the controllers):

$path = config('assets.relative_path') . '/videos/video_'.ICL_LANGUAGE_CODE.'.mp4';
if(file_exists($path)) {
    return asset_path('videos/video_'.ICL_LANGUAGE_CODE.'.mp4');
}  
// here return a default video for example that you know exists for sure