This is the official Baguette website repository.
Go to file
Karchnu 209cc4686f Simple tests. 2022-05-06 19:14:32 +02:00
content Simple tests. 2022-05-06 19:14:32 +02:00
sass BaguetteOS: new pages (not yet referenced). 2020-05-18 15:58:17 +02:00
static A few images. 2020-05-01 18:34:41 +02:00
themes Simple tests. 2022-05-06 19:14:32 +02:00
.gitignore First commit 2020-03-29 17:26:12 +02:00
.gitmodules Move templates to dedicated theme 2020-04-18 00:46:51 +02:00
LICENSE Initial commit 2020-03-29 11:23:58 -04:00 Add credits for CSS speech bubble 2020-04-01 17:12:20 +02:00
config.toml Fixed style, theme, spec files explanations. 2020-04-23 19:44:32 +02:00


This repository contains a prototype for a dnsmanager homepage. Below, you will find instructions on how to use it and how to contribute to it.

On a high-level, this website is made for Zola using the water.css stylesheet to decorate the semantic HTML on all pages. Currently this website does:

  • static pages
  • blog articles
  • internationalization (i18n) with support for localized dates

The current structure is:

  • content/ - individual pages to be rendered (Markdown + colocated files)
    • blog/ - a section rendering its subchildren
    • blog/YYYY/ - transparent subsections per year for better browsability
    • blog/YYYY/foobar/ - individual blogposts (, their translations (, and colocated assets (eg. images)
  • sass/ - where the SASS stylesheets reside
    • style.scss - for customizations over raw water.css
    • _mobile.scss - for mobile-specific customizations
  • static/water.css - 3rd party stylesheet for basic styles
  • templates/ - where HTML templates are
    • index.html - the main template, that renders the index page and serves as a basis for other templates
    • page.html - the template used for single pieces of content (static pages, blogposts)
    • section.html - the template used for lists of content (blog, tags)
    • widgets.html - a few macros to make everything easier


If you want to contribute to this website, you first need to setup the Zola static site generator. You can either download a pre-compiled package, or compile the program from source using a Rust compiler.

Package setup

For GNU/Linux users, there's a snap package available (no Flatpack yet):

$ snap install --edge zola

On Mac, you can install zola using Homebrew:

$ brew install zola

Alternatively, you can install a precompiled binary from the Github releases:

$ wget
$ tar xf zola*.gz && rm zola*.gz
$ sudo cp zola /bin/ && rm ./zola

Compile from source

If you don't have rustc (the official Rust compiler) and cargo (the related package manager) setup, you can either install them through your distribution, or get the latest version directly from the Rust project using rustup. If you're using Nix or GNU Guix for package management, you can also use those to setup cargo and rustc.

If you're running Debian buster or later, you can simply do:

$ sudo apt install cargo rustc

If your distribution does not have a package for Rust, you can download rustup and use it to setup a stable compiler.

Once Rust is setup, we can download Zola's source and compile it. Make sure you have git installed (sudo apt install git) before you proceed:

$ git clone
$ git checkout v0.10.1
$ cargo install --path=.

The last command (cargo install) not only compiles the project, but copies the generated binary to ~/.cargo/bin, which should already be in your $PATH after setting up Rust. You can check that zola is correctly setup by running it with the --version argument:

$ zola --version
zola 0.10.1

If you have an error message such as bash: zola: command not found, it is neither a problem with the Zola project or this website. It means the cargo bin directory is not in your $PATH for executable programs. A few things you can try:

  • logging out then logging back in, if you've just setup rust, could apply changes to your $PATH
  • appending export PATH="$HOME/.cargo/bin:$PATH" to your ~/.profile

If you still fail at running zola, you should read your distro's documentation or ask a friend.

Compiling the site

Now that zola is up and running, we can use it to build our website. When building a site, zola needs to know about its final address in order to generate links.

$ git clone
$ cd dnsmanager-website
$ zola build

zola will then place all the generated files in the public/ folder. Note that zola needs to know about its base URL in order to generate links. By default, the base_url is defined in config.toml for the website's current address. You can pass another base URL as an argument to zola using the -u flag, and a different output folder using the -o flag:

$ zola build -u "http://localhost:1337" -o public_local/
$ zola build -u "http://acab13122131baca.onion" -o public_onion/
Building site...
-> Creating 7 pages (3 orphan), 5 sections, and processing 0 images
Done in 407ms.

Live reload

When updating the website content and stylesheets, you can run zola serve to setup a local web server with a preview of your changes:

Building site...
-> Creating 7 pages (3 orphan), 5 sections, and processing 0 images
Done in 730ms.

Web server is available at

Listening for changes in /home/user/Desktop/Sites/dnsmanager/{content, config.toml, static, templates, themes, sass}
Press Ctrl+C to stop

You can then access the website at the address zola will output, usually

Note that this live reload feature does not entirely play well with the macro system at the moment, so if you see some changes in your work are not reflected on the preview, don't hesitate to kill zola using Ctrl-c and then start it again.


In this section, we explain how to get started contributing to this website. We will introduce how to edit content for the website (edition), how to translate the website (translation), and how to hack on the templates (webdesign).

It is assumed you are familiar with the git ecosystem and you can submit a patch either through a pull request on the project's forge or via email to one of the maintainers. If you are not at ease with git, please ask a friend to teach you so we can cooperate and build awesome things together!


Create a new page

Create a new folder in the content/ folder. In this folder, place an file for the English page, and one file per translation like (see translating pages).

Each post has some TOML metadata attached. This is called a frontmatter, and the available variables are described in the Zola documentation. The frontmatter is mandatory although it can be empty, and should contain at least the title of the page:

title = "About the project"

We want to decentralize everything.

Create a new blog post

Creating a blogpost is very similar to creating any page, but it is important that a blogpost has a date frontmatter key set following the format year-month-day like so:

title = "Long live the Commune!"
date = 2020-03-29

They may kill us, but they may never kill our ideas.

Blogposts are organized per year to ensure the blog/ folder does not become too bloated. So in 2020, your posts should go inside content/blog/2020/your-article/ folder.

The post summary is taken from the first part of the article. If you add a <-- more --> tag, everything before that will be treated as the post summary.

Attach files to a page

As previously explained, every page has its own folder. Any file you place inside that is not a Markdown file will be copied alongside the generated page. Asset colocation is further discussed in the Zola documentation.

This means you can directly link the file from the Markdown page using a relative link:

title = "Hypothetical demo"

[Link to latest incredible theory](important_stuff.pdf)

![Photo of Frantz Fanon](frantz_fanon.jpg)

A link to another page can use the @ sign to signify the link target is found in the content folder, as explained in the docs on internal links:

title = "New post"

As explained in the [introduction](@/introduction/, we should abolish the government.

This allows to keep links between pages valid when their URLs change.

Transitioning to a new year

If a new year is starting, you may want to create a new folder for the year and copy the placeholder section files from the past year into the new folder (one file per available language):

$ mkdir content/blog/2021
$ cp content/blog/2020/_index.*.md content/blog/2021


Add a new language

Adding a language is not hard, but it takes a few steps. The example here takes fr as language code for french translations, just replace it with your own language.

In config.toml:

  • declare the language in the languages variable: {code = "fr", rss = true}
  • translate the basic template strings in the translations section:
source = "Source de cette page"
readmore = "Lire la suite"

Translating pages

If you want to translate a page in the content folder, the translated page should have the language code before the .md extension, like The homepage is translated from content/, and some common parts (such as the navigation bar) are located in the content/_common folder.

Note: don't forget to copy the section file for year-folders in the blog, otherwise no article will appear on your language's blog. You can safely copy content/2020/ to, say, content/2020/


As a webdesigner, you should look at the files in sass/ folder (for the style sources), and templates/ folder (for tera templates.

If you would like to change the water.css stylesheet, refer to the water.css README. Also, if you need to make deeper changes to water.css, please fork water.css instead of applying local changes here.


Apart from the upstream water.css, there are two stylesheets for the website, with style.scss being the main one. _mobile.scss is imported into style.scss, then both are rendered to style.css.

The stylesheets are written in the SCSS language, which is a superset of CSS that compiles to bare CSS. Here is a quick introduction to SASS/SCSS styling.

If you want to make changes for different viewports (such as mobile phones), please use a dedicated stylesheet. All changes for mobile-related responsiveness should live in _mobile.scss.


The templates for Zola use the tera template engine. If you are familiar with jinja templates, they are very similar systems.

You may be looking for how to use control structures such as conditions, loops, macros and includes.


Using variables:

{# Here's how to write comments #}
{% set variable = 2 + 2 %}
My variable is {{ variable }}

Using a function:

<link rel="stylesheet" href="{{ get_url(path="static/water.css") }}">

Using a macro:

{% import "widgets.html" as macros %}
The current language's index page lies in {{ macros::i18n_page(path="") }}


index.html is the main template that gets rendered for everypage. It renders the global page skeleton according to the language requested. In addition, it defines a few blocks that are overriden by children templates:

  • title: the raw page title
  • main: the main content

Both page.html and section.html extend index.html. They are children of index.html, one for rendering individual pieces of content, the other for rendering lists of content.

Custom macros

The widgets.html file contains a few useful macros. The macros related to translation/localization are documented later in the translations in templates section.

menu macro

The menu macro builds a menu from a Markdown file, where each entry is separated by a thematic break. This pattern for static site generators is explained in this article. The menu macro assumes that the HTML generated by every entry will have it wrapped by paragraph tags (<p>...</p>) and will strip that.

Here's an example menu file in content/


First entry


Second entry


Third entry

You can then summon this menu like this:

{% import 'widgets.html' as widgets %}
{{ widgets::menu(content="") }}

Translations in templates

Localized string

If you want to use a translation string defined in the translations section of the config, you can use the trans function, like so:

{{ trans(key="readmore", lang=lang) }}

Conveniently, the lang variable is automatically set by Zola in most contexts.

Localized path

In case you need to interact with a localized page, you will need to replace the last .md with There is a widgets::i18n_path for that. You can use it like this:

{% import "widgets.html" as widgets %}
{{ widgets::i18n_path(path="@/blog/") }}
Localized page content

If you wish to directly extract the contents of a localized page, without any regards to its frontmatter, you can use the i18n_content macro:

{% import "widgets.html" as widgets %}
{{ widgets::i18n_content(path="@/blog/") }}
Localized URL

If you need to get the localized URI for path on the website, you can use the i18n_url macro which acts as a wrapper around the get_url function:

{% import "widgets.html" as widgets %}
<a href="{{ widgets:i18n_uri(path = "rss.xml") }}">RSS</a>


If something is missing for you, please open an issue.

  • blog
    • basic blog
    • pagination
    • summaries
  • i18n
    • pages
    • blogposts
    • other strings in the templates
    • localized RSS links
    • links to navigate between languages
    • support generic default_language (not en by default)
    • localized title/description for RSS
    • setup/configuration guide
    • contribution guide (edition, translation, webdesign)
    • credits
    • quickstart guide for git
  • other
    • ASCII banner does not overflow
    • translation bubble fits nicely on all sizes


This libre website would not have been possible without: