Zola Content Types

Basic Content format

Content is usually stored in .md files.

Specifically, content is written in CommonMark via pulldown-cmark. Further, it optionally supports parsing footnotes, Github flavored tables, Github flavored task lists and strikethrough.

title: YAML frontmatter

# title
## subtitle

Text with [link](

* listitem 
* listitem

| foo | bar |
| --- | --- |
| baz | bim |

- [ ] foo
- [x] bar

Hello, ~wrld~ world! and signals that the directory is a section1. The other *.md files are pages. signals that the directory is a page2 with colocated assets3. It should be the only *.md file in the directory.


YAML or TOML frontmatter needs to be embedded into most md files.

title: Zola Macros
slug: zola-macros
date: 2023-07-12
title = "Zola Macros"
slug = "zola-macros"
date = 2023-07-12T00:00:00.000Z

*.md files in the content directory

Zola indexes all *.md-files in the content directory and makes them available in the following ways.

  • via the get_page(path=*) function, if you know the path
  • via the containing section or taxonomy

other files

are not indexed and are not available via get_page(path=*). If you need the final URL of the file it needs to be constructed.

for colocated assets3 constructing a direct link would look like this:

<a href="{{page.permalink}}{{page.assets[i]}}"> linktext </a>

For assets not colocated, but stored next to the content:

<a href="{{page.permalink | split(sep="/") | slice(start=0, end=-1) | join(sep="/") }}{{page.assets[i]}}"> linktext </a>

However they are copied to the final site as a static asset, if it's not in ignored_content4 in the config file:

image files

{% set page_dir = page.components | slice(start=0, end=-1) | join(sep="/") %} {% set image_path = page_dir ~ "/" ~ page.extra.image %}

data files

Zola supports file types toml, json, csv, bibtex, yaml/yml, and xml via load-data()5 in templates and shortcodes. Only UTF-8 encoding is supported.

Zola Macros


Zola is a fast static site generator in a single binary with everything built-in 1 2. It uses the Tera template engine, which is similar to Jinja2, Django templates, Liquid, and Twig3.

Generic Macros

Macros are a way to reuse common parts of templates. They are similar to functions in programming languages. You can define macros in a separate file and import them in your templates. Macros can take arguments and return some HTML ref3.

Here is an example of a macro that creates a simple card component3:

Using the site structure:

 - page.html
 - macros.html
{% macro card(title, text, image) %}
<div class="card">
{% if image %}
<img src="{{ image }}" alt="{{ title }}">
{% endif %}
<div class="card-content">
<h3>{{ title }}</h3>
<p>{{ text }}</p>
{% endmacro card %}

You can save this macro in a file called macros.html and import it in your template like this:

{% import "macros-gallery.html" as macros %}

{{ macros::card(title="Zola", text="A fast static site generator", image="zola.png") }}

This will render a card with the title, text and image you provided.

You can learn more about macros and other features of Zola from its documentation3.

Macros can't really provide return values for other templates but they can be embedded in specific cases.

Image Resizing and Content Colocation

You can resize images in Zola using the built-in function resize_image, which is available in template code as well as in shortcodes. The function takes the following arguments:

  • path: The path to the source image relative to the content directory.
  • width and height: The dimensions in pixels of the resized image. Usage depends on the op argument.
  • op (optional): Resize operation. This can be one of: "scale", "fit_width", "fit_height", "fit", or "fill". The default is "fill".
  • format (optional): Encoding format of the resized image. May be one of: "auto", "jpg", "png", or "webp". The default is "auto".
  • quality (optional): JPEG or WebP quality of the resized image, in percent. Only used when encoding JPEGs or WebPs; for JPEG default value is 75, for WebP default is lossless.

The function returns an object with the following schema:

  • url: The final URL for that asset
  • static_path: The path to the static asset generated
  • width: New image width
  • height: New image height
  • orig_width: Original image width
  • orig_height: Original image height

For example, to resize an image called logo.png to 200 pixels wide and 100 pixels high, you can use this code in your template:

 - imagedisplay.html


{% set resized = resize_image(path="logo.png", width=200, height=100) %}
<img src="{{ resized.url }}" alt="Logo" width="{{ resized.width }}" height="{{ resized.height }}">

You can learn more about the resize operations and how Zola performs image processing from its documentation4.

As for storing images next to the content, Zola supports assets co-location. This means that you can place any static files (such as images, CSS, JavaScript, etc.) in the same directory as your content files and they will be copied to the output directory with the same structure5. For example, if you have a page called blog/ and an image called blog/my-image.jpg, they will be copied to public/blog/my-post/index.html and public/blog/my-image.jpg, respectively.

You can access the co-located assets using the page.permalink variable, which is the full URL of a page without a trailing slash5. For example, to display an image called my-image.jpg that is co-located with a page called, you can use this code in your template:

Direct use of an image

<img src='{{ page.permalink ~ "my-image.jpg" }}' alt="My image">

You can learn more about assets co-location and other features of Zola from its documentation5.