Creating an array of maps in .Scratch

I want to store an array of maps in .Page.Scratch. These maps are added dynamically via a short code - i.e. I want to push a map to an array of maps in .Page.Scratch. This is what I tried initially:

{{ $question := .Get 0 }}

{{ $faq := dict
    "question" $question
    "answer" .Inner
}}

{{ .Page.Scratch.Add "faqs" $faq }}

For context - this is a short code for FAQ entries that is applied like so:

{{% faq "The question" %}}
    The answer.
{{% /faq %}}

I then later want to iterate over all FAQs in a partial and output them as JSON-LD meta data.

However, {{ .Page.Scratch.Add "faqs" $faq }} yields the following error:

failed to process shortcode: "faq.html:21:12": execute of template failed at <.Page.Scratch.Add>: error calling Add: can’t apply the operator to the values

I am sure there is a way to dynamically store an array of maps in a scratch but I am unable to figure out how :thinking:

markdown

{{% faq "Question 1" %}}
Answer 1.
{{% /faq %}}

{{% faq "Question 2" %}}
Answer 2.
{{% /faq %}}

layouts/shortcodes/faq.html

{{ $id := printf "%s-%03d" .Name (add .Ordinal 1) }}
{{ $faq := dict "question" (.Get 0) "answer" .Inner }}
{{ .Page.Store.SetInMap "faqs" $id $faq }}

layouts/_default/single.html

{{ $noop := .WordCount }}
{{ with .Store.GetSortedMapValues "faqs"  }}
  <h3>FAQs</h3>
  <dl>
    {{ range . }}
      <dt>{{ .question }}</dt>
      <dd>{{ .answer }}</dd>
    {{ end }}
  </dl>
{{ end }}

The {{ $noop := .WordCount }} bit above causes .Content to be evaluated.

1 Like

I saw .SetInMap but did not consider it since it would require an additional identifier. So there is no way to just push elements to an array that is in turn stored in .Store or .Scratch?

Sure you can.

{{ .Page.Store.Add "faqs" (slice (dict "question" (.Get 0) "answer" .Inner)) }}

But the other approach gives you a unique element id so that you can jump from the faq summary to the faq on the page.

1 Like

I see, thank you. I am using

{{ .Page.Store.Add "faqs" (slice (dict "question" (.Get 0) "answer" .Inner)) }}

now, however within the partial later on,

{{ $faqs := .Store.GetSortedMapValues "faqs" }}
{{ printf "%#v" $faqs }}

still just outputs <nil> and conversely

{{ $noop := .WordCount }}
{{ with .Store.GetSortedMapValues "faqs"  }}
  <h3>FAQs</h3>
  <dl>
    {{ range . }}
      <dt>{{ .question }}</dt>
      <dd>{{ .answer }}</dd>
    {{ end }}
  </dl>
{{ end }}

generates no output. Using {{ printf "%#v" (.Page.Store.Get "faqs") }} within the shortcode shows the added entries as expected though.

// edit: never mind, when not using .SetInMap I just need to use .Get instead of .GetSortedMapValues obviously.

It looks like you are trying to use .Add with .GetSortedMapValues. That won’t work. You need to .SetInMap instead of add. Here’s a dirt simple example:

git clone --single-branch -b hugo-forum-topic-44677 https://github.com/jmooring/hugo-testing hugo-forum-topic-44677
cd hugo-forum-topic-44677
hugo server

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