2024-02-04 23:33:11 +01:00
---
title: 'Shortcodes'
date: 2024-02-04T22:22:43+01:00
---
## Custom shortcodes
Hugo provides [built-in shortcodes ](https://gohugo.io/content-management/shortcodes/#use-hugos-built-in-shortcodes ),
Hextra adds [some more ](https://imfing.github.io/hextra/docs/guide/shortcodes/ ).
However, I need to embed other media sources and want to migrate some of my own
2024-02-29 15:41:18 +01:00
HTML[^1] and CSS[^2] structures. For this purpose there is an official guide on
[creating own shortcodes ](https://gohugo.io/templates/shortcode-templates/ ).
2024-02-04 23:33:11 +01:00
### iFrame
2024-02-28 21:48:26 +01:00
To embed arbitrary media `layouts/shortcodes/iframe.html` is created containing
2024-02-29 15:41:18 +01:00
the following code:
2024-02-04 23:33:11 +01:00
```html {filename="layouts/shortcodes/iframe.html"}
2024-02-28 21:48:26 +01:00
{{ $src := .Get "src" -}}
{{ $class := .Get "class" -}}
< div class = "wrap-element{{ with $class }} {{ . }}{{ end }}" >
2024-02-04 23:33:11 +01:00
< iframe class = "wrapped-iframe"
2024-02-28 21:48:26 +01:00
{{ with $src }}src="{{ . }}"{{ end }}
2024-02-04 23:33:11 +01:00
frameborder="0" allowfullscreen>
< / iframe >
< / div >
```
2024-02-28 21:48:26 +01:00
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:
2024-02-04 23:33:11 +01:00
```css {filename="assets/css/custom.css"}
/* Responsive iframe */
.wrap-element {
2024-02-28 21:48:26 +01:00
margin-top: 1.5rem;
2024-02-04 23:33:11 +01:00
position: relative;
overflow: hidden;
padding-top: 56.25%;
}
.wrapped-iframe {
2024-02-28 21:48:26 +01:00
border-radius: 0.5rem;
2024-02-04 23:33:11 +01:00
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
}
2024-02-28 21:48:26 +01:00
@media (min-width: 1280px) {
.funkwhale {
padding-top: 28.12%;
}
}
2024-02-04 23:33:11 +01:00
```
2024-02-29 15:41:18 +01:00
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
2024-02-28 21:48:26 +01:00
[W3Schools ](https://www.w3schools.com/howto/howto_css_responsive_iframes.asp ).
The `funkwhale` class is used for embedding Funkwhale media in order to decrease
the height of the iframe on bigger screens.
2024-02-04 23:33:11 +01:00
As a result the following shortcode embeds my Influenca (Official Musicvideo):
```
2024-02-28 21:48:26 +01:00
{{< /* iframe src="https://libre.video/videos/embed/163971b8-dfff-4309-a579-185090ae88c5" */>}}
2024-02-04 23:33:11 +01:00
```
### Raw HTML
For using raw HTML code in a Markdown the file `layouts/shortcodes/rawhtml.html`
is created as follows:
```html {filename="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 ](https://anaulin.org/blog/hugo-raw-html-shortcode/ ).
2024-02-28 21:48:26 +01:00
### Media figure
2024-02-29 15:41:18 +01:00
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
2024-02-28 21:48:26 +01:00
shortcode is inspired by the [solution in the Zen theme ](https://github.com/frjo/hugo-theme-zen/blob/main/layouts/shortcodes/audio.html ):
```html {filename="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:
```html {filename="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 >
```
2024-02-29 15:41:18 +01:00
The additional `<figcaption>` and `<a>` elements are organized by a grid[^4]
2024-02-28 21:48:26 +01:00
using the following CSS code added to the `assets/css/custom.css` file:
```css {filename="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;
}
```
2024-02-04 23:33:11 +01:00
## Nesting
In order to nest several shortcodes using the Hextra theme, I have to explicitly
set [Goldmark ](https://gohugo.io/getting-started/configuration-markup/ ) markdown
renderer to unsafe mode by including the following setting in the `hugo.yaml`
configuration file.
```yaml {filename="hugo.yaml"}
markup:
goldmark:
renderer:
unsafe: true
2024-02-28 21:48:26 +01:00
```
## Shortcode adaption
Sometimes built-in shortcodes just need a slight adaption to work for me.
### Custom CSS class
The [figure shortcode ](https://gohugo.io/content-management/shortcodes/#figure )
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:
```css {filename="assets/css/custom.css"}
/* Cover figure */
figure.thumbnail {
width: 200px;
}
2024-02-29 15:41:18 +01:00
```
[^1]: [HTML ](https://en.wikipedia.org/wiki/HTML ) in the Wikipedia
[^2]: [CSS ](https://en.wikipedia.org/wiki/CSS ) in the Wikipedia
[^3]: [Figure ](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure )
in the MDN Web Docs.
[^4]: [CSS grid layout ](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout )
in the MDN Web Docs