Chienomi

Jykillより推せる!! PureBuilder Simply (1.7)

開発::util

PureBuilder Simplyとは?

PureBuilder Simplyは静的ウェブサイトの構成システム(ジェネレータ)である。

レイヤー的にはWordPressやMovableTypeなどのCMSを置き換えるものであり、同様のソフトウェアとしてはJykillやPelican、その他あまり有名ではないソフトウェアがいくつか存在する。

PureBuilder Simplyは私が開発・保守しているソフトウェアであり、GitHubでApache License 2.0にて公開している

PureBuilder Simplyの原型は2005年に開発されたACCSであるが、現在の実装となったのは2017年で、“PureBuilder Simply”の名を関するソフトウェアとしては3代目となる。 前作であるPureBuilder2とは互換性は全くなく、完全に新しいソフトウェアとして書き直された。

初代PureBuilderは2014年に開発され、このときはZshによるユーティリティスクリプトとなっており、ドキュメントはPureDocという形式で書くものだった。 その後PureBuilderは一般的なドキュメント記法であるMarkdownをサポートするようになり、2015年にRubyで書かれたPureBuilder2がデビューする

PureBuilder2はRubyコードとしてサイトを書く(ドキュメント自体はPureDocまたはMarkdownで書く)ことを支援するものだった。 しかし、2017年に登場したPureBuilder SimplyはMarkdownまたはReSTructured Textでサイトを書き、あとは設定ファイルがあれば良いという形に大きく変化した。

PureBuilder Simplyにおいて大きな転換となったのが、PureBuilder2ではKramdownを用いて自前でMarkdown処理をしていたものを、Pandocを利用して生成するように変更したことだ。 これによって複雑化した実装をシンプルなアプローチの集合に変更できている。

PureBuilder Simplyの開発動機の大きな点としては、「PureBuilder2のサイト制作がしんどい」ということであった。

Mimir Yokohamaの業務としてPureBuilder2によるサイト構築を提供していた1が、PureBuilder2の構築及び構成変更は結構手間がかかり、あんまりやりたいと思えないものだったし、Mimir Yokohamaのウェブサイト構築サービスは非常に安価2であるため、もう少し楽にやりたかったし、PureBuiler2は保守も結構やりづらかった。

こうしたことから、「楽に」「緻密に」「汎用性を持って」構築できるようにPureBuilder Simplyが開発された。そして、PureBuilder Simplyはこの世界で最も素晴らしいウェブサイト構築システムとなったのである。3

PureBuilder Simplyによるサイト構築 (概要)

構築手順についてはMimir Yokohamaのウェブサイトに記事があり、動画も公開されている

基本的には

  • PureBuilder Simplyを導入する
  • ウェブサイトのドキュメントディレクトリと、ビルドされたHTMLを配置するディレクトリを作成する
  • ドキュメントディレクトリに.pbsimply.yamlを作成する
  • テンプレートを用意する

の4手順である。

導入は、JykillのようにRubyGemsにはなっておらず、GitHubからとってくる必要があるが、その場合でも単純にRubyのスクリプトファイル3つを実行可能にするだけで十分である。 出来は良いので将来的にはGem化する可能性もあるが、Gem化することでハードルが下がるわけではないのでそれほど積極的なわけではない。

.pbsimply.yamlに関して、Chienomiは次の通り

outdir: ../Build
toc: yes
post_eruby: no
testserver_port: 8088
accs_order: desc
self_url_external_prefix: "https://chienomi.org/"

ほとんどサンプルファイルをコピーするだけで良い。 ちなみに、サンプルファイルは1.7で少し更新され、コメントで説明がつくようになった(英語だけど)。 また、サンプル用のテーマが追加された。

テンプレートに関してはサンプルファイルのものを使うほうが話は早いと思うが、

pandoc -D html5 > template.html

とするのでも良い。

導入そのものは「Pandocを必要とする」ためちょっと他より手間だが、構築自体は要件がより少なく楽である。

このウェブサイトもまた、PureBuilder Simplyによって構築されている。

特長

他アプローチのソフトウェア (例えばCMS) 比

高い可搬性

ドキュメントはMarkdown、またはReSTructured Textで書く。 これはPureBuilder Simply固有のものではなく、広く普及した形式である。

さらに生成にはPandocを利用しており、ソースドキュメントはPandocを使って他の形式に変換できるという意味を含め、CMSで書いたときのようにソースドキュメントが利用不能になってしまうような事態を避けられる。

ビルトドキュメントはHTMLファイルであり、どのような通常のウェブサーバーでも公開できる。

もちろん、いずれもバックアップも容易である。

データベース不要

操作しづらく、クラッシュの不安もあるデータベースは必要ない。

システムに備わる最も基本的な、かつ最も性能が高められたデータベース機能であるファイルシステムを使っているのだ。

ネットワークに依存せず、マシンに依存せず

静的なファイルによって構成されるため、その執筆はコンピュータさえあれば可能であり、なんならスマートフォンで書くこともできる。 インターネットにつながっている必要もなく、特定のマシンでなければいけないわけでもない。

実際、今この瞬間、私は中央のマシン(業務用ワークステーション)ではなく、寝室にあるコンピュータでこの記事を書いている。ソースドキュメントはMercurialリポジトリになっており、hg pushすれば中央のマシンに更新が反映されるのだ。

低いサーバー要件

静的ページを配信するのはウェブサーバーにとって最も基本的な機能であり、アプリケーションの実行ができないGitHub Pagesなどでも公開できる。

もちろん、ISPが提供するホームページ公開サービスや、数多いレンタルサーバーでも公開できるだろう。

セキュア

静的なファイルをサーブするだけなので、CMSなどにありがちなセキュリティリスクが存在しない。 サーバーそのものが安全であるならば安全である。

より良好なパフォーマンス

静的なファイルとしてサーブされるため、ほかのいかなるコンテンツ生成方式よりも高速である。

Nginxのような静的ファイルのサーブに良好な性能を発揮するサーバーとの組み合わせならなおさら速い。

ただしこのメリットは、動的に生成されたページをCDNを介して配信する場合、動的生成も事前生成戦略を取ることになるため特別なメリットとはならない。 もちろん、PureBuilder Simplyによって構築されたサイトをCDNによって配信することは可能であり、むしろより容易である。

編集・検索が容易

ファイルとして存在するMarkdownドキュメントを編集するだけだから、その編集や修正、アップデートは非常に簡単だ。

「テキストファイル郡である」ということはUnixユーザーであるならばどれほど嬉しいかすぐわかるだろう。

例えば、“PureBuilder” という単語が含まれたソースドキュメントを探すには次のようにすれば良い。

grep -F PureBuiler -r .

例えばすべてのソースドキュメントの”Foo’s Homepage”という文字列を”Great Dragon’s website”に改めたいと思ったら次のようにすれば良い。

find . -name '*.md' | while read
do
  sed -i -e "s/Foo's Homepage/Great Dragon's website/g" "$REPLY"
done

Zshならもっと簡単だ。

for i in **/*.md
do
  sed -i -e "s/Foo's Homepage/Great Dragon's website/g" "$i"
done

もちろん、これはWindowsであっても、Perl Power Toolsを使うなり、Git for Windowsに付属するGit Bashを使うなりといった方法でも可能になる。

そして、全てがテキストファイルであるために、バージョン管理システム(例えばGitやMercurial)との相性も良い。

同アプローチの他ソフトウェア比

ここでは主にJykillを想定して述べていきたいと思う。

ロックインの回避

Markdown形式を基本とするが、ReSTにも対応している。 この両方をサポートするソフトウェアは比較的少なく、Markdownに縛られる必要がない。

ドキュメントのメタデータを必要とする場合はMarkdown Frontmatter、あるいはReSTructured Text docinfoとして記述する。 これもドキュメントの形式として普及したものであり、ロックイン度合いがより低い。

ゆるい制約

どこのディレクトリにファイルを置かなければいけない、とか、何の機能を使わなければいけない、といった制約が非常にゆるい。 「実際に使う必要なものが存在していれば良い」という形だ。

Chienomiには検索機能があるが、これもPureBuilder Simplyプロジェクトの一部として書かれている。もちろん、PureBuilder Simply自体は動的な動作をサポートしないが、PureBuilder Simplyはそのまま利用される静的なファイルを配置することを妨げないので、PureBuilder Simplyプロジェクト内にCGIスクリプトを配置することができるのである。

自由度の高いカスタマイズ

Pandocのテンプレート機能を使っており、これにより「メタ変数を使った処理」が可能だ。 そして、Pandocのテンプレートだけでは足りない場合のために

  • pre plugins
  • post plugins
  • eruby template expension

の3つの機能をサポートしている。つまり、生成に関わる動的な機能を4段階備えている。

また、非常にシンプルに動作するため、「PureBuilder Simply側でデプロイする」みたいな機能は提供しない。 これは一見すると不便なようだが、実際には予約投稿を実現したり、サーバーになっていないシステム上で動作させたりとより汎用性高く使えるようになっている。

自由なライセンス

Apache License 2.0で提供されており、自由にカスタマイズしたり、複製したり、使用したり、配布したり、あるいはフォークしたりできる。

プラグイン機能

この手のソフトウェアはプラグイン機能を持っているのが一般的ではあるが、PureBuilder Simplyの場合、ソースドキュメント(Markdown, あるいはReST)を編集するpre pluginsと、ビルトドキュメント(HTML)を編集するpost pluginsの両方をサポートする。

どちらでもドキュメントメタデータが利用でき、さらにpost pluginsは同一ディレクトリ内のドキュメントのメタデータにもアクセスできる仕様だ。

また、これらのpluginsはperlによって起動され(1.7からは実行可能なファイルは直接実行)、フィルタプログラムであれば良いため、様々なスクリプト言語によって実装することができる。

結果、プラグイン機能は非常に書きやすく、特別に強力である。 例えばHarukamy’s Memorandaにはコメント機能があるが、このコメント機能はpost pluginsによって実装されている。

また、Mimir Yokohamaのウェブサイトには辞書機能があるが、こちらもpost pluginsを用いた実装である。

便利なテンプレート機能

PureBuilder SimplyはテンプレートシステムにPandocのものを利用しており、

  • 変数展開
  • 条件変数
  • 変数イテレータ

の3つの機能を搭載する。

このためにプラグインなどに頼らずとも様々な機能をテンプレートに組み込むことができる。 Mimir Yokohamaのサイトでは複数箇所にあるメニューや目次、ドキュメント情報があるほか、ページの種類(メインページ, 記事ページ, プロモーションページ, 連載ページ等)によって表示が変化するようにもなっているが、これらは全てテンプレートの機能を利用している。

さらに便利になるように、PureBuilder Simply 1.6から追加で変数を定義するようになった。これは、Pandocテンプレート上では書けないプログラム的処理によって生成される変数であり、この変数があることでプラグインやeRubyテンプレートを使わなくても動的生成するような値を書けるようになった。

なお、このアプローチはかなり有力だと考えているので、「こういう値を用意してほしい」というリクエストがあれば、GitHub上のissuesでリクエストしてほしい。

WordPressからのインポート

Chienomiを構築するために作成したWordPressのアーティクルインポーターがある

現在普及しているWordPressのウェブサイトから移行するのが楽だ。

日本人作者

私が書いているので、日本語ドキュメントがある(英語ドキュメントの翻訳なのだけども)。

そして私に質問することも(回答は約束はできないが)できるし、今後も日本語のドキュメントは増えていくだろう。

連続するコンテンツページのサポート

連載やシリーズもの、あるいはカテゴリ分けされた記事など、ブログのように「どんどん増えていく記事」に対して、文書の定義やリンクの作成など余事に気を取られる必要はない。

PureBuilder Simply ACCS(Article ColleCtion System)は記事を執筆後、コマンド一発でインデックスを作成する。 このインデックスはeRubyで書くことができ、ブログスタイルの見出しが可能なだけでなく、ブログでは難しい一覧機能などを提供できる。

テキストコンテンツ指向

同様のソフトウェアは、本質がどうであるかによらず、どちらかといえばよりモダンな、「テキストや内容よりも見た目や装飾に比重のあるウェブサイト」を制作できることをウリにしているようだ。

PureBuilder Simplyでもそのようなウェブサイトを制作することは可能だが、中身のある、「文章や記事をたくさん書く」人が労力少なく、執筆に集中できる仕組みを重視している。

だから、(このサイトのように)たくさんの記事の執筆に熱量を注ぐ人にとって使いやすい。

メタデータを利用した外部プログラムの支援

PureBuilder Simplyはメタデータをキャッシュとしてではなく、データベースとして外部ファイルに保存する。 これはRuby Mershal形式であり、Rubyプログラムから読むことができる。

これにより、記事の生成に関わるpre/post pluginsとは全く違うプラグイン機能を書くことができる。 例えばChienomiのトップページに最新記事の一覧があるが、これは全記事のメタデータをデータベースから読み取って、自動的に生成されている。 Mimir YokohamaにあるRSS機能や最新記事機能も同様だ。

自由なメタデータデータベースへのアクセスが可能であることは、事前生成ゆえの制約のうち多くのことから解き放ってくれる強力な機能となる。 (ただし、この機能を利用するにはRubyプログラミングに関するスキルが必要ではある)

PureBuilder Simplyによるサイト構築 (詳細)

注意事項

今のところWindowsは正式にはサポートされておらず、Windows上で動作させるには問題がある可能性がある。 問題となる箇所は限定的なので、CygwinやMSYS上で動作させる分には問題ないはずだ。

Windowsで動作させる上での不具合があれば、GitHubでissuesとして報告してもらえると助かる。 日本語でもOKである。

Pandocの導入

それぞれのプラットフォームでPandocを導入する。

Pandocの導入方法については触れないが、重要なのはpandocというコマンドでPandocが実行可能である必要があるということだ。

Windows*MSYS環境で利用する場合も、Windows版Pandocをインストールした上で、/usr/local/bin/pandocとして

#!/bin/bash

"/c/Users/foouser/AppData/Local/Pandoc/pandoc.exe" "$@"

みたいにして実行権限を与える、といった方法で解決できる。

MSYSの導入についても割愛するが、MSYSを入れるよりは、Git for Windowsを入れる(Git Bashを使う)のが私のお勧めである。

PureBuilder Simplyの導入

~/bin$PATHが通っていると仮定する。 Windowsの場合は、MSYS bashなら同様にできるはずだ。

$ mkdir ~/opt ~/bin
$ cd ~/opt
$ git clone 'git://github.com/reasonset/purebuilder-simply'
$ cp purebuilder-simply/*.rb ~/bin

PureBuilder Simplyサイトの作成

ここではサンプルサイトを利用してソースサイトを作る。 サイトのルートとして~/Documents/mywebsiteを利用するが、適宜読み替えてほしい。

$ mkdir -pv ~/Documents/mywebsite/Build
$ cp -rv ~/opt/purebuilder-simply/sample-doc/basedoc ~/Documents/mywebsite/Source

設定の編集

まずは~/Documents/mywebsite/Sourceに移動してそのディレクトリでVSCodeを開く、というのがお勧めの作業方法だ。端末も開いておくと良い。

Windows*MSYSの場合、MSYS上のパスはWindows上のパスにマップされているので注意が必要だ。

いずれにせよ、そのディレクトリにある.pbsimply.yamlを編集する。

実は本質的に必須なのはoutdir だけである。だから、

outdir: ../Build

と書けば十分だったりする。PureBuilder 1.7からデフォルトポートが80から8000に変更になったので、testserver_portも事実上の必須ではなくなった。

追加の項目にどのようなものがあるかは、READMEやサンプル設定ファイルを参考にしてほしい。

ドキュメントを書く

Markdownで書くとするととりあえず冒頭に

---
title: ここにタイトル
---

と書いておけば十分だったりする。あとは好きなようにその情熱を書き連ねてあげれば良い。

その他有効な項目(別に書かなくても良い)にどのようなものがあるかはREADMEに書いてある。

frontmatterになっているものは、基本的な値。Pandoc templateになっているものはPandocのデフォルトテンプレートが使用するもの(サンプルテンプレートでも使用する)で、Sample templateになっているものはサンプルテンプレートで独自に使用しているもの。

単純にsystemになっているものはPureBuilder Simplyがセットする変数なので手書きはしない。これはテンプレートで使うものだからだ。逆にACCSになっているものはACCSが使うものなので必要なら手書きする。

timestampfrontmatter/systemとなっており、「書いてあったらPureBuilder Simplyが使う」ということである。何に使うかというと、それ以降にある形式変換されたタイムスタンプ用だ。

生成する

現在はビルドディレクトリの用意は不要になった。 ソースドキュメントのルートディレクトリ上で

pbsimply-pandoc .

のようにすれば同ルートディレクトリ上のドキュメントがビルドされる。

PureBuilder Simply 1.6/1.7のポイント

1年2ヶ月ぶりの更新となったPureBuilder Simply 1.6のポイントは個人的にはforce refreshなのだが、実質的に大きいのは「プログラム的処理を加えた変数の追加」である。

これによって「URLエンコードされたアドレスやタイトル」「XMLスキーマに変換されたタイムスタンプ」などが定義され、テンプレート上で使えるようになった。

1.6はChienomi構築用に不足している機能を追加した形である。 コード的に見ればそれほど大きな変更ではないのだが(とはいえそこまで小さい変更でもなかったが)、PureBuilder Simplyの機能性や応用を考えるとかなり大きい。

(もっとも、開発として見ればimporterやsearcherの開発のほうがずっと大きかったが)

1.7はデフォルト値の調整やテーマの追加など、スキルを持たない人がより簡単にサイトを構築できるような変更が主。