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 iframe
element 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: 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:
/* Cover figure */
figure.thumbnail {
width: 200px;
}