summaryrefslogtreecommitdiffstats
path: root/content/content/shortcodes.md
diff options
context:
space:
mode:
Diffstat (limited to 'content/content/shortcodes.md')
-rw-r--r--content/content/shortcodes.md243
1 files changed, 243 insertions, 0 deletions
diff --git a/content/content/shortcodes.md b/content/content/shortcodes.md
new file mode 100644
index 0000000..af90a02
--- /dev/null
+++ b/content/content/shortcodes.md
@@ -0,0 +1,243 @@
++++
+title = "Shortcodes"
+weight = 40
++++
+
+Zola borrows the concept of [shortcodes](https://codex.wordpress.org/Shortcode_API) from WordPress.
+In our case, a shortcode corresponds to a template defined in the `templates/shortcodes` directory or
+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](@/templates/overview.md#load-data) that you
+ want to display in your page's body.
+
+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](@/content/table-of-contents.md).
+
+## 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 %}>
+ <iframe
+ src="https://www.youtube.com/embed/{{id}}{% if autoplay %}?autoplay=1{% endif %}"
+ webkitallowfullscreen
+ mozallowfullscreen
+ allowfullscreen>
+ </iframe>
+</div>
+```
+
+This template is very straightforward: an iframe pointing to the YouTube embed URL wrapped in a `<div>`.
+In terms of input, this shortcode expects at least one variable: `id`. Because the other variables
+are in an `if` statement, they are optional.
+
+That's it. Zola will now recognise this template as a shortcode named `youtube` (the filename minus the `.html` extension).
+
+The Markdown renderer will wrap an inline HTML node such as `<a>` or `<span>` into a paragraph.
+If you want to disable this behaviour, wrap your shortcode in a `<div>`.
+
+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
+<blockquote>
+ {{ body }} <br>
+ -- {{ author}}
+</blockquote>
+```
+
+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
+<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.
+
+## 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 `<div>` 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 `<div>` 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 `<div>` 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 `<div>` 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") }}