Range statement for data files in subdirectories


#1

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.


#2

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.


#3

@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!


#4

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