Working with arrays in Front Matter - want a page link to be generated in TWO categories

Note: When I say “categories” it is not the default Hugo taxonomy. I have a Front Matter param on each product page that normally contains a SINGLE value. Ex.

Category: "Wood"
Tags: [ "widgets", "non-widgets" ]

or

Category: "Steel"
Tags: [ "widgets", "non-widgets" ]

This way I can create a page that loads cards for each product page on a Category Page (list.html). Here is the example of my code for listing all “non-widgets” in Category “steel”:

 {{ $pageArray := where .Site.Pages ".Params.Category" "Steel" }}
        
        {{ range where $pageArray.ByWeight "Params.tags" "intersect" (slice "non-widgets") }}   
            <div class="col-lg-4 col-md-6 d-flex py-2" data-aos="zoom-in" data-aos-delay="50">
                <a href="{{ .Permalink }}" class="index-anchor">    
                <div class="card h-60">
                    {{ if .Params.categoryImage }}
                        {{ with .Resources.GetMatch .Params.categoryImage }}                            
                        <div class="card-img">
                            <img width="100%" src="{{ .RelPermalink }}" alt="{{ .Title }}" class="image-fluid">
                        </div>                              
                        {{ end }}
                    {{ end }}
                    <div class="card-body">  
                            <h5 class="card-title"><a href="{{ .Permalink }}">{{ .Title | truncate 35 }}</a></h5>
                            <p class="card-text pb-2">
                                {{ .Summary | safeHTML | truncate 180 }} <br />
                                <div class="row justify-content-center"><a href="{{ .Permalink }}" class="btn"> Details...</a>
                            </div>
                            </p>                            
                    </div>                   
                </div>
                </a>
            </div> 
            {{ end }}
            {{ end }}
            </div>

THE PROBLEM: I have a few products that fit in BOTH categories. I know that I can make an array in front matter for these products:

Category: [ "Wood", "Steel"]
Tags: [ "widgets", "non-widgets" ]

But I’m not sure how I would modify my category page code (example above) to find a product that fits both categories and load it’s card on both “Wood” and “Steel” category list pages.

And since I have a few product pages that fit both categories, does that mean that I need to turn the Front Matter param.Category for EVERY PRODUCT PAGE into an array (most containing only one value)?

If a front matter parameter is defined as a slice on one or more pages, then it should be defined as a slice on all pages. If you don’t do this, you will run into problems when trying build page collections.

You should also get into the habit of defining front matter parameters with the first character lower case.

To answer your question about building the page collection, let’s say we have two posts:

+++
title = 'Post 1'
date = 2022-08-29T13:06:48-07:00
draft = false
categories = ['foo']
+++

and

+++
title = 'Post 2'
date = 2022-08-29T13:06:49-07:00
draft = false
categories = ['foo', 'bar']
+++

To build a collection where categories contains foo or bar:

{{ range where site.RegularPages "Params.categories" "intersect" (slice "foo" "bar") }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}

To build a collection where categories contains both foo and bar:

{{ $p := where site.RegularPages "Params.categories" "intersect" (slice "foo") }}
{{ $p := where $p "Params.categories" "intersect" (slice "bar") }}
{{ range $p }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}
4 Likes

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