Keeping order from frontmatter, not config

Hi All,
I would like your thoughs on one thing.

In my hugo.toml file I got specified few parameters, each parameter with three values.

I am calling this parameters to be used in layout using shortcode. In frontmatter of each post I specify only the ones that need to be displayed.

The issue I have right now is that Order, in which items are taken and displayed is strictly as placed in hugo.toml file.

Can I ask for help with keeping an order as specified in frontmatter?

Thats about what I like to get help with, now a bit of examples.


The frontmatter for post (example here) contains:

amazon:
 - Blender
 - IrishGlass
 - IceCreamScoop

hugo.toml contain something like that in relation to this three elements.

 [[params.amazon]]
   identifier = "IceCreamScoop"
   picture = "/amazon/Ice_Cream_Scoop.jpg"
   path = "https://amzn.to/4dmx6nv"
 [[params.amazon]]
   identifier = "Blender"
   picture = "/amazon/Blender.jpg"
   path = "https://amzn.to/3vBuaCE"
 [[params.amazon]]
   identifier = "IrishGlass"
   picture = "/amazon/Irish_Glass.jpg"
   path = "https://amzn.to/4c5zFZs"

The shortcodde (which I am using inside content {{< amazon >}}) code is as follow (part):

{{ $allTools := .Site.Params.amazon }}
{{ $frontmatterIds := $.Page.Params.amazon }}

{{ with $frontmatterIds }}

<div id="amazon-slider">
    <div class="amazon-container" id="scroll-container">

        {{ range where $allTools "identifier" "in" . }}

            {{ $toolPicture := resources.Get .picture }}

                    <div class="amz">
                    <picture class="amazon-image" aria-labelledby="{{ printf "figcaption-%s" ($toolPicture.RelPermalink | hash.XxHash) }}">
                        <a href="{{ .path  }}" target="_blank" rel="noopener">
                            {{- $200w := $toolPicture.Resize "200x webp" -}}
                            {{- $400w := $toolPicture.Resize "400x webp" -}}
                            <source srcset="{{with $400w.RelPermalink }}{{.}}{{ end }} 2x,
                                            {{with $200w.RelPermalink }}{{.}}{{ end }}"
                                            type="image/webp">
                            <img src="{{ $toolPicture.RelPermalink }}" alt="{{ T .identifier }}" width="200" height="200" decoding="async" loading="lazy"/>
                            <span id="{{ printf "figcaption-%s" ($toolPicture.RelPermalink | hash.XxHash) }}" class="caption">{{ T .identifier }}</span>
                        </a>
                    </pictire>
                    </div>

        {{ end }}

    </div>
</div>

{{ end }}

This will render in order from hugo.toml file like that:

  • IceCreamScoop
  • Blender
  • IrishGlass

because thats the order in that file.

Can I ask for advise/help how to request order as per statement in contant file?

In this need, will be:

  • Blender
  • IrishGlass
  • IceCreamScoop

you have to loop on the frontmatter list, and lookup the matching site.Param instead

   {{ range $.Page.Params.amazon }}
      {{ $identifier := . }}
      {{ with where site.Params.amazon "identifier" $identifier }}
         <h3>{{- $identifier -}}</h3>
         <h4>access one field</h4>
         {{ with index . 0 }}
            <p>Picture = {{ index . "picture" }}</p>
         {{ end }}
         <h4>range all fields</h4>
         <ul>
            {{ range $k, $v := index . 0 }}
               <li>{{ $k }} = {{ $v }}</li>
            {{ end }}
         </ul>
      {{ else }}
         <h3>{{ $identifier }} MISSING in site config</h3>
      {{ end }}
   {{ end }}

p.s. maybe sort the frontmatter list for better user experience if it matches your use case

{{ range sort $.Page.Params.amazon }}

  • Blender
  • IceCreamScoop
  • IrishGlass
1 Like

Thats what I am doing. I specify in frontmatter the order that I would prefer but my shortcode using lookup order from hugo.toml file.


Thanks for the initial code, I will have a look how I can use it. The problem right not is getting .picture value, but will think about it.

keep in mind, that where returns an array, to get the map you will have to first index with 0.

updated the example code to show a direct field access.

with this content file:
---
amazon:
   - Blender
   - Missing
   - IrishGlass
   - IceCreamScoop
---

## Sorted by Frontmatter

it will render like this:
image

1 Like

Just been thinking about something different, as with your approach causing me some hiccups.

By using sort I got this:

 {{ range sort (where $allTools "identifier" "in" .) "identifier" }}

will sort alphabetically by identifier.

It would be nice if I could sort by $frontmatterIds but somehow is not working.

ref: Sort a range by custom param - #4 by zwbetz

Looking at this:

This shall theoretically work:

{{ range sort (where $allTools "identifier" "in" .) "Params.amazon"}} 

but getting error calling sort: can't evaluate an invalid value

or

{{ range sort (where $allTools "identifier" "in" .) $frontmatterIds "asc" }}

no error, but not sorting correctly.

Think thats a different topic…

But if i remember it right my sort in the post actueally does sorting the list of amazon identifiers from frontmatter. Which in your code is $frontmatterId
…

In general I would prefer to sort the smaller list.should be cheaper and allows better handling of spelling errors…

Or I got it wrong and there`s somthing you can point out

Thanks.

I will do some playing and will see with what I will come out.