2017-09-27 14:37:17 +00:00
|
|
|
+++
|
|
|
|
title = "Shortcodes"
|
|
|
|
weight = 40
|
|
|
|
+++
|
|
|
|
|
2020-07-29 18:20:43 +00:00
|
|
|
Zola borrows the concept of [shortcodes](https://codex.wordpress.org/Shortcode_API) from WordPress.
|
2019-11-26 19:30:30 +00:00
|
|
|
In our case, a shortcode corresponds to a template defined in the `templates/shortcodes` directory or
|
2020-07-29 18:20:43 +00:00
|
|
|
a built-in one that can be used in a Markdown file. If you want to use something similar to shortcodes in your templates,
|
|
|
|
try [Tera macros](https://tera.netlify.com/docs#macros).
|
|
|
|
|
|
|
|
Broadly speaking, Zola's shortcodes cover two distinct use cases:
|
|
|
|
|
|
|
|
* Inject more complex HTML: Markdown is good for writing, but it isn't great when you need add inline HTML or styling.
|
|
|
|
* Ease repetitive data based tasks: when you have [external data](@/documentation/templates/overview.md#load-data) that you
|
|
|
|
want to display in your page's body.
|
2019-11-26 19:30:30 +00:00
|
|
|
|
2020-07-29 18:20:43 +00:00
|
|
|
The latter may also be solved by writing HTML, however Zola allows the use of Markdown based shortcodes which end in `.md`
|
|
|
|
rather than `.html`. This may be particularly useful if you want to include headings generated by the shortcode in the
|
|
|
|
[table of contents](@/documentation/content/table-of-contents.md).
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
## Writing a shortcode
|
|
|
|
Let's write a shortcode to embed YouTube videos as an example.
|
|
|
|
In a file called `youtube.html` in the `templates/shortcodes` directory, paste the
|
|
|
|
following:
|
|
|
|
|
|
|
|
```jinja2
|
|
|
|
<div {% if class %}class="{{class}}"{% endif %}>
|
2018-05-17 16:32:46 +00:00
|
|
|
<iframe
|
|
|
|
src="https://www.youtube.com/embed/{{id}}{% if autoplay %}?autoplay=1{% endif %}"
|
|
|
|
webkitallowfullscreen
|
|
|
|
mozallowfullscreen
|
2017-09-27 14:37:17 +00:00
|
|
|
allowfullscreen>
|
|
|
|
</iframe>
|
|
|
|
</div>
|
|
|
|
```
|
|
|
|
|
|
|
|
This template is very straightforward: an iframe pointing to the YouTube embed URL wrapped in a `<div>`.
|
2019-11-26 19:30:30 +00:00
|
|
|
In terms of input, this shortcode expects at least one variable: `id`. Because the other variables
|
|
|
|
are in an `if` statement, they are optional.
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2019-11-26 19:30:30 +00:00
|
|
|
That's it. Zola will now recognise this template as a shortcode named `youtube` (the filename minus the `.html` extension).
|
2018-05-19 10:12:02 +00:00
|
|
|
|
2020-07-29 18:20:43 +00:00
|
|
|
The Markdown renderer will wrap an inline HTML node such as `<a>` or `<span>` into a paragraph.
|
2019-11-26 19:30:30 +00:00
|
|
|
If you want to disable this behaviour, wrap your shortcode in a `<div>`.
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2020-07-29 18:20:43 +00:00
|
|
|
A Markdown based shortcode in turn will be treated as if what it returned was part of the page's body. If we create
|
|
|
|
`books.md` in `templates/shortcodes` for example:
|
|
|
|
|
|
|
|
```jinja2
|
|
|
|
{% set data = load_data(path=path) -%}
|
|
|
|
{% for book in data.books %}
|
|
|
|
### {{ book.title }}
|
|
|
|
|
|
|
|
{{ book.description | safe }}
|
|
|
|
{% endfor %}
|
|
|
|
```
|
|
|
|
|
|
|
|
This will create a shortcode `books` with the argument `path` pointing to a `.toml` file where it loads lists of books with
|
|
|
|
titles and descriptions. They will flow with the rest of the document in which `books` is called.
|
|
|
|
|
|
|
|
Shortcodes are rendered before the page's Markdown is parsed so they don't have access to the page's table of contents.
|
|
|
|
Because of that, you also cannot use the `get_page`/`get_section`/`get_taxonomy` global functions. It might work while
|
|
|
|
running `zola serve` because it has been loaded but it will fail during `zola build`.
|
2019-01-17 17:29:18 +00:00
|
|
|
|
2017-09-27 14:37:17 +00:00
|
|
|
## Using shortcodes
|
|
|
|
|
2018-05-17 16:32:46 +00:00
|
|
|
There are two kinds of shortcodes:
|
2017-10-19 11:48:50 +00:00
|
|
|
|
2019-11-26 19:30:30 +00:00
|
|
|
- ones that do not take a body, such as the YouTube example above
|
|
|
|
- ones that do, such as one that styles a quote
|
2017-10-19 11:48:50 +00:00
|
|
|
|
2019-11-26 19:30:30 +00:00
|
|
|
In both cases, the arguments must be named and they will all be passed to the template.
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2019-11-26 19:30:30 +00:00
|
|
|
Lastly, a shortcode name (and thus the corresponding `.html` file) as well as the argument names
|
|
|
|
can only contain numbers, letters and underscores, or in Regex terms `[0-9A-Za-z_]`.
|
|
|
|
Although theoretically an argument name could be a number, it will not be possible to use such an argument in the template.
|
2017-10-23 12:18:05 +00:00
|
|
|
|
2019-11-26 19:30:30 +00:00
|
|
|
Argument values can be of one of five types:
|
2017-10-26 15:03:26 +00:00
|
|
|
|
2018-05-17 17:04:42 +00:00
|
|
|
- string: surrounded by double quotes, single quotes or backticks
|
2017-10-26 15:03:26 +00:00
|
|
|
- bool: `true` or `false`
|
2019-11-26 19:30:30 +00:00
|
|
|
- float: a number with a decimal point (e.g., 1.2)
|
|
|
|
- integer: a whole number or its negative counterpart (e.g., 3)
|
|
|
|
- array: an array of any kind of value, except arrays
|
2017-10-26 15:03:26 +00:00
|
|
|
|
|
|
|
Malformed values will be silently ignored.
|
|
|
|
|
2019-11-26 19:30:30 +00:00
|
|
|
Both types of shortcode will also get either a `page` or `section` variable depending on where they were used
|
|
|
|
and a `config` variable. These values will overwrite any arguments passed to a shortcode so these variable names
|
|
|
|
should not be used as argument names in shortcodes.
|
2018-06-25 17:13:21 +00:00
|
|
|
|
2017-09-27 14:37:17 +00:00
|
|
|
### Shortcodes without body
|
|
|
|
|
2018-05-17 17:04:42 +00:00
|
|
|
Simply call the shortcode as if it was a Tera function in a variable block. All the examples below are valid
|
2017-09-27 14:37:17 +00:00
|
|
|
calls of the YouTube shortcode.
|
|
|
|
|
|
|
|
```md
|
2017-10-19 11:48:50 +00:00
|
|
|
Here is a YouTube video:
|
|
|
|
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* youtube(id="dQw4w9WgXcQ") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* youtube(id="dQw4w9WgXcQ", autoplay=true) */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2018-05-17 17:04:42 +00:00
|
|
|
An inline {{/* youtube(id="dQw4w9WgXcQ", autoplay=true, class="youtube") */}} shortcode
|
2017-09-27 14:37:17 +00:00
|
|
|
```
|
|
|
|
|
2018-10-18 21:09:32 +00:00
|
|
|
Note that if you want to have some content that looks like a shortcode but not have Zola try to render it,
|
2018-05-17 17:04:42 +00:00
|
|
|
you will need to escape it by using `{{/*` and `*/}}` instead of `{{` and `}}`.
|
|
|
|
|
2017-09-27 14:37:17 +00:00
|
|
|
### Shortcodes with body
|
2019-11-26 19:30:30 +00:00
|
|
|
Let's imagine that we have the following shortcode `quote.html` template:
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
```jinja2
|
|
|
|
<blockquote>
|
|
|
|
{{ body }} <br>
|
|
|
|
-- {{ author}}
|
|
|
|
</blockquote>
|
|
|
|
```
|
|
|
|
|
2019-11-26 19:30:30 +00:00
|
|
|
We could use it in our Markdown file like so:
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
```md
|
2017-10-19 11:48:50 +00:00
|
|
|
As someone said:
|
|
|
|
|
2018-05-17 16:32:46 +00:00
|
|
|
{%/* quote(author="Vincent") */%}
|
2017-09-27 14:37:17 +00:00
|
|
|
A quote
|
2018-05-17 16:32:46 +00:00
|
|
|
{%/* end */%}
|
2017-09-27 14:37:17 +00:00
|
|
|
```
|
|
|
|
|
2017-10-23 12:18:05 +00:00
|
|
|
The body of the shortcode will be automatically passed down to the rendering context as the `body` variable and needs
|
2019-11-26 19:30:30 +00:00
|
|
|
to be on a new line.
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2018-10-18 21:09:32 +00:00
|
|
|
If you want to have some content that looks like a shortcode but not have Zola try to render it,
|
2018-05-17 17:04:42 +00:00
|
|
|
you will need to escape it by using `{%/*` and `*/%}` instead of `{%` and `%}`. You won't need to escape
|
|
|
|
anything else until the closing tag.
|
|
|
|
|
2020-12-14 15:29:10 +00:00
|
|
|
### Invocation Count
|
|
|
|
|
|
|
|
Every shortcode context is passed in a variable named `nth` that tracks how many times a particular shortcode has
|
|
|
|
been invoked in a Markdown file. Given a shortcode `true_statement.html` template:
|
|
|
|
|
|
|
|
```jinja2
|
|
|
|
<p id="number{{ nth }}">{{ value }} is equal to {{ nth }}.</p>
|
|
|
|
```
|
|
|
|
|
|
|
|
It could be used in our Markdown as follows:
|
|
|
|
|
|
|
|
```md
|
|
|
|
{{/* true_statement(value=1) */}}
|
|
|
|
{{/* true_statement(value=2) */}}
|
|
|
|
```
|
|
|
|
|
|
|
|
This is useful when implementing custom markup for features such as sidenotes or end notes.
|
|
|
|
|
2017-09-27 14:37:17 +00:00
|
|
|
## Built-in shortcodes
|
|
|
|
|
2018-10-18 21:09:32 +00:00
|
|
|
Zola comes with a few built-in shortcodes. If you want to override a default shortcode template,
|
|
|
|
simply place a `{shortcode_name}.html` file in the `templates/shortcodes` directory and Zola will
|
2017-09-27 14:37:17 +00:00
|
|
|
use that instead.
|
|
|
|
|
|
|
|
### YouTube
|
|
|
|
Embed a responsive player for a YouTube video.
|
|
|
|
|
|
|
|
The arguments are:
|
|
|
|
|
|
|
|
- `id`: the video id (mandatory)
|
2021-02-07 16:13:03 +00:00
|
|
|
- `playlist: the playlist id (optional)
|
2019-11-26 19:30:30 +00:00
|
|
|
- `class`: a class to add to the `<div>` surrounding the iframe
|
|
|
|
- `autoplay`: when set to "true", the video autoplays on load
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
Usage example:
|
|
|
|
|
|
|
|
```md
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* youtube(id="dQw4w9WgXcQ") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2021-02-07 16:13:03 +00:00
|
|
|
{{/* youtube(id="dQw4w9WgXcQ", playlist="RDdQw4w9WgXcQ") */}}
|
|
|
|
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* youtube(id="dQw4w9WgXcQ", autoplay=true) */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* youtube(id="dQw4w9WgXcQ", autoplay=true, class="youtube") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Result example:
|
|
|
|
|
2017-10-03 15:21:18 +00:00
|
|
|
{{ youtube(id="dQw4w9WgXcQ") }}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
### Vimeo
|
|
|
|
Embed a player for a Vimeo video.
|
|
|
|
|
|
|
|
The arguments are:
|
|
|
|
|
|
|
|
- `id`: the video id (mandatory)
|
2019-11-26 19:30:30 +00:00
|
|
|
- `class`: a class to add to the `<div>` surrounding the iframe
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
Usage example:
|
|
|
|
|
|
|
|
```md
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* vimeo(id="124313553") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* vimeo(id="124313553", class="vimeo") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Result example:
|
|
|
|
|
|
|
|
{{ vimeo(id="124313553") }}
|
|
|
|
|
|
|
|
### Streamable
|
|
|
|
Embed a player for a Streamable video.
|
2018-05-17 16:32:46 +00:00
|
|
|
|
2017-09-27 14:37:17 +00:00
|
|
|
The arguments are:
|
|
|
|
|
|
|
|
- `id`: the video id (mandatory)
|
2019-11-26 19:30:30 +00:00
|
|
|
- `class`: a class to add to the `<div>` surrounding the iframe
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
Usage example:
|
|
|
|
|
|
|
|
```md
|
2018-05-17 17:04:42 +00:00
|
|
|
{{/* streamable(id="92ok4") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2018-05-17 17:04:42 +00:00
|
|
|
{{/* streamable(id="92ok4", class="streamble") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Result example:
|
|
|
|
|
2018-05-17 17:04:42 +00:00
|
|
|
{{ streamable(id="92ok4") }}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
### Gist
|
2018-05-17 16:32:46 +00:00
|
|
|
Embed a [Github gist](https://gist.github.com).
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
The arguments are:
|
|
|
|
|
|
|
|
- `url`: the url to the gist (mandatory)
|
|
|
|
- `file`: by default, the shortcode will pull every file from the URL unless a specific filename is requested
|
2019-11-26 19:30:30 +00:00
|
|
|
- `class`: a class to add to the `<div>` surrounding the iframe
|
2017-09-27 14:37:17 +00:00
|
|
|
|
|
|
|
Usage example:
|
|
|
|
|
|
|
|
```md
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
|
2018-05-17 16:32:46 +00:00
|
|
|
{{/* gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57", class="gist") */}}
|
2017-09-27 14:37:17 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Result example:
|
|
|
|
|
|
|
|
{{ gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57") }}
|