Hugo

Getting specific and deeply structured data dynamically

I couldn’t describe better as a title so… based on this topic, considering the Data Files are hierarchically structured instead - like /data/folder1/folder2/folder3/file.json - is it possible to get this specific file if the path is unknown, in the meaning of coming from a variable?

For example, considering the path is stored in a FrontMatter Parameter, like:

---
data: folder1/folder2/folder3/file
---

In the template I should do something like:

{{ (index (index (index (index .Site.Data "folder1" ) "folder2" ) "folder3" ) "file" }}

Or the reverse, it’s just a pseudo-code I wrote right now, I didn’t really test

But not only this is not practical, but this defeats the purpose of a dynamically specified path/node and, therefore, I can’t use one single template for multiple sections with minimal variations between them.

Imagining Hugo could be nifty in this matter, I also tried, without success, of course, this:

{{ (index .Site.Data "folder1.folder2.folder3.file" ) }}

The last attempt I could try, but I don’t really have a clue about how to do it (so far I’ve only seen this in the Hugo Debug Partial in a Gist), would be using a recursive partial, thus index-ing N times, as long as dots or slashes would exist in the string.

Anything else I might now know?

Related enhancement request:

Alright, just so the main question don’t become too long, I almost did it with recursive partials:

{{ $this       := .this }}
{{ $node       := .node }}
{{ $collection := (.collection) | default (index (.this.Site.Data) (.this.Site.Language.Lang) ) }}

{{ if (in .node "/" ) }}

    {{ $current := (index (first 1 (split .node "/" ) ) 0) }}
    {{ $next    := replaceRE (printf "%s/?" $current) "" $node }}

    {{ partial "find" (dict "this" $this "node" ($next) "collection" (index $collection $current ) ) }}

{{ else }}
    
    {{ $this.Scratch.Set "resource" (index $collection .node ) }}

{{ end }}

And to use:

{{ partial "find" (dict "this" . "node" "full/path/to/the/file" ) }}

Adding this to hold is an old habit I’ve acquired a long time ago when I had a different problem with scopes. In here it’s probably not needed.

Problem with this implementation are:

  1. It’s slow. Three tabs opened pointing to three different pages took a few seconds to reload when changing the template (LiveReload)
  2. If the current value being parsed is also present in the next, the Regex will result in an expression like
    -word because the common term between them was stripped off from the left of the hyphen/dash
  3. I noticed it to not be reliable all the time. I don’t how exactly Hugo’s parsing works in terms of processing order, but in some pages, I’ve got what I wanted - I successfully read data from the JSON found - but sometimes not.
  4. I had to use a Scratch to hold the results because I don’t know if there’s such a thing a return statement we have in other languages - and simply outputting the results doesn’t make them usable

It’s something, yes, but not quite yet

That referenced Issue could be just what I need for this old project :ok_hand: