Fathy AR A dev blog: journal, notes, and more...

Finding a Better Method for Hiding Page Metadata Using Front Matter Variables

Posted on in Web Dev · 695 words · 4 minute read
Tagged with: Hugo, Theme Development

I was trying to solve a problem related to the option of displaying and hiding metadata of a page. This is useful in cases where some data in the metadata is irrelevant to be displayed. The metadata I’m talking about here is the information of a page that is commonly displayed on top of or below the page’s main heading or title such as date and word count. In my case, this metadata is generated by two partial templates in partials/article/metadata.html and partials/article/metadata.less.html.

Here is the idea. I wanted users to be able to disable displaying some parts of the metadata—or even the entire metadata—simply by adding one or some key-value pairs in the front matter. But, by default, the templates will display the metadata.

Below is the example of a content page with a YAML front matter:

---
title: Hello
date: 2021-08-22
categories: ['cat1', 'cat2']
---
page content here

The above content page example by default will display its metadata: date and categories. And, by adding displaymetadata: false to the front matter, I want all of the metadata not to be displayed—excluding the title. And only the date will be hidden if displaydate: false is added. If displaymetadata: true and displaydate: true are added, then it won’t matter because the default is that all parts of metadata is displayed.

For example, the date in the content page below will be hidden.

---
title: Hello
date: 2021-08-22
categories: ['cat1', 'cat2']
displaymetadata: true
displaydate: false
---
page content here

Here’s a part of the content of the partial template file stored in the metadata.html:

{{ if $displayMetadata }}
    {{ if or .Date .Params.categories }}
    <p>
        {{ if or $displayDate .Params.categories }}Posted {{ end }}
        {{ if $displayDate }}
            on <time>{{ .Date.Format (default "2006-01-02 15:04:05" .Site.Params.dateFmt) }}</time>
        {{ end }}
        {{ with .Params.categories }}
            {{ range first 1 . }} in <a href="{{ "/cat/" | relLangURL }}{{ . | urlize }}">{{ . }}</a> {{- end -}}
            {{ range after 1 . -}} , <a href="{{ "/cat/" | relLangURL }}{{ . | urlize }}">{{ . }}</a> {{- end -}}
        {{ end }}
    </p>
    {{ end }}
{{ end }}

What I needed to do then, was assigning the value of $displayMetadata and $displayDate. Here is what I did the first time.

{{ $scratch := newScratch }}

{{ if eq .Params.displaymetadata false }}
    {{ $scratch.Set "displayMetadata" false }}
{{ else }}
    {{ $scratch.Set "displayMetadata" true }}
{{ end }}

{{ if eq .Params.displaydate false }}
    {{ $scratch.Set "displayDate" false }}
{{ else }}
    {{ $scratch.Set "displayDate" true }}
{{ end }}

{{ $displayMetadata := $scratch.Get "displayMetadata" }}
{{ $displayDate := $scratch.Get "displayDate" }}

What I did was utilizing Hugo’s newScratch function. It worked. But, it was quite complicated for such a simple task. I needed to find an easier way.

And, yes, I then found an easier and simpler way to do the task.

{{/*
    If the param value is not equal to false (i.e. "true" or "not defined") then display the metadata,
    otherwise when the param value is false then do not display the metadata
*/}}
{{ $displayMetadata := (ne .Params.displaymetadata false) }} 
{{ $displayDate := (ne .Params.displaydate false) }}

It worked like a charm.

But, then after contemplating and going back and forth between Hugo’s docs pages, I decided to change the parameters key name in the front matter to something that is more relevant and to-the-point.

So, instead of this,

displaymetadata: false
displaydate: false

I chose this,

metadataHideAll: true
metadataHideDate: true

because by default the template will display the metadata, and it is way closer to logic to use the metadataHideAll key and set its value to true in order to tell the template to hide them than it is to use the displaymetadata with its value set to false.

So, here is the final version of the method in setting the value of $displayMetadata and $displayDate:

{{/*
    if the param value is not equal to true (i.e. "false" or "not defined") then $displayMetadata is set to true,
    else when the param value is "true" then $displayMetadata is set to false
*/}}

{{ $displayMetadata := (ne .Params.metadataHideAll true) }}
{{ $displayDate := (ne .Params.metadataHideDate true) }}