Netlify + Decap CMS: Iterating over images array

Continuing the discussion from Image Processing in a Range:

Hi there,

After long search in docs and trying different options I tries this solutions by @jmooring however this also throw error:

at <$.Resources.GetMatch>: error calling GetMatch: unable to cast []interface {}{"/images/properties/gggg.jpg"} of type []interface {} to string

I use this simple code which works perfectly fine

{{ $coverImageget := resources.Get .Params.coverImage }}
{{ $coverImage := $coverImageget.Resize "1080x" }}
 {
   src: '{{ $coverImage.RelPermalink | absURL }}',
},

But for minor change where I use range I cannot make it work, there is 1 error after another. Why does this not work? what is other way where I can range and generate a $somename so I can use it to $somenamet.Resize etc. where did I go wrong in the below code?

{{ range .Params.images }}
{{ with $.Resources.GetMatch . }}
{{ with .Resize "500x " }}
 {
  src: '{{ .RelPermalink | absURL }}',
 },
{{ end }}
{{ end }}
{{ end }}

Thanks

Hard to say without seeing the entire project, but I suspect your front matter is fouled up.

1 Like

Hi @jmooring

I made a brand new repo to see if the issue is project related but it is still there. Here I make a minimal repo to show the issue. Also available on we transfer for direct download.

Thanks for taking the time to read and help.

https://github.com/tocih50254/image-range-error.git

404 page not found

1 Like

Apologies @jmooring , my account was hidden the repo is now publicly available. Thank you for taking the time

You have this in your frontmatter:

images:
  - - images/cats/ludemeula-fernandes.jpg
  - - images/cats/manja-vitolic.jpg
  - - images/cats/michael-sum.jpg
  - - images/cats/mikhail-vasilyev.jpg
  - - images/cats/pacto-visual.jpg

what is that supposed to mean/do? If images is an array of strings (“images/cats/…”, “images/cats/…”), there must be only one leading dash. What you’re writing is an an array called images, whose first element is an empty array called array containing only one element, namely images/cats/luderneula-fernandes.jpg. That makes no sense at all. very little sense.

Hello @chrillek

I’m uncertain about the validity of your claim,

I’ve structured the frontmatter in this particular way out of necessity. While I can successfully retrieve the list of items, there could be potential limitations that I’m unaware of. It’s important to note that this format is not by my choice, but rather how Netlify CMS inserts these values into the frontmatter, and I’m not sure to the reasons behind it.

For your reference, here’s a repository that contains the frontmatter in the format that’s currently being used, and it appears to successfully generate a list from the frontmatter.

Thank you

So, your problem is solved now?

Hi @chrillek

No! My issue is regarding a solution that @jmooring provided few time ago to someone else which when I try is not working for me.

Here is a repo which produce the error check line 17 in layouts/index.html

Thanks

What makes you think than that your front matter is ok although your code very obviously stumbles upon it? You do a $.GetResources ., which throws an error because dot at that point is an array. I explained that already.
Check by adding {{warnf "%#v" .}} before the GetResource call. You’ll see something like this:
[]interface {}{"images/cats/ludemeula-fernandes.jpg"}
which indicates a slice containing a single string.
If you can’t change your frontmatter, change your code to access the first element of this map instead of dot.

Hi @chrillek

Is it working for you if you use "- " single dash?

Thanks

Your code is then working ok, of course. In that it doesn’t throw an error in Hugo and the home page shows a single cat. That is, btw, not related to me doing it – it’s just as it should be.

You have two choices:

  • Leave your front matter as it is and change the parameter of $.GetResources
  • Change your front matter to specify only an array instead an array of arrays and leave your code as it is.

Everything is, btw, working as designed.

Hi @chrillek

The nearest to single dash I can achieve is this

images:
  - image: images/cats/ludemeula-fernandes.jpg
  - image: images/cats/manja-vitolic.jpg

will this work in Hugo?

Thanks

If you use the right code, you can make it work in Hugo. Ask yourself what kind of data structure you’re defining in the front matter (and use warnf "%#v" . to verify). And then ask yourself how to get at those parts of the data structure that you need.

Or read up about page bundles and perhaps use those. Or drop a CMS that butchers your front matter. It’s really an uphill battle you’re fighting here, uselessly it seems to me.

Hi @chrillek

Netlify CMS (Decap CMS) is one of the main cms which works fine with Hugo.

There must be a work around this in Hugo most of the time I am missing an $ or something like this to make something work. since this is a list of list can’t I just tell Hugo to range .Params.images and get the list item of the empty list?

Thanks


Even if I use the single “-” dash the suggested code is not working and does not output images

I’ve already explained how to do that twice. The third explanation would just be the same: access the first element of the dot, as that’s an array (slice in Hugo parlance) in your case.

Out of curiosity I stood up a quick test site, hosted by Netlify and using Decap CMS (formerly Netlify CMS).

Repo: https://github.com/jmooring/hosting-netlify-decap-cms
Live site: https://hosting-netlify-decap-cms.netlify.app/

And from what I can tell from the documentation, the allow_multiple option (default is true) on the image widget is only relevant when using an external media library.

Using the native/built-in image storage mechanism, you have to do something like this in your Decap CMS configuration file:

- label: Images
  name: images
  widget: list
  fields:
    - {name: path, label: Image, widget: image}
    - {name: alt, label: Alt, widget: string}

Which is actually pretty slick, allowing you to add things like alt, id, title, and class attributes to an img element, or a caption if you wanted to render figure elements instead, etc.

Decap CMS produces a content file like this:

title: Kittens
date: 2023-09-16T19:22:36.024Z
tags: 
  - kittens
  - cats
  - cute
images:
  - path: images/uploads/a.jpg
    alt: A kitten
  - path: images/uploads/b.jpg
    alt: Another kitten
  - path: images/uploads/c.jpg
    alt: Yet another kitten

And then you can render all of the images with:

{{ range .Params.images }}
  {{ $alt := or .alt "" }}
  {{ with resources.Get .path }}
    {{ with .Resize "200x webp" }}
      <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $alt }}">
    {{ end }}
  {{ end }}
{{ end }}

This in another example of coding defensively. If the images parameter is not present in front matter, the code is skipped (range over nothing does nothing). If the path key is not present (unlikely in this setup) the code is skipped. And if the alt key isn’t present we explicity set it to an empty string.

Visit the repo (link above) to see the entire Decap CMS configuration file. Other than the list widget for images, I just copied and pasted from their examples.

3 Likes

Thank you @jmooring

That was a quality solution!

I replaced the existing code with your example and I was able to make it work.

# older format static/admin/config.yaml
- { 
     label: Images
     name: images
     widget: list
     required: false
     field: {label: Image, name: image, choose_url: false, widget: image}
}

Thanks a lot for taking the time to provide solution.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.