Merging content in `content` with metadata in `data`

I have some posts in content/posts, and some metadata about those posts in data/posts. Each of the content/posts entries has its own frontmatter, to which I would like to add the metadata in data/posts – effectively, I’d like to merge that data into the corresponding content.

The docs say:

Data files aren’t used to generate standalone pages - rather they’re meant supplemental to the content files. This feature can extend the content in case your frontmatter would grow immensely.

But how does one actually “extend the content” in this way? For example, let’s say I want to put my slug in a data file; how do I associate the data file with the corresponding content?

You have to define your own relationship, and map a key from file to data file, using some common key, i.e. filename or a param.

Then in your template you can get the page’s data by something ala:

{{ index .Site.Data.myPageData .Params.myKey }}

Where myPageData is /data/myPageData.toml (or JSON etc.) and myKey is defined in the page’s frontmatter. This is up to you, but the advantage of using a key defined in front matter is that multiple pages can share the same meta data (just use the same key).

1 Like

That’s the approach I’m using now, but I think that’s only going to work for parameters that don’t need to be in the frontmatter itself – it’s not really a merging of the data into the frontmatter.

For example, if I have an arbitrary parameter that I want to use, like the myKey example you cited, the previous approach will work. But let’s say I want to specify title or slug in the data file and not in the content itself – I don’t think that will work, because the page has already been generated by inspecting the file’s frontmatter. (Or at least, I couldn’t find a way to make it work.)

Does that make sense?

Yes, you cannot override front-matter variables like title and slug.

1 Like

Thanks for confirming, @bep. Do you think it would be in the project’s scope to accept a patch that optionally allowed this merging to occur?

Or is this something that should happen outside of Hugo? (For example, maybe one uses an external tool to rewrite the frontmatter from a data file and inject that slug.)

You can process the data from data file in the template before the variable from FM.

{{ if isset .Site.Data.names .Title }}
  {{ $yaml := (index .Site.Data.names .Title) }}
  <h1>
    {{ with $yaml.penname }}
      {{ index . }}
    {{else}}
      {{ .Title }} 
    {{ end }}
  </h1>                  
{{ end }}