Make frontmatter fields required per archetype / enforce schema?

I want to work with multiple editors to manage content with hugo. You can define an archetype, but this seems to only be for the initial creation of a document.

What I would like is the capability to define required frontmatter fields, and even better to tie them to a specific schema for validation. The goal would be that hugo refuses to build the site is a field is missing or its the wrong type/format.

I plan to automate this flow, at least server side, so if here is another tool I could run that would enforce the schema that would work for this need. I’ve seen some tools like NetlifyCMS where this enforcement could go into the gui, but I would like a way to do this without a dependency on a specific front end and on the server side.

Even some rudimentary required field functionality would be great.

Let’s say your content looks like this:

content/
β”œβ”€β”€ article/
β”‚   β”œβ”€β”€ article-1.md
β”‚   β”œβ”€β”€ article-2.md
β”‚   β”œβ”€β”€ article-3.md
β”‚   └── _index.md
└── _index.md

And you want to validate the frontmatter in article-1, article-2, and article-3.

layouts/_default/baseof.html

{{ if and (eq .Kind "page") (eq .Type "article") }}
  {{ partial "validate-article-params.html" . }}
{{ end }}

layouts/partials/validate-article-params.html

{{ $page := .}}
{{ $pageParams := slice
  (dict
    "name" "foo"
    "required" true
    "type" "string"
  )
  (dict
    "name" "bar"
    "required" false
    "type" "int64"
  )
  (dict
    "name" "baz"
    "required" false
    "type" "bool"
  )
}}
{{ range $pageParams }}
  {{ if .required }}
    {{ if not (isset $page.Params .name) }}
      {{ errorf "The %s parameter in %s is not defined." .name $page.Path }}
    {{ end }}
  {{ end }}
  {{ if isset $page.Params .name }}
    {{ $type := printf "%T" (index $page.Params .name) }}
    {{ if not (eq $type .type) }}
      {{ errorf "The %s parameter in %s is of type %s but should be of type %s." .name $page.Path $type .type }}
    {{ end }}
  {{ end }}
{{ end }}

See https://gohugo.io/functions/errorf/

2 Likes