Using page resources

In a leaf branch I have index.html and myimage.png.
In index.html I have specified myimage.png as a resource:

----
resources:
  - name: myimg
    src: myimage.png
---

How can I use this resource in index.html? What I want to achieve is:

<img src="{{ .GetMatch "myimg" }}">

but this only works from templates, not from the index.html.

Also, myimage.png is not included when generating the static site pages.

You need to use a shortcode. There are posts in this forum about shortcodes that fetch image resources in Page Bundles. Shortcodes can be used in HTML content files.

Welcome to the wonders of Hugo :wink:

I basically copied the recipe from Get image by resource name using images.inline shortcode, posting #3.

Content document:

---
description: September | Images
resources:
  - name: de_kiel1
    src: de_kiel1.png
    title: De Kiel, 29 september 2018
---

{{< image name="de_kiel1" size="600px" >}}

shortcode:

{{ $name := .Get "name" }}
{{ $size := .Get "size" }}
{{ $match := printf "*%s*" $name }}
{{ $img := .Page.Resources.GetMatch $match }}
{{ $img := $img.Resize $size }}

<img 
class="img-fluid"
src="{{ $img.Permalink }}">

Error:

Error: Error building site: "/bulk/tmp/quickstart/content/pictures/index.html:11:1": failed to render shortcode "image": failed to process shortcode: "/bulk/tmp/quickstart/themes/september/layouts/shortcodes/image.html:5:15": execute of template failed: template: shortcodes/image.html:5:15: executing "shortcodes/image.html" at <$img.Resize>: nil pointer evaluating resource.Resource.Resize

I still seem to miss a step…

How is the project’s content organized?

Post the output of the tree command.


A few notes that may be relevant in your case.

Resources are available either through Page Bundles or through the assetsDir.

index.html or md creates a leaf bundles (single page).
_index.html or md is an optional file to enter meta data for branch bundles (list page).

An index.html directly under /content/ would turn the entire content directory into a single page.

Thanks for the explanation. The problem is, indeed, related to the project origanisation.

First, my misconception was to consider resources as a series of key/value pairs. Hugo treats resources as resources, which means that the result of Resource.GetMatch will be null if the resource file cannot actually be found. Makes sense.

Then I was thinking in terms of web sites. Given these files:

content/pictures/index.html
content/pictures/foo.png
static/images/bar.png

I use two resources in content/pictures/index.html

  - name: res1
    src: foo.png
  - name: res2
    src: ../images/bar.png

I expect foo.png to be next to the index.html (it is, it works). Likewise I’d expect bar.png in ../images/bar.png – it is not… it would be served under that name but the actual file is in ../static/images/bar.png. I haven’t figured out how to solve this.

I personally avoid symlinks like the plague but I suppose you could use one for your use case.

OR

You could try setting the assetDir to /static/ and fetch bar.png with the method resources.Get. This method is quite useful when one needs to fetch a resource outside a Page Bundle, the catch is that it needs to reside in the assetDir.

Interesting. I played a bit with assets and resources.Get but now I can’t seem provide additional metadata (e.g., title) with the asset.

The way I would do it would be to store the call to the image
e.g. {{ $img := resources.Get "PATH-to-asset" }}
and then render the associated meta data from the front matter of the page in which the image should be rendered like so:

{{ with $img }}
Title: {{ $.Page.Params.imgTitle }}
{{ end }}

OR

Within the assetDir place the image within a directory and add the metadata in an .md file right next to it and fetch its content with resources.Get again.

I try to understand…

From my example, modified for assets:

content/pictures/index.html
content/pictures/foo.png
assets/images/bar.png

The resources in content/pictures/index.html, now with title:

  - name: res1
    src: foo.png
    title: Foot at its best
  - name: res2
    src: ???
    title: Bar is barred

and typical usage in the same file:

{{< showimage resourcename="res1" }}

How can I get resource res2 associated with assets/images/bar.png?

The front matter you quoted above belongs in the resources table that is meant for Page Resources. assets/images/bar.png is NOT a Page Resource.
It is an asset fetched on demand for use in the Page.

Therefore to render its metadata you would need to enter it in a front matter parameter outside the resources table. Like so:

imgTitle: Bar is barred

And then in the template (shortcode or whatever)

{{ $img := resources.Get "images/bar.png" }}
{{ with $img }}
<img src="$img.Permalink" alt="$.Page.Params.imgTitle">
{{ end }}

Or use whatever naming convention or Permalink variation suits your project.
But you should get the general idea from the above.

Notes
The $ dollar sign and the .Page variable will fetch the front matter parameter from within the context of the $img. This is how one accesses Page parameters from the lower level of a shortcode.

Likewise if imgTitle was entered in the .Params table of the project config it would be accessed with $.Site.Params.imgTitle.

Okay, got that working…

Bottom line: Page resources are page resources only. They must reside next to or below the page itself. No reaching up, even though no error is given when a resource has src: ../images/foo.png.

Final question (for today :wink: ) Given the setup from post #8, when I use resource res1 (which is foo.png) and I use .RelPermalink I would expect foo.png in the generated HTML. However it is generated as /pictures/foo.png. With relativeURLs set in the config it becomes ../pictures/foo.png. Is that intentional?

Yes. As per the Doc

Setting relativeURLs to true in your site configuration will cause Hugo to rewrite all relative URLs to be relative to the current content.

Also note that one can use the .RelPermalink variable to generate a relative URL for a resource, i.e. $img.RelPermalink

ref: Page resources | Hugo

Exactly. But in my book that means that when pictures/index.html refers to foo.png, the relative url is foo.png, not ../pictures/foo.png.

Anyway, no big deal. Thanks for your patience.

This topic was automatically closed after 24 hours. New replies are no longer allowed.