Zola is a static site generator (SSG), similar to Hugo, Pelican, and Jekyll (for a comprehensive list of SSGs, please see Jamstack). It is written in Rust and uses the Tera template engine, which is similar to Jinja2, Django templates, Liquid, and Twig.
Content is written in CommonMark, a strongly defined, highly compatible specification of Markdown. Zola uses pulldown-cmark to parse markdown files. The goal of this library is 100% compliance with the CommonMark spec. It adds a few additional features such as parsing footnotes, Github flavored tables, Github flavored task lists and strikethrough.
SSGs use dynamic templates to transform content into static HTML pages. Static sites are thus very fast and require no databases, making them easy to host. A comparison between static and dynamic sites, such as WordPress, Drupal, and Django, can be found here.
To get a taste of Zola, please see the quick overview below.
Unlike some SSGs, Zola makes no assumptions regarding the structure of your site. In this overview, weβll be making a simple blog site.
This overview is based on Zola 0.17.1.
Please see the detailed installation instructions for your platform. With Zola installed, letβs initialize our site:
You will be asked a few questions.
> What is the URL of your site? (https://example.com):
> Do you want to enable Sass compilation? [Y/n]:
> Do you want to enable syntax highlighting? [y/N]:
> Do you want to build a search index of the content? [y/N]:
For our blog, letβs accept the default values (i.e., press Enter for each question). We now have a myblog
directory with the following structure:
For reference, by the end of this overview, our myblog
directory will have the following structure:
βββ config.toml
βββ content/
β βββ blog/
β βββ _index.md
β βββ first.md
β βββ second.md
βββ sass/
βββ static/
βββ templates/
β βββ base.html
β βββ blog-page.html
β βββ blog.html
β βββ index.html
βββ themes/
Letβs start the Zola development server within the newly created myblog
directory:
> Successfully )
)
If you point your web browser to http://127.0.0.1:1111, you should see a βWelcome to Zolaβ message.
Letβs make a home page. To do this, letβs first create a base.html
file inside the templates
directory. This step will make more sense as we move through this overview.
MyBlog
{% block content %} {% endblock %}
Now, letβs create an index.html
file inside the templates
directory.
{% extends "base.html" %}
{% block content %}
This is my blog made with Zola.
{% endblock content %}
This tells Zola that index.html
extends our base.html
file and replaces the block called βcontentβ with the text between the {% block content %}
and {% endblock content %}
tags.
Now letβs add some content. Weβll start by making a blog
subdirectory in the content
directory and creating an _index.md
file inside it. This file tells Zola that blog
is a section, which is how content is categorized in Zola.
In the _index.md
file, weβll set the following variables in TOML format:
Note that although no variables are mandatory, the opening and closing
+++
are required.
blog.html
in the templates
directory as the template for listing the Markdown files in this section. blog-page.html
in the templates
directory as the template for individual Markdown files. For a full list of section variables, please see the section documentation. We will use title = βList of blog postsβ in a template (see below).
Letβs now create some more templates. In the templates
directory, create a blog.html
file with the following contents:
{% extends "base.html" %}
{% block content %}
<!-- If you are using pagination, section.pages will be empty. You need to use the paginator object -->
{% for page in section.pages %}
{{ page.title }}
{% endfor %}
{% endblock content %}
{{ section.title }}
As done by index.html
, blog.html
extends base.html
, but this time we want to list the blog posts. The title we set in the _index.md
file above is available to us as {{ section.title }}
. In the list below the title, we loop through all the pages in our section (blog
directory) and output the page title and URL using {{ page.title }}
and {{ page.permalink | safe }}
, respectively. We use the | safe
filter because the permalink doesnβt need to be HTML escaped (escaping would cause /
to render as /
).
If you go to http://127.0.0.1:1111/blog/, you will see the section page for blog
. The list is empty because we donβt have any blog posts. Letβs fix that now.
In the blog
directory, create a file called first.md
with the following contents:
The title and date will be available to us in the blog-page.html
template as {{ page.title }}
and {{ page.date }}
, respectively. All text below the closing +++
will be available to us as {{ page.content }}
.
We now need to make the blog-page.html
template. In the templates
directory, create this file with the contents:
{% extends "base.html" %}
{% block content %}
{{ page.title }}
{{ page.date }}
{{ page.content | safe }}
{% endblock content %}
Note the
| safe
filter for{{ page.content }}
.
This should start to look familiar. If you now go back to our blog list page at http://127.0.0.1:1111/blog/, you should see our lonely post. Letβs add another. In the content/blog
directory, letβs create the file second.md
with the contents:
Back at http://127.0.0.1:1111/blog/, our second post shows up on top of the list because itβs newer than the first post and we had set sort_by = βdateβ in our _index.md
file. As a final step, letβs modify our home page to link to our blog posts.
The index.html
file inside the templates
directory should be:
{% extends "base.html" %}
{% block content %}
This is my blog made with Zola.
Click here to see my posts.
{% endblock content %}
This has been a quick overview of Zola. You can now dive into the rest of the documentation.