Rust 製の静的サイトジェネレータ Zola のはじめかた


Zola なに?

  • Rust 製の静的サイトジェネレータ
  • テンプレートエンジンには、こちらも Rust 製の Tera を使用(Jinja2 とだいたい同じ文法)
  • シングルバイナリで扱いやすい

www.getzola.org


インストール

MacOSの場合

$ brew install zola

Windows の場合

$ winget install getzola.zola

シングルバイナリなので、https://github.com/getzola/zola/releases からダウンロードしてパスに追加するだけでも良い


プロジェクト生成

> .\zola.exe init example
Welcome to Zola!
Please answer a few questions to get started quickly.
Any choices made can be changed by modifying the `config.toml` file later.
> 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]:

Done! Your site was created in path/to/example

Get started by moving into the directory and using the built-in server: `zola serve`
Visit https://www.getzola.org for the full documentation.

ディレクトリ構成は以下のようになる。

example
├─ content     ・・・ Markdown でコンテンツを作成
├─ sass        ・・・ Sass ファイルを配置
├─ static      ・・・ 画像など静的ファイルを配置(contentディレクトリに直接配備してもOK)
├─ templates   ・・・ 各ページのひな形HTML(Tera)を配置
├─ themes      ・・・ 公開されている各種テーマをインストール
└─ config.toml ・・・ Zola 設定ファイル

config.toml は以下の内容で初期生成される。

# The URL the site will be built for
base_url = "https://example.com"

# Whether to automatically compile all Sass files in the sass directory
compile_sass = true

# Whether to build a search index to be used later on by a JavaScript library
build_search_index = false

[markdown]
# Whether to do syntax highlighting
# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola
highlight_code = false

[extra]
# Put all your custom variables here

config.toml の設定項目はhttps://www.getzola.org/documentation/getting-started/configuration/


基本的な構成

Zola では、サイトを section と page で構成する。

content の中に作成したディレクトリに _index.md が存在する場合に section となる。

section の中に作成した複数のマークダウンファイルが page になる。

example
├─ content
│     ├─ _index.md
      ├─ section01
      │    ├─ _index.md
      │    ├─ page01.md
      │    └─ page02.md
      └─ section02
            ├─ _index.md
            ├─ page01.md
            └─ page02.md

上記のような構成で、zola build すると、public ディレクトリに以下のような構成のHTMLファイルが生成される。

example
├─ public
│     ├─ index.html
      ├─ section01
      │    ├─ index.html
      │    ├─ page01
      │    │    └─ index.html
      │    └─ page02
      │          └─ index.html
      └─ section02
            ├─ index.html
            ├─ page01
            │    └─ index.html
            └─ page02
                  └─ index.html

_index.mdpage01.md といったファイルで自身のコンテンツをマークダウンとして記載する。

マークダウンファイルは、他の SSG と同じようにフロントマターで設定値を定義することができる。つまり以下のような感じ。

+++
title = "List of blog posts"
sort_by = "date"
template = "blog.html"
page_template = "blog-page.html"
+++

This is my first blog post.

セクションに定義できるフロントマターは https://www.getzola.org/documentation/content/section/#front-matter を参照

ページに定義できるフロントマターは https://www.getzola.org/documentation/content/page/#front-matter を参照


テンプレート

section や page に適用するHTMLのテンプレートは templates 以下に html ファイルを作成することで定義する(Sass は sass ディレクトリに作成)。

テンプレートには Rust 製のテンプレートエンジンである Tera が使われる。

Tera の文法については以下を参照。

blog1.mammb.com

標準的には以下のように html を作成する。

example
├─ templates
│     ├─ index.html
      ├─ section.html
      └─ page.html

例えば、index.html に全体に適用するHTMLを定義する。

<!DOCTYPE html>
<html lang="en">
    <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      {% block js %}
      {% endblock js %}
    </head>

    <body>
      <section class="section">
        <div class="container">
          {% block content %} {% endblock content %}
        </div>
      </section>
    </body>
</html>

{% block content %} {% endblock content %} の中に、別途定義したコンテンツが埋め込まれることになる。

section.htmlpage.html は section と page 用のテンプレートで、先に定義した index.htmlextends で拡張して流用することができる。

{% extends "index.html" %}

{% block content %}
    <h1>{{ page.title }}</h1>
    {{ page.content | safe }}
{% endblock content %}

section と page に適用されるテンプレートは、デフォルトで section.htmlpage.html となっているため、以下のようなマークダウンを content の中に書けば、

+++
title = "My title"
+++

My content

以下のようなHTMLが生成される。

<!DOCTYPE html>
<html lang="en">
    <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>

    <body>
      <section class="section">
        <div class="container">
          <h1>My title</h1>
          My content
        </div>
      </section>
    </body>
</html>

テンプレートを指定したたい場合は、マークダウンのフロントマターに template を指定することで個別に設定することもできる。

+++
title = "Index page"
template = "my-template.html"
+++

## This is my first post.


テーマ

section.htmlpage.html を一から自身で作成することはほとんどない。

通常は、公開されているテーマから選択し、カスタマイズして利用することになる。

https://www.getzola.org/themes/

テーマというより templates のテンプレートといった感じ。

テーマは、themes ディレクトリの中で git clone して導入し、config.toml に設定する。

例えば、book テーマの場合は、以下のようにインストールし、

$ cd themes
$ git clone https://github.com/getzola/book.git

config.toml に以下を追加する

theme = "book"

その他のテーマは https://github.com/getzola/themesにまとまっている。

themes の中には、templatesstatic などが自身のプロジェクトと同じような構成となっている。つまり以下のような感じ。

example
├─ content
├─ sass
├─ static
├─ templates ・・・ (1)
├─ config.toml
└─ themes
     └─ book ・・・ book テーマ
          ├─ sass
          ├─ static
          ├─ templates
          └─ config.toml

これらのテーマは、(1) のtemplates に、テーマのファイルを継承した html を作成することでカスタマイズする。themes 内のファイルを直接編集することは推奨されていない(ホットリロードの対象にもならない)。

テーマの提供するテンプレートは、カスタマイズ可能なように {% block before_menu %} {% endblock before_menu %} のように各種フックポイントが用意されているので、これを自身のテンプレートで設定する。


Zola 利用の流れ

  • zola init でプロジェクトディレクトリを生成
  • テーマを選び、インストール
  • content の中に section と page の .md ファイルを作成
  • zola serve でローカルサーバを起動して確認
  • content の中に section と page の .md ファイルを加筆
  • 必要に応じてテンプレートを修正
  • zola build でビルドし、生成された public ディレクトリの中身をホストサーバにデプロイ


Shortcodes

Zola ではマークダウンで表現しにくいHTMLを Shortcodes という仕組みで関数化して利用することができる。

例えば、Mermaid で図を書きたい場合、book テーマを使っているとすると、 templates/index.html を以下のようにして book テーマを拡張し、mermaid.min.js を初期化する。

{% extends "book/templates/index.html" %}

{% block js %}
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>
{% endblock js %}

templates/shortcodes ディレクトリ内に mermaiddiagram.html を用意して以下のように定義する。これが Shortcodes となる。

<div class="mermaid">
{{ body }}
</div>

自身のコンテンツのマークダウンで以下のように mermaiddiagram.html を使うことができ、Mermaid 記法の図を埋め込むことができる。

{% mermaiddiagram() %}
  ここに Mermaid 記法を使える
{% end %}


補足

Zolaは、末尾がスラッシュとなった、 pretty URL と呼ばれるURLを生成します(例えば /about/)。

多くのウェブサーバーでは、このようなURLへのリクエストは暗黙的に/about/index.html と解釈されるが、このディレクトリインデックス機能が動作しなかったり、異なる設定がなされている場合、ページが正しく表示されないケースがあります。

現状 Zola には、この問題を回避するための構成オプションがありません。 これを解消するため、モンキーパッチを当てたフォークを作成しておいたので、必要な方は参考にしてください。

github.com