Zola

Zola is a static site generator (SSG) written in Rust and uses the Tera template engine. Zola uses pulldown-cmark to parse content written in CommonMark specification of Markdown. Zola prioritizes ease of use, super fast build, simple templating, and is suitable for minimalistic and fast dev blog.

Content

Section

Zola uses the directory structure to determine the site structure. Each child directory in the content directory represents a section if it contains an _index.md file. The _index.md file stores both the metadata and the content of a section. For example, the content in content/blog/_index.md is shown on https://mywebsite.com/blog/. If a directory does not contain an _index.md file, no section will be created, but Markdown files within that directory will still create pages (known as orphan pages). Note that the content directory itself creates a main content section, regardless the existence of an _index.md file inside the directory, and if content/_index.md is created, its content is shown on https://mywebsite.com/.

Front matter

The TOML front matter is used to embed a set of metadata at the beginning of a file enclosed by triple pluses (+++). Content added after the closing +++ will be parsed as Markdown and accessible through the section.content variable in the templates.

YAML front matter formatted by triple minuses (---) is also supported.

Sorting

Posts will be iterated over in the order specified by the sort_by variable set in the _index.md file of the section. The sort_by variable can be given a few values: date, update_date, title, title_bytes, weight, slug, or none.

Asset colocation

Zola supports asset colocation with sections and pages.

Pages with co-located assets should be placed as an index.md in a dedicated directory (content/blog/foo/index.md) instead of directly in their section directory (content/blog/foo.md). By default, this page's slug will be the directory name and thus its permalink will be https://mywebsite.com/blog/foo/.

All non-Markdown files added in a section/page directory will be copied alongside the generated page when the site is built, which allows accessing them with a relative path. Note that we can use ignored_content in the config file to ignore selected asset files.

Static assets

All files/directories placed in the static directory will be copied to the public directory. These files won't be parsed as Markdown files.

A common use case is putting site-wide assets (CSS files, site logos and JavaScript files) under static and use an absolute path to access the assets.

Note that zola supports colocation between content and static if the subpaths are the same. That is, we can use relative path to access static/blog/zola/logo.svg from content/blog/zola/index.md.

Pagination

Enable pagination for a section's pages by setting paginate_by to a positive number.

Drafting

Sections and pages can be drafted by setting the draft option in the front matter. When a section is drafted its descendants like subsections, pages, and assets will not be processed unless the --drafts flag is passed.

Page

A page is any Markdown file that is not _index.md within the content directory. Note that a index.md file will generate a page with the name of its directory. For example content/about/index.md will create a page at <BASE_URL>/about.

Front matter

We can set page front matter as well.

Shortcode

Zola borrows the concept of shortcodes from WordPress to cover two distinct use cases:

Limitations

Shortcode has several limitations:

If the shortcode is invalid it will get rendered directly into the final HTML instead of being processed.

Shortcode without body and arguments

One basic shortcode example is a shortcode without body and arguments. We can create a file named withoutbodywithoutarguments.html in the templates/shortcodes directory, which has the following content.

templates/shortcodes/withoutbodywithoutarguments.html

<div>
    My message.
</div>

Zola will recognize this template as a shortcode named withoutbodywithoutarguments. We can then use it in any Markdown files as if it was a Tera function in a variable block.

{{ withoutbodywithoutarguments() }}

Shortcode with body and without arguments

We can create a file named withbodywithoutarguments.html in the templates/shortcodes directory, which has the following content.

templates/shortcodes/withbodywithoutarguments.html

<div>
    {{ body }}
</div>

And then use it in any Markdown files.

{% withbodywithoutarguments() %}
My message.
{% end %}

Shortcode without body and with arguments

Shortcode accepts five types of arguments:

Malformed values will be silently ignored.

We can create a file named withoutbodywitharguments.html in the templates/shortcodes directory, which has the following content.

templates/shortcodes/withoutbodywitharguments.html

<div>
    {{ message }}
</div>

And then use it in any Markdown files.

{{ withoutbodywitharguments(message="My message") }}

Shortcode with body and arguments

We can create a file named withbodywitharguments.html in the templates/shortcodes directory, which has the following content.

templates/shortcodes/withbodywitharguments.html

<div>
    {{ body }}
    {{ message }}
</div>

And then use it in any Markdown files.

{% withbodywitharguments(message="My message") %}
My body.
{% end %}

Escaping

We can escape rendering content that looks like a shortcode by using {{/* and */}} instead of {{ and }}, and {%/* and */%} instead of {% and %}.

Examples

YouTube

We can put a youtube.html file in the templates/shortcodes directory with the below content.

templates/shortcodes/youtube.html

<div {% if class %}class="{{class}}"{% endif %}>
    <iframe
        src="https://www.youtube.com/embed/{{id}}{% if autoplay %}?autoplay=1{% endif %}"
        webkitallowfullscreen
        mozallowfullscreen
        allowfullscreen>
    </iframe>
</div>

Zola now recognizes this template as the youtube shortcode that wraps an iframe pointing to an YouTube URL in a <div>

The Markdown renderer wraps an inline HTML node into a paragraph but we can disable this behavior by wrapping the shortcode in a <div>.

Books

We can create books.md in templates/shortcodes with the below content.

templates/shortcodes/books.md

{% set data = load_data(path=path) -%}
{% for book in data.books %}
### {{ book.title }}

{{ book.description | safe }}
{% endfor %}

Zola creates a shortcode books that takes in the path argument, which points to a .toml file, so it can load lists of books with titles and descriptions.

Extra variables

When rendering the Markdown content, each heading will be automatically assigned a unique id, obtained by converting the heading text to a slug through processes like whitespace replacement and special character stripping.

We can manually specify an id as well as CSS classes using a {#id-placeholder .class-placeholder} suffix on the heading line.

We can generate anchor link for a heading by setting the insert_anchor_links variable on the section front matter page.

To link to a page or a heading in a page, create a link using @/ to point to the target Markdown file and # for the target heading. Note that the path to the file starts from the content directory (therefore @/blog/post.md links to content/blog/post.md).

Broken internal links are treated as errors.

Table of contents

Each section or page automatically generates a table of contents for itself based on the headers generated with Markdown and is available in the template through variables like page.toc and section.toc.

Syntax highlighting

We can enable Zola's built-in syntax highlighting by configuring it in config.toml.

highlight_code = true

Below is a list of some supported languages and their short names.

Inline vs classed highlighting

We can choose to use a highlighting scheme to get the colors directly encoded in the html file, or use the css color scheme to apply the CSS class definitions and thus enable dynamic switching of the highlighting theme.

Annotations

We can use additional annotations to customize how code blocks are displayed:

Taxonomies

Taxonomies are a way for us to group content according to custom-defined categories.

Zola can build a search index from the sections and pages content to be used by a JavaScript library such as elasticlunr or fuse.

Sass

Sass is a popular CSS preprocessor that adds special features like variables and nested rules to facilitate the maintenance of large sets of CSS rules.

Templates

Zola uses the Tera template engine.

Here are a few variables available on all templates except feeds and the sitemap:

Standard templates

Zola looks for three standard templates:

The homepage is a section so index.html also has access to the section variables just like section.html. The page.html template has access to the page variables.

Custom templates

We can create custom templates by creating an HTML file inside the templates directory (or its subdirectories). A custom template will be used when its path within the templates directory is explicitly specified in a page's template front-matter variable (or if it is included in another template that is applied).

Section

By default, Zola tries to load templates/index.html for content/_index.md and templates/section.html for other _index.md files.

Here are some common section variables available in the template:

Page

Here are some common page variables available in the template:

Table of contents

Both section and page template have a toc variable that corresponds to an array of headers. A header has the following fields:

See also

←Previous