`.
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`.
## Using shortcodes
There are two kinds of shortcodes:
- ones that do not take a body, such as the YouTube example above
- ones that do, such as one that styles a quote
In both cases, the arguments must be named and they will all be passed to the template.
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.
Argument values can be of one of five types:
- string: surrounded by double quotes, single quotes or backticks
- bool: `true` or `false`
- 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
Malformed values will be silently ignored.
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.
### Shortcodes without body
Simply call the shortcode as if it was a Tera function in a variable block. All the examples below are valid
calls of the YouTube shortcode.
```md
Here is a YouTube video:
{{/* youtube(id="dQw4w9WgXcQ") */}}
{{/* youtube(id="dQw4w9WgXcQ", autoplay=true) */}}
An inline {{/* youtube(id="dQw4w9WgXcQ", autoplay=true, class="youtube") */}} shortcode
```
Note that if you want to have some content that looks like a shortcode but not have Zola try to render it,
you will need to escape it by using `{{/*` and `*/}}` instead of `{{` and `}}`.
### Shortcodes with body
Let's imagine that we have the following shortcode `quote.html` template:
```jinja2
{{ body }}
-- {{ author}}
```
We could use it in our Markdown file like so:
```md
As someone said:
{%/* quote(author="Vincent") */%}
A quote
{%/* end */%}
```
The body of the shortcode will be automatically passed down to the rendering context as the `body` variable and needs
to be on a new line.
If you want to have some content that looks like a shortcode but not have Zola try to render it,
you will need to escape it by using `{%/*` and `*/%}` instead of `{%` and `%}`. You won't need to escape
anything else until the closing tag.
### 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
{{ value }} is equal to {{ nth }}.
```
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.
## Built-in shortcodes
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
use that instead.
### YouTube
Embed a responsive player for a YouTube video.
The arguments are:
- `id`: the video id (mandatory)
- `class`: a class to add to the `
` surrounding the iframe
- `autoplay`: when set to "true", the video autoplays on load
Usage example:
```md
{{/* youtube(id="dQw4w9WgXcQ") */}}
{{/* youtube(id="dQw4w9WgXcQ", autoplay=true) */}}
{{/* youtube(id="dQw4w9WgXcQ", autoplay=true, class="youtube") */}}
```
Result example:
{{ youtube(id="dQw4w9WgXcQ") }}
### Vimeo
Embed a player for a Vimeo video.
The arguments are:
- `id`: the video id (mandatory)
- `class`: a class to add to the `
` surrounding the iframe
Usage example:
```md
{{/* vimeo(id="124313553") */}}
{{/* vimeo(id="124313553", class="vimeo") */}}
```
Result example:
{{ vimeo(id="124313553") }}
### Streamable
Embed a player for a Streamable video.
The arguments are:
- `id`: the video id (mandatory)
- `class`: a class to add to the `
` surrounding the iframe
Usage example:
```md
{{/* streamable(id="92ok4") */}}
{{/* streamable(id="92ok4", class="streamble") */}}
```
Result example:
{{ streamable(id="92ok4") }}
### Gist
Embed a [Github gist](https://gist.github.com).
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
- `class`: a class to add to the `
` surrounding the iframe
Usage example:
```md
{{/* gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57") */}}
{{/* gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57", class="gist") */}}
```
Result example:
{{ gist(url="https://gist.github.com/Keats/e5fb6aad409f28721c0ba14161644c57") }}