HUGO

How to get the path to the assets directory without hardcoding?

In a shortcode for image processing responsive images from page resources (bundels) I retrive some file information about the original soure. Therefore I use the following variables in my shortcode:

{{ $image := .Page.Resources.GetMatch (.Get "src") }}

{{ $file := path.Join (path.Dir .Page.File.Path) $image }}
{{ $stat := os.Stat $file }}

This works well and I can display some file information, e.g. the file size ( {{div (int $stat.Size) 1024 }} KB).

But I would like to provide also another shortcode for images, which are stored in the default assets folder (/assets). I use the following variables in this shortcode:

{{ $image := resources.Get (.Get "src") }}

{{ $file := path.Join ("assets") $image }}
{{ $stat := os.Stat $file }}

This works, but is there an alternative (better) solution to retrive the assets file path without hardcoding the assets directory? The os.Stat function needs this path information.

I’m relative new to Hugo but I didn’t finde any informations about that topic in the documentation or in the community forum here. I’m gratefull for any suggestions.

The assets folder is for pipes, not for anything template related. Think of it as something that is processed outside of the design part of your Hugo site. Files (and paths) that are used in templates have to be created by the content structure or be within the static directory.

Thanks for your answer.

I know the basic difference between assets for pipes and page resources resp. page bundles for content organisation. The problem is, that the static folder doesn’t support image processing, e.g. for responsive images.

“The image is a Page Resource, and the processing methods listed below do not work on images inside your /static folder.” (see: https://gohugo.io/content-management/image-processing/)

And I would like to have the choice between page bundle organisation and a centralized image directory for all posts or pages. The centralized approach is in some cases better than the decentral organisation in page bundles, in my opinion.

For images as part of page bundles I use the following shortcode to generate responsive images:

{{ $altText := .Get "alt"}}
{{ $caption := .Get "caption"}}
{{ $linkTitle := .Get "link-title"}}
{{ $image := .Page.Resources.GetMatch (.Get "src") }}

{{ $file := path.Join (path.Dir .Page.File.Path) $image }}
{{ $stat := os.Stat $file }}

{{ with $image }}
{{ with $caption }}
<figure>
{{ end }}
    <a href="{{.RelPermalink}}" {{ with $linkTitle }} title="{{ $linkTitle }} ({{ $stat.Name }}, {{ $image.Width }} x {{ $image.Height }} px, {{div (int $stat.Size) 1024 }} KB)" {{ end }} target="_blank">
        <img
            srcset="
            {{ if ge $image.Width 320 }}
                {{ (.Resize "320x").RelPermalink }} 320w,
            {{ end }} 
            {{ if ge $image.Width 430 }}
                {{ (.Resize "430x").RelPermalink }} 430w,
            {{ end }}
            {{ if ge $image.Width 860 }}
                {{ (.Resize "860x").RelPermalink }} 860w,
            {{ end }}
            {{ if ge $image.Width 1720 }}
                {{ (.Resize "1720x").RelPermalink }} 1720w
            {{ end }}"           
            sizes="(max-width: 900px) calc(100vw - 4rem), 860px"
            src="
            {{ if ge $image.Width 1720 }} 
                {{ (.Resize "860x").RelPermalink }}
            {{ end }} 
            " alt="{{$altText}}"/>
    </a>
    {{ with $caption }}
    <figcaption>{{ $caption }}</figcaption>
    </figure>
    {{ end }}
{{ end }} 

(Example for using the shorcode above: {{< responsive-image src="kuchen-2000.jpg" alt="Gugelhupf" caption="Gugenhupf" link-title="Originalbild in neuem Fenster öffnen" >}})

An almost similar solution works also for images in the assets folder. But my question was, whether it is possible to avoid hardcoding the assets folder, see the line {{ $file := path.Join ("assets") $image }} in the following shortcode:

{{ $altText := .Get "alt"}}
{{ $caption := .Get "caption"}}
{{ $linkTitle := .Get "link-title"}}
{{ $image := resources.Get (.Get "src") }}


{{ $file := path.Join ("assets") $image }}
{{ $stat := os.Stat $file }}

{{ with $image }}
{{ with $caption }}
<figure>
{{ end }}
    <a href="{{.RelPermalink}}" {{ with $linkTitle }} title="{{ $linkTitle }} ({{ $stat.Name }}, {{ $image.Width }} x {{ $image.Height }} px, {{div (int $stat.Size) 1024 }} KB)" {{ end }} target="_blank">
        <img
            srcset="
            {{ if ge $image.Width 320 }}
                {{ (.Resize "320x").RelPermalink }} 320w,
            {{ end }} 
            {{ if ge $image.Width 430 }}
                {{ (.Resize "430x").RelPermalink }} 430w,
            {{ end }}
            {{ if ge $image.Width 860 }}
                {{ (.Resize "860x").RelPermalink }} 860w,
            {{ end }}
            {{ if ge $image.Width 1720 }}
                {{ (.Resize "1720x").RelPermalink }} 1720w
            {{ end }}"           
            sizes="(max-width: 900px) calc(100vw - 4rem), 860px"
            src="
            {{ if ge $image.Width 1720 }} 
                {{ (.Resize "860x").RelPermalink }}
            {{ end }} 
            " alt="{{$altText}}"/>
    </a>
    {{ with $caption }}
    <figcaption>{{ $caption }}</figcaption>
    </figure>
    {{ end }}
{{ end }} 

Worth reading about responsive images and Hugo are the following blog posts:

  • Kalbag, Laura (2018): Processing Responsive Images with Hugo
  • Ott, Thomas (2020): Responsive Images in Hugo
  • Wills, Adam: Responsive Images in Hugo
  • Haukås, Nils Norman (2018): Hugo: How to add support for responsive images trough image processing and page bundles

My shortcodes for responsive images are inspired by this theme: https://github.com/jcfischer/hugo-chaschper/blob/master/layouts/shortcodes/figure.html - Both shortcodes work, but I thought there is an better solution available instead of hardcoding the /assets Folder, so I can also use the os.Stat function to retreive some file information from images stored in the assets directory. Or with other words: Is there an equivalent to the line {{ $file := path.Join (path.Dir .Page.File.Path) $image }} for the default assets folder?

(PS: As I’m new to the hugo community I can only post two links inside a post, so I could not link the worth reading blog posts … search engines will find them quickly, indeed. )

The path to the assets directory must be hard coded. But if all you need is file size, you can use this instead of os.Stat:

{{ $img := resources.Get "images/a.jpg" }}
{{ $filesize := len $img.Content }}