Range statement for data files in subdirectories

I’m using this type of data directory structure (just an example):

data
  subdir1
    datafile-1-1.toml
    datafile-1-2.toml
  subdir2
    datafile-2-1.toml
    datafile-2-2.toml
    datafile-2-3.toml

The content of a data file is something like

[[mydata]]
title = "Hugo - Data Files"
url = "https://gohugo.io/extras/datafiles/"
date = 2017-03-30T00:00:00Z

I’d like to use a range statement to display all “mydata” items from all the TOML data files in all subdirectories:

{{ range .Site.Data }}
     {{ partial "mydata.html" . }}
{{ end }}

This does not work: does not display anything.

The contents of the mydata.html partial:

{{ range .mydata }}
  <a href="{{ .url }}" target="_blank">{{ .title }}</a>
{{ end }}

So far it only works if I manually call the range statement on each subdirectory:

{{ range .Site.Data.subdir1 }}
{{ range .Site.Data.subdir2 }}

Is it possible to have a single range statement that goes through all data subdirectories and displays all data items?

Thank you for your help.

You have to remember that the Data dir is one big map (dictionary).

{{ $subDir, $files  := range .Site.Data }}
{{ $filename, $fileContent  := range $files }}
{{ $fileContent.title }} 
{{ end }}
{{ end }}

The above totally untested, but I believe I’m correct.

@anaurelian were you able to get this to work? I’ve been trying to do something similar, but have been unsuccessful.

I’m trying to range over a number of data files for team members. The file structure I have is:

data
  team 
     john.yaml
     steve.yaml

And for simplicity sake each person has two data points

name: john
img: images/john_profile.jpg

And what I would like to do is to range those team member files and be able to call the params within them. So for visual purposes since I understand this is not how the range and the data dir function work, I’d like do to something like this

<div class="row">
    {{ range .Site.Data.team .}}
        <div class="col">
           {{.img}}
           {{.name}}
       <div>
    {{ end }}
<div>

@bep I tried your suggestion above and tried manipulating it a number of times, but keep getting this error

ERROR: 2017/12/06 15:37:00 template.go:529: template: theme/index.html:15: too many declarations in command

Any thoughts? It seems like what @anaurelian and I are trying to do is pretty much the same.

Thanks!

1 Like

Not sure if this is helpful but couldn’t you just nest ranges? If you know that your data is always in the same structure and directory depth.

{{ range $parentKey, $parent := .Site.Data }}
    {{ range $childKey, $child := . }}
        <p>Parent (directory): {{ $parentKey }} with current key of: {{ $childKey }}</p>
        {{ partial "yourDataTemplate.html" . }}
    {{ end }}
{{ end }}

Tested this on my site and was able to loop through every data file in the following structure:

  • data (folder)
    • example1 (folder)
      • file1.yaml
    • example2 (folder)
      • file2.yaml
      • file3.yaml
1 Like