Using a Hugo shortcode to peek into a Page
The framework I use to build this site is Hugo, and it is amazing: it is a fast and simple static site generator. Yet its simplicity does absolutely not take away from its flexibility and customisability.
One of those features is the ability to use shortcodes. They allow writers to easily include custom user-built components into their content, yet maintaining the ultra-clean Markdown files that we all love to see.
Preview and embed internal pages.
A shortcode I wrote yesterday, that I aptly called peek
, helps me quickly offer the reader a peek into another page on this blog.
It creates a card that provides a brief description of that post, and on which users can click on as a reference.
Here are two examples of that shortcode in action:
Huam-dong, a mix of old and new
Just a few hundred metres down from Seoul station (서울역) there is this small, rather old neighbourhood called Huam-dong (후암동). A neighbourhood where…
Numbers and Counting in Korean
An explanation of the native Korean and Sino-Korean numbers and their differences. I explain the concept of quantifiers or measure words in Korean, and how they are used for counting.
Using this method lets me quickly refer to previously written content that is relevant while working on new content, whilst encouraging me to revisit older posts.
Finding a hero.
In my posts, I make use of a front matter parameter hero
to specify whether I want to an image to be the mascot of that post. This is nothing more than a path to an image file in that post’s Page Bundle.
Other than the images that can be seen under Chroma, I don’t yet make use of parameter in any other place.
So I thought it would be nice to include a post’s hero
as a preview each time the shortcode generates the preview of a page. Hence, if it has been set in its front matter, I wanted my shortcode peek
to be able to pull that image from the hero
parameter.
The following with
statements allow me to do this: given a post $peek
, check whether its hero
parameter is set, and if it is set check if that path points to a proper file of type image.
If it does, we can safely pull that file and run it through Hugo’s image processing pipeline.
We don’t do any complicated processing – crop the image to a 128x128
thumbnail, and wrap that in a <div>
.
Update: I’ve modified the condition above to check the ResourceType
of the file in hero
– see Page Resources.
{{ with $peek.Params.hero }}
{{ with $peek.Resources.GetMatch . }}
{{ if eq .ResourceType "image" }}
<div class="peek-hero">
<img src="{{ (.Fill "128x128").RelPermalink }}" alt="{{ $peek.Title }}">
</div>
{{ end }}{{ end }}{{ end }}
Adding a simple description.
The next part is simple: pull the title and a description, and put it in a second `.
One interesting little thing here is the truncate
function, which prevents the enclosed description from getting sizely – it is limited by 150 characters. However, if the post does not have a hero
image supporting it, we provide a bit more room for double that amount of characters.
I do know that the condition to check for that hero
image is not as thorough as the one used in the above. However, since it avoids multiple conditional statements, it works sufficiently for now.
<div class="peek-lead">
<p class="peek-title">{{ $peek.Title }}</p>
{{ with $peek.Description }}
<p>{{ . | truncate (cond (isset $peek.Params "hero") "150" "300") "…" }}</p>
{{ end }}
</div>
Putting it together.
We must not forget to let Hugo know what page $peek
to peek in: the one we pass down through the shortcode command. To ensure nice formatting, I run the title texts and post descriptions through markdownify
.
Finally, we join those two fragments, and flavour it with CSS to wrap it all together into a nice card for users click on.
Here is the final code.
{{/* layouts/shortcodes/peek.html */}}
{{ $peek := .Site.GetPage (.Get 0) }}
<a href="{{ $peek.RelPermalink }}"
alt="{{ $peek.Title | markdownify }}" class="peek">
{{ with $peek.Params.hero }}
{{ with $peek.Resources.GetMatch . }}
{{ if eq .ResourceType "image" }}
<div class="peek-hero">
<img src="{{ (.Fill "128x128").RelPermalink }}"
alt="{{ $peek.Title | markdownify }}">
</div>
{{ end }}{{ end }}{{ end }}
<div class="peek-lead">
<p class="peek-title">{{ $peek.Title | markdownify }}</p>
{{ with $peek.Description }}
<p>{{ . | markdownify | truncate (cond (isset $peek.Params "hero")
"150" "300") "…" }}</p>
{{ end }}
</div>
</a>
Save the code as layouts/shortcodes/peek.html
, and then it can be used: by writing
{{< peek "posts/driving-around-jeju" >}}
in a content file Hugo will render the following:
Motorcycle around Jeju
Scenes of Jeju captured whilst on a motorcycle ride.
Last updated at on .
Comments.