静的ブログサイトを Zola で作る
Rust 製 SSG ツール Zola で作ったウェブページを GitHub Actions を使って GitHub Pages にホストする
Categories: web
Tags: zola ssg github-pages github-actions rust
Zola🔗
Zola は SSG - Static Site Generator (静的サイト生成)のツールです。 Rust で書かれていることによる高速なビルドと豊富な機能が特徴です。
似たツールとしては Golang 製の Hugo があります。 Hugo のほうが歴史も長く枯れており知名度と人気があるため Theme (デザインのテンプレート)が豊富に公開されています。 また、ビルド速度は Zola より Hugo のほうが速いようです。 とはいえ Zola もその他の言語の SSG に比べると十分に速いです。 ざっくり体感として、数百ページを超えるとビルドのラグを少し感じなくもないです。 数千ページを超えると数秒以上かかりました。 Hugo だとその程度の量は秒未満で処理できることが多いです。 本当にページが莫大に増える見込みがあるようであれば、事前にページを大量生成してビルド時間を疑似体験・簡易比較しておいてもいいかもしれない(けど、個人的には気にするほどではないと思う)。
Hugo にない Zola の特徴的な機能としては 検索機能 があります。 ビルド時に検索のインデックスを静的に生成し、JS から使うことができるようにすることが可能です。 ただし、私が試した限りでは日本語でインデックスを作ることができませんでした。 GitHub の README に Hugo との機能比較がより詳細に記述されています。
Install Zola🔗
# Mac
brew install zola
# Windows
scoop install zola
# or
choco install zola
zola -V
# => zola 0.14.1
Init Zola🔗
zola init <your_project_name>
cd ./<your_project_name>
zola serve
http://127.0.0.1:1111 がタイムアウトせずに反応が返ってくればこの時点では OK 。 以下のようなディレクトリ構成になっているはず。
$ tree -L 1
.
├── config.toml # Zola の設定ファイル。TOML フォーマット。
├── content # ブログ記事などのコンテンツのファイルをおさめる。 .md など。
├── sass # SASS をおさめる。 SASS 以外は無視される。 sass/foo/bar.sass -> public/foo.bar.css と変換される。
├── static # 画像や JS などの静的なファイルおさめる。
├── templates # テンプレートのファイルをおさめる。 Rust の Tera フォーマット。
└── themes # Theme という、有志が公開してくれているデザインテンプレートをおさめる。 git submodule でいれる。
5 directories, 1 files
theme を適用する。 今回は RatanShreshtha/DeepThought を使わせてもらいました。 RatanShreshtha さん、ありがとうございます。
git init
git submodule add https://github.com/RatanShreshtha/DeepThought.git themes/deep-thought
設定オプションは
- Zola 共通のは https://www.getzola.org/documentation/getting-started/configuration/
- この Theme 特有のは https://github.com/RatanShreshtha/DeepThought#theme-options
あたりに全部乗ってるのでまるまるコピーすれば OK 。config.toml
の [extra]
以下が Theme 特有の設定オプションの箇所。
base_url = "https://<github_id_or_organization_name>.github.io/<repository_name>"
title = "Hoge Blog"
description = "ほげブログ"
default_language = "en"
theme = "deep-thought"
output_dir = "public"
compile_sass = true
minify_html = true
taxonomies = [
{ name = "categories", feed = true, paginate_by = 10 },
{ name = "tags", fees = true, paginate_by = 10 },
]
build_search_index = true
[markdown]
highlight_code = true
highlight_theme = "zenburn"
# When set to "true", emoji aliases translated to their corresponding
# Unicode emoji equivalent in the rendered Markdown files. (e.g.: :smile: => 😄)
render_emoji = true
external_links_target_blank = true
external_links_no_follow = true
external_links_no_referrer = true
[link_checker]
# Skip link checking for external URLs that start with these prefixes
skip_prefixes = []
# Skip anchor checking for external URLs that start with these prefixes
skip_anchor_prefixes = []
[extra]
{ code = "en", nav_items = [
{ url = "$BASE_URL/", name = "Home" },
{ url = "$BASE_URL/posts", name = "Posts" },
{ url = "$BASE_URL/docs", name = "Docs" },
{ url = "$BASE_URL/tags", name = "Tags" },
{ url = "$BASE_URL/categories", name = "Categories" },
]},
]
# Author details
[extra.author]
name = "<your_name>"
[extra]
を除く部分では base_url
のみが必須指定要素で、他はなくても OK 。
{ url = "$BASE_URL/posts", name = "Posts" },
という設定があるが、ここがこの Theme におけるサイトのヘッダの記事一覧に対応している。
これにあわせて、記事を作成してみる。
touch contetnt/posts/2021-11-13-hello-zola.md
+++
title = "Hello, World"
description = "こんにちは、世界"
draft = false
[taxonomies]
tags = ["hoge", "fuga"]
categories = ["foo"]
[extra]
toc = true
+++
## 記事本文はここにマークダウンで記述していく・・・
### 111
あああ
### 222
いいい
### 333
ううう
Front Matter で指定できる内容の一覧は https://www.getzola.org/documentation/content/page/#front-matter を参照。
touch contetnt/posts/_index_.md
これは、/posts URL にアクセスしたときに記事の一覧を出すのに作っておかなければならない。
Front Matter description
のディスクリプションは記事一覧ページで表示される。
このあたり Hugo とは役割が違う。
+++
description = "記事の一覧です。"
+++
_index.md
で指摘できる内容の一覧は https://www.getzola.org/documentation/content/section/#front-matter を参照。
ローカルで確認🔗
zola serve --drafts
で起動。 --drafts
オプションは Front Matter で draft = true
となっている記事も含めてビルドするという指定。
通常、本番ビルド時には付けない。
http://127.0.0.1:1111 を開いてページが表示され、ヘッダから記事をたどって見ることができていれば OK 。
zola serve
している間は public
というフォルダができていることに気付く。
Zola ではビルドした成果物はデフォルトではそこに出力されるので、Git 管理から除外しておく。
echo "/public/" > .gitignore
次に GitHub Actions のビルド用ワークフローを作成
touch .github/workflows/build-and-deploy-gh-pages.yml
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
name: Build and deploy GH Pages
jobs:
build:
runs-on: ubuntu-latest
if: github.ref != 'refs/heads/main'
steps:
- name: checkout
uses: actions/checkout@v2
- name: build only
uses: shalzz/zola-deploy-action@v0.14.1
env:
TOKEN: ${{ secrets.PAT }}
BUILD_DIR: .
BUILD_ONLY: true
build-and-deploy:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: checkout
uses: actions/checkout@v2
- name: build and deploy
uses: shalzz/zola-deploy-action@v0.14.1
env:
TOKEN: ${{ secrets.PAT }}
BUILD_DIR: .
PAGES_BRANCH: gh-pages
詳細は https://github.com/shalzz/zola-deploy-action#usage を参照。
さて、上記ワークフローはビルド成果物を gh-pages
ブランチにコミットとプッシュする挙動になっている。
その権限を Actions に与えるために GitHub の Personal Access Token を払い出して、このリポジトリの GitHub Secrets に登録しておく。
Token の Scope は repo
とかでいい。
上記の例であれば PAT
という名前で Secrets に登録している。
- Personal Access Token の設定 - https://github.com/settings/tokens
- Secrets の登録画面 - https://github.com/<your_github_id>/
/settings/secrets/actions
最後に忘れずに
touch .nojekyll
しておく。GitHub Pages はもともと Jekyll 専用だったので、これをしないと Jekyll 以外の SSG をホスティングできない仕様になっている。
プッシュ & ビルド & デプロイ🔗
GitHub に Push する。
https://github.com/<your_github_id>/gh-pages
ブランチが作成され、ビルド成果物一式がそこに入っているはず。
https://github.com/<your_github_id>/
注意点・はまりどころ🔗
zola serve
がちょっとしたファイル変更でよく落ちる。再起動(再実行)すればいいだけだが、かなり面倒。
categories
や tags
の配列の要素に空文字 ( ""
) があるとバグるので、気を付ける。
hugo のように新規記事作成サブコマンドやそのときに使えるひな形のような機能がない。僕はこんな感じのコマンドを Makefile に置いている。
cp dev/posts/template.md content/posts/`date "+%Y-%m-%d-"`generated-new-post.md
まとめ🔗
SSG はほとんどのユースケースでは、 Hugo を選択するのが無難ではないだろうか。 Hugo は機能も Theme も豊富で、枯れていて、なによりボリュームが大きくなっても ビルドが爆速 。
しかし、 Zola も実用上はそこまで遜色ない。検索機能など欲しい機能が Zola にしかないなら選択肢になると思う(ただ、日本語が、、)。
書くのが疲れてきたので、Google Domain の設定は別エントリに後日まとめる。
(追記) 続き を書いた。