212 lines
No EOL
5.8 KiB
Markdown
212 lines
No EOL
5.8 KiB
Markdown
---
|
|
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
|
|
HTML[^1] and CSS[^2] structures. For this purpose there is an official guide on
|
|
[creating own shortcodes](https://gohugo.io/templates/shortcode-templates/).
|
|
|
|
### iFrame
|
|
|
|
To embed arbitrary media `layouts/shortcodes/iframe.html` is created containing
|
|
the following code:
|
|
|
|
```html {filename="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:
|
|
|
|
```css {filename="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 `iframe`element to make the embeded resource
|
|
responsible. This idea originates from a snippet of
|
|
[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.
|
|
|
|
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:
|
|
|
|
```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/).
|
|
|
|
### 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](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>
|
|
```
|
|
|
|
The additional `<figcaption>` and `<a>` elements are organized by a grid[^4]
|
|
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;
|
|
}
|
|
```
|
|
|
|
## 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
|
|
```
|
|
|
|
## 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;
|
|
}
|
|
```
|
|
|
|
[^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 |