Shortcodes

Shortcodes

Custom shortcodes

Hugo provides built-in shortcodes, Hextra adds some more. However, I need to embed other media sources and want to migrate some of my own HTML1 and CSS2 structures. For this purpose there is an official guide on creating own shortcodes.

iFrame

To embed arbitrary media layouts/shortcodes/iframe.html is created containing the following code:

layouts/shortcodes/iframe.html
{{ $src := .Get "src" -}}
{{ $class := .Get "class" -}}

<div class="wrap-element{{ with $class }} {{ . }}{{ end }}">
  <iframe class="wrapped-iframe"
    {{ with $src }}src="{{ . }}"{{ end }}
    frameborder="0" allowfullscreen>
  </iframe>
</div>

The values of the named shortcode parameters src and class are saved into variables and inserted, if not null. Additionally, the file assets/css/custom.css is created and populated with:

assets/css/custom.css
/* Responsive iframe */

.wrap-element {
  margin-top: 1.5rem;
  position: relative;
  overflow: hidden;
  padding-top: 56.25%;
}

.wrapped-iframe {
  border-radius: 0.5rem;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

@media (min-width: 1280px) {
  .funkwhale {
    padding-top: 28.12%;
  }
}

The definitions of the CSS classes wrap-element and wrapped-iframe are applied to the div and iframeelement to make the embeded resource responsible. This idea originates from a snippet of W3Schools. The funkwhale class is used for embedding Funkwhale media in order to decrease the height of the iframe on bigger screens.

As a result the following shortcode embeds my Influenca (Official Musicvideo):

{{< iframe src="https://libre.video/videos/embed/163971b8-dfff-4309-a579-185090ae88c5" >}}

Raw HTML

For using raw HTML code in a Markdown the file layouts/shortcodes/rawhtml.html is created as follows:

layouts/shortcodes/rawhtml.html
<!-- raw html -->
{{.Inner}}

This way I can write raw HTML code between an opening {{< rawhtml >}} and closing {{< /rawhtml >}} shortcode. The idea is taken from a blog post by Ana Ulin.

Media figure

Audio and video sources can be enclosed in a <figure>3 element providing additional description in a caption and a link to the source file. My audio shortcode is inspired by the solution in the Zen theme:

layouts/shortcodes/audio.html
{{ $caption := .Get "caption" -}}
{{ $preload := .Get "preload" | default "none" -}}
{{ $src := .Get "src" -}}
{{ $type := .Get "type" -}}

<figure class="media">
  <audio controls preload="{{ $preload }}">
    <source src="{{ $src }}" {{ with $type }}type="{{ . }}"{{ end }}>
  </audio>
{{ with $caption -}}
  <figcaption>{{ . | markdownify }}</figcaption>
{{ end }}
{{ with $src -}}
  <a href="{{ . }}">Source link</a>
{{ end -}}
</figure>

The video shortcode is extended by a poster attribute to view an image before playing back the video:

layouts/shortcodes/video.html
{{ $caption := .Get "caption" -}}
{{ $poster := .Get "poster" -}}
{{ $preload := .Get "preload" | default "none" -}}
{{ $src := .Get "src" -}}
{{ $type := .Get "type" -}}

<figure class="media">
  <video controls preload="{{ $preload }}" poster="{{ $poster }}">
    <source src="{{ $src }}" {{ with $type }}type="{{ . }}"{{ end }}>
  </video>
{{ with $caption -}}
  <figcaption>{{ . | markdownify }}</figcaption>
{{ end }}
{{ with $src -}}
  <a href="{{ . }}">Source link</a>
{{ end -}}
</figure>

The additional <figcaption> and <a> elements are organized by a grid4 using the following CSS code added to the assets/css/custom.css file:

assets/css/custom.css
/* Media figure */

figure.media {
  display: grid;
  grid-template-areas: 'player player'
                       'caption link';
  grid-template-columns: 2fr 1fr;
  margin-top: 1rem;
}

figure.media figcaption {
  margin: 1rem;
  grid-area: caption;
}

figure.media audio {
  border-radius: 0.5rem;
  grid-area: player;
  max-height: 40px;
  width: 100%;
}

figure.media video {
  border-radius: 0.5rem;
  grid-area: player;
  width: 100%;
}

figure.media a {
  margin: 1rem;
  grid-area: link;
}

Nesting

In order to nest several shortcodes using the Hextra theme, I have to explicitly set Goldmark markdown renderer to unsafe mode by including the following setting in the hugo.yaml configuration file.

hugo.yaml
markup:
  goldmark:
    renderer:
      unsafe: true

Shortcode adaption

Sometimes built-in shortcodes just need a slight adaption to work for me.

Custom CSS class

The figure shortcode already provides the option to provide a custom class. In order to keep the size of a figure for a thumbnail image small I add the following CSS code to the assets/css/custom.css file:

assets/css/custom.css
/* Cover figure */

figure.thumbnail {
  width: 200px;
}

  1. HTML in the Wikipedia ↩︎

  2. CSS in the Wikipedia ↩︎

  3. Figure in the MDN Web Docs. ↩︎

  4. CSS grid layout in the MDN Web Docs ↩︎

Last updated on