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

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

Motorcycle around Jeju

Scenes of Jeju captured whilst on a motorcycle ride.

Written by
Paul J.
 on .
Last updated at on .

Comments.

There are currently no comments on this article.

Leave a comment.



Supports formatting in Markdown.

By submitting your comment, you agree to your comment being published here under the terms of the Creative Commons BY-SA 4.0.