How to range through subdirectories in /data folder

I already looked at this solution: https://discourse.gohugo.io/t/range-statement-for-data-files-in-subdirectories/5974

but it is 5 years old and very confusing to me.

My previous setup is like this:

But now my structure is like this:

data/
  verbs/
    form_1/
    form_2/
...

My layouts/verbs/single.html file looks this this:

{{ define "main" }}
<header>
</header>
{{ range (index .Site.Data.verbs .File.BaseFileName) }}
    {{ range . }}
        <h3> Reference: {{ .title }} </h3>
        <h3> Verse </h3>
        <p>{{ .arabic | safeHTML}}</p>
        <!-- [aya][translation] -->
        <p>{{ .translation | safeHTML}}</p>
        <hr>
    {{ end }}
{{ end }}

{{ end }}

and the JSON sample: JSON Blob | 1000529962998185984

and an example .md file:

---
title: "02_طلق"
---

I am very confused how to configure the range statements now.

Can anybody offer guidance?

I have adjusted my HTML to this:

  {{ range $parentKey, $parent := .Site.Data }}
      {{ range $childKey, $child := . }}
        <p>{{ $child.arabic | safeHTML}}</p>

and a further adjustment renders the loop but not the output:

{{ range $child }}
            <p>{{ .arabic | safeHTML}}</p>

but nothing renders.

{{ range $parentKey, $parent := .Site.Data.verbs }}
    {{ range $parent }}
        <h3> Reference: {{ .title }} </h3>
        <h3> Verse </h3>
        <p>{{ .arabic | safeHTML}}</p>
        <!-- [aya][translation] -->
        <p>{{ .translation | safeHTML}}</p>
        <hr>
    {{ end }}
{{ end }}

I think this will work.

This didn’t work.

It only renders the 2 parent items (in this case, form_1 and form_2) at the same time on every nested .md file

So what I have discovered is that with this example:

{{ range $parentKey, $parent := .Site.Data.verbs }}

      {{ range $childKey, $child := . }}

        <p> {{ $childKey }} </p>
        <p> {{ $child }} </p>
...

Every nested JSON/MD file will show the same data:

form_1/entry_1
form_2/entry_1

and then all the other entries are shown, but their maps are displayed like this:

map[]

So the issue is in how I am looping, as I cannot ever view the maps of any entry beyond the first entry of form_x/entry_1

As far as I know, markdown file is not supported in data directory.
But as long as json files are used, it should be ok.
I created a demo for you.
See this template.

data
└── verbs
    ├── form_1
    │   ├── entry_1.json
    │   ├── entry_2.json
    │   └── entry_3.json
    └── form_2
        ├── entry_1.json
        ├── entry_2.json
        └── entry_3.json

http://localhost:1313 renders

form_1 > entry 1
form_1 > entry 2
form_1 > entry 3
form_2 > entry 1
form_2 > entry 2
form_3 > entry 3

json file sample

ignore this :wink: rewriting…

1 Like

The thing to understand here is, that data/foldername/filename.toml translates to site.Data.foldername.filename. So you can’t just range over site.Data

With this structure:

data/
  verbs/
    form_1/
    form_2/
...

I would range over the folders like this:

{{ $key, $value := range site.Data.verbs.form_1 }}
  {{ $key }} <-- data (from data.toml)
  {{ $key2, $value2 := range $value.data }}
    {{ $value2 }} <-- everything in data.toml
  {{ end }}
{{ end }}

For your sample json file you would have (inside the ranges above):

{{ $key }}  <-- "form_1"

then range through `$value.data`:

{{ $key2 }} <-- "2:143"

then range through value2:

{{ $value2.arabic }} <-- sorry, can't select a short sample, but it's the content of the arabic part.
{{ $value2.buckwalter }} <-- wa ka *a`lika jaEalo na` kumo ...
{{ $value2.translation }} <-- And thus we have made you a just community

The above sample assumes:

data/verbs/form_1/data.toml with your sample in JSON Blob | 1000529962998185984

Remember, that it would be much better to have a minimum workable example. just some layout files with one or two datafiles so someone could present proper code samples.

So how would I add this to the layouts/verbs/index.html file?

Do I:

  • Need 5 different HTML files for each form?
  • or do I do {{ $key, $value := range site.Data.verbs.form_X }}, where I have this code written out 5 times for each form?

I am using this: GitHub - leonstafford/accessible-minimalism-hugo-theme: Minimalist Hugo theme with a penchant for accessibility

and I render everything in layouts/verbs/index.html

That’s what I mean with “let us have a sample”. At least put a sample site with that theme and your data directory into a github repo. What you are trying to do right now is hinting about your real setup :slight_smile: … for instance:

  • what page is rendering the verbs/index.html layout? (Pretty sure that layout file is never used, because it indicates a section verbs which would require a list.html and a single.html.
  • how does the “inside” of verb_1 look like?

I am relatively sure your attempts might be working, but not with the content/layout setup you have.

1 Like

Sorry, I made a mistake about the files I meant to say single.html instead of index.html. I will try to setup the git repo, but for now here is the output of layouts/verbs/single.html:

{{ define "main" }}

  {{ range $parentKey, $parent := .Site.Data.verbs }}

    <p> {{ $parentKey }} <p> <-- shows  form_1 and on next loop, shows form_2

      {{ range $childKey, $child := $parent }}

        <p> {{ $child }} </p>  <-- shows the first entry of form_1: entry_1 & form_2: entry_2

            <h3> Ref: </h3>
            <p> {{ .title }} </p>
            <h3> Content: </h3>
            <p>{{ $child.arabic | safeHTML}}</p> <--shows nothing
            <!-- [aya][translation] -->
            <p>{{ .translation | safeHTML}}</p> <--shows nothing
            <hr>
      {{ end }}
  {{ end }}

{{ end }}

and my layouts/verbs/list.html:

{{ define "main" }}
<ul>
{{ range .Data.Pages }}
    <li>
      <a href="{{ .Permalink }}">{{ .Title }}</a>
    </li>
{{ end }}
</ul>

{{ end }}

Here is the sample of content/verbs/form_1/entry_1.md:

---
title: "entry_1"
---

and in content/verbs/_index.md the content to cascade the MD files:

---
title: "Verbs"
type: verbs
cascade:
  type: verbs
---

After investigating and understanding what this does:

{{ range (index .Site.data.verbs .File.BaseFileName) }}

I tried:

 {{ range $parentKey, $parent := .Site.Data.verbs}}

  {{ range (index $parentKey .File.BaseFileName) }}

...

But this gives an error:

execute of template failed at <index $parentKey .File.BaseFileName>: error calling index: cannot index slice/array with nil

Does anybody have any suggestions for what else I can do? I am still stuck on this issue without a solution.

That would be helpful.

1 Like

Hello,

I have setup a working example of the content here:

Right now with what I have, all the JSON content is displayed on each sub-folder.

What I want is to only show the content relevant to the sub-folder:

01_قلب.md - should only show:

form_1:01_قلب.json content.

1 Like

bumping for visibility.

layouts/verbs/single.html

{{ define "main" }}

  {{ with index site.Data.verbs .CurrentSection.File.ContentBaseName .File.ContentBaseName }}
    {{ range $k, $_ := . }}
      <h3>Verse:</h3>
      <p>{{ $k }}</p>
      <h3>Content:</h3>
      <p>{{ .arabic | safeHTML }}</p>
      <p>{{ .translation | safeHTML }}</p>
    {{ end }}
  {{ end }}

{{ end }}
1 Like