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:
{{ $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:
/* 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:
<!-- 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:
{{ $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:
{{ $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:
/* 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.
markup:
goldmark:
renderer:
unsafe: trueShortcode 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:
/* Cover figure */
figure.thumbnail {
width: 200px;
}