Nested lists without front matter

I wish to create a simple FAQ for our website. It has three sections, so ideally the structure would look like this:

  • topic1:
    • q1
    • q2
  • topic2:
    • q1
    • q2
    • q3
  • topic3:
    • q1

The faq.toml looks like this:

[faq]

[[faq.section]]
    name = "topic1"
    identifier = "topic1"
    url = "/faq/topic1"
    weight = 1

[[faq.section]]
    weight = 1
    question = "q1"
    answer = "a1"
    parent = "topic1"

[[faq.section]]
    weight = 2
    question = "q2"
    answer = "a2"
    parent = "topic1"

[[faq.section]]
    name = "topic2"
    identifier = "topic2"
    url = "/faq/topic2"
    weight = 200

[[faq.section]]
    weight = 1
    question = "q1"
    answer = "a1"
    parent = "topic2"

The shortcode is like this:

{{ $currentPage := . }}
    {{ range .Site.Data.faq.faq.section }}
        {{ if .HasChildren }}
            <li>
                {{ printf "%#v" . }}
                <p>{{ .Name }}</p>
                <ul class="sub">
                    {{ range .Children }}
                    <li> {{ .Name }} </a> </li>
                {{ end }}
                 </ul>
        {{else}}
            <li>
                <p>{{ .Name }}</p>
          {{end}}
          </li>
{{end}}

I cannot get .HasChildren to work. I defined the parents and made references to identifiers. But has children returns nil every time. How to do iterate over parents (topic1, topic2) and then over their respective children?
What am I missing?

Hi,

.HasChildren is a special feature of Menu Entries. So in your case, it is looking at a HasChildren key in your section object, which is in a data file. There is no such key, therefore it returns nil.

You can nest range statements.


Have a read about how to define menus here:

Thank you for a swift reply. I still don’t understand most of things.

I have read the two links you have provided. Heck, I’ve been reading Hugo documentation for the past four hours. :weary:

So in your case, it is looking at a HasChildren key in your section object, which is in a data file.

How do I make it have children? I want “q1” to be the child of “topic1”. I thought this works by assigning parent parameters, but it doesn’t. I just want to have a FAQ page with three sections, each of which has a list of Q&As.

I need to understand how to structure my page and I don’t think the documentation is all that clear on this topics.

You seem to be confusing data files and menus.

In Hugo, “menus” mean something special. You define your menus either in your config.toml file, or on your content front matter. NOT in your /data/ folder. In Hugo menus, parent-child relationships are defined by specifying the "parent" value in the child entry.

The /data/ folder contains regular data files. These may be toml, yaml, or json format files. Here, parent-child relationships are typically implied in their structures;

[object]
title = "This is a parent"

  [[object.children]]
  title = "This is child 1"

  [[object.children]]
  title = "This is child 2"

Have a read about the data folder here: https://gohugo.io/templates/data-templates/#the-data-folder

You can of course still define the relationships by setting the parent value in the children, but it gets more complicated to parse then. You can read about how to iterate over data like this in Hugo here: https://gohugo.io/templates/introduction/#logic

Thank you! I will have a look at the sources you provided. I thought you can spoof data as menus, but apparently you cannot.
Big thanks again for the information and prompt reply!