Website/content/docs/website/hugo/shortcodes.md

212 lines
5.7 KiB
Markdown
Raw Normal View History

2024-02-04 23:33:11 +01:00
---
title: 'Shortcodes'
date: 2024-02-04T22:22:43+01:00
draft: true
---
## 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 and CSS structures. For this purpose there is a official guide on how to
[create your own shortcodes](https://gohugo.io/templates/shortcode-templates/).
### iFrame
2024-02-28 21:48:26 +01:00
To embed arbitrary media `layouts/shortcodes/iframe.html` is created containing
2024-02-04 23:33:11 +01:00
the following [HTML](https://en.wikipedia.org/wiki/HTML) code:
```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
```
The definitions of the [CSS](https://en.wikipedia.org/wiki/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
Audio and video sources can be enclosed in a `<figure>`[^1] 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):
[^1]: [Figure](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure)
in the MDN Web Docs.
```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[^2]
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;
}
```
[^2]: [CSS grid layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout)
in the MDN Web Docs
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-04 23:33:11 +01:00
```