Using Hugo .Render to Save Repetition

Featured image for sharing metadata for article

Up until recently, my Hugo site's templates were full of snippets like:

{{- if eq .Type "posts" -}}
<meta name="twitter:label1" value="Reading time" />
{{ if eq 1 .ReadingTime }}
	<meta name="twitter:data1" value="{{ .ReadingTime }} min" />
{{ else }}
	<meta name="twitter:data1" value="{{ .ReadingTime }} mins" />
{{ end }}
{{ end }}
{{- if (eq .Type "events") -}}
	{{ if .Params.Start }}
	<meta name="twitter:label1" value="Start time" />
	<meta name="twitter:data1" value="{{ dateFormat "Mon, 02 Jan 2006 15:04:05 MST" .Params.Start }}" />
	{{ end }}
	{{ if .Params.Adr }}
	<meta name="twitter:label2" value="Address" />
	<meta name="twitter:data2" value="{{ .Params.adr.street_address }}, {{ .Params.adr.locality }}, {{ .Params.adr.postal_code }}" />
	{{ end }}
{{- end -}}

This wasn't really a very scalable solution, as each time I created a new content type, I'd need to add a new case statement.

But recently I learned about Hugo's .Render functionality, which means I can update my templates to just call to .Render:

 		<meta name="twitter:card" content="summary" />
 		<meta name="twitter:title" content="{{ .Title }} &middot; {{ .Site.Title }}" />
 		<meta name="twitter:description" content="{{ $description }}" />
-
-		{{- if eq .Type "posts" -}}
-		<meta name="twitter:label1" value="Reading time" />
-		{{ if eq 1 .ReadingTime }}
-			<meta name="twitter:data1" value="{{ .ReadingTime }} min" />
-		{{ else }}
-			<meta name="twitter:data1" value="{{ .ReadingTime }} mins" />
-		{{ end }}
-		{{ end }}
-		{{- if (eq .Type "events") -}}
-			{{ if .Params.Start }}
-			<meta name="twitter:label1" value="Start time" />
-			<meta name="twitter:data1" value="{{ dateFormat "Mon, 02 Jan 2006 15:04:05 MST" .Params.Start }}" />
-			{{ end }}
-			{{ if .Params.Adr }}
-			<meta name="twitter:label2" value="Address" />
-			<meta name="twitter:data2" value="{{ .Params.adr.street_address }}, {{ .Params.adr.locality }}, {{ .Params.adr.postal_code }}" />
-			{{ end }}
-		{{- end -}}
 		<meta name="twitter:image" content="{{ $imageUrl }}" />
+		{{ .Render "sharing-card" }}

And then i.e. in events/sharing-card.html:

{{ if .Params.Start }}
  <meta name="twitter:label1" value="Start time" />
  <meta name="twitter:data1" value="{{ dateFormat "Mon, 02 Jan 2006 15:04:05 MST" .Params.Start }}" />
{{ end }}
{{ if .Params.Adr }}
  <meta name="twitter:label2" value="Address" />
  <meta name="twitter:data2" value="{{ .Params.adr.street_address }}, {{ .Params.adr.locality }}, {{ .Params.adr.postal_code }}" />
{{ end }}

And in posts/sharing-card.html:

<meta name="twitter:label1" value="Reading time" />
{{ if eq 1 .ReadingTime }}
  <meta name="twitter:data1" value="{{ .ReadingTime }} min" />
{{ else }}
  <meta name="twitter:data1" value="{{ .ReadingTime }} mins" />
{{ end }}

As well as that, you can set up a _default/sharing-card.html, which will be used if each content type doesn't override it.

EDIT: However, as found the other day, this actually broke my RSS/JSON Feeds.

.Render looks up Content Views for the same output format that it's currently rendering. So when I set i.e. my RSS feed to .Render "content" it was actually looking up content.xml, which didn't exist, as it's content.html! The workaround I've now employed is to have a partial that stores the HTML rendering of the page, and can then be called from JSON Feed, HTML or RSS to save on duplication.

Fortunately this didn't break my h-feed - maybe we should be using these instead of JSON Feed/RSS, eh?

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #hugo #www.jvt.me.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.