シンプルで洗練されたCMS 「Bolt」 のすゝめ 或いはCMSカスタムフィールド論
Boltとは
BoltはSilex(Symfony2ベースのマイクロフレームワーク)を利用して製作されているCMSです。
※ロゴのイラストからしても名前の意味は雄ネジのボルト。
Boltはシンプルかつ設計も素直でわかりやすくということを念頭に作られており、CMS全体の設計が非常に洗練されています。 もう複雑でオレオレルールの多いCMSはこりごりと思っているWeb製作者の皆様におすすめしたいCMSです。
CMS探訪
個人的にカスタムフィールドやカスタムコンテンツを簡単に設定できる筋の良いCMSを探していて、その1つの選択肢としてBoltにたどり着いた、というのが本当のところです。
他の候補としてProcessWireやDrupal8等も試しています。
カスタムフィールドとカスタムコンテンツの設定はProcessWireが一番GUI派にも簡単かもしれません。
カスタムフィールド
Boltの話をする前にカスタムフィールドについて語らせてください。
「"コンテンツ"管理システムの規定する"コンテンツ"の型(ブログ記事・固定ページ)に無理やりサイトのコンテンツを押し込めるのではなく、コンテンツの持つ属性をそのまま表現したい。それが簡単にできなければ真の意味でのコンテンツ管理とは呼べないのではないか」
と最近ますます強く思っています。
ここで言う"サイトのコンテンツ"とは例えば
- 料理屋のメニュー(料金やカロリーの情報を含む)
- Web制作会社の制作実績(URLやクライアントの名前の情報を含む)
などを意味します。"ブログ記事"や"固定ページ"以外にこれらの独自の情報を格納できるコンテンツの型があれば自然な形でコンテンツを表現できます。
カスタムフィールド(ないしカスタムコンテンツ)の機能がない場合でも、もともとのコンテンツが持つべき独自の情報をブログの本文の定位置に決まった書式で書く、タイトルの先頭に挿入しておく、などの方法で次善の対処をすることはできます。 しかし、データを柔軟に利用できるようにするには、切り離せるデータは切り離してアトミックに管理するべきであり、これでは何かと窮屈です。
カスタムフィールドの設定が簡単なCMSがほしい!
現在、弊社がカスタムフィールドが必要となるときによく利用するのはWordPressです。 もちろん、お客様の要望でWordPressをよく指定されるということもありますが。 単なるブログシステムだったWordPressがある程度の互換性を保ちながらよくぞここまで多機能になったものだと感心させられます。
しかし、後付けは後付けです。設定が必要以上に煩雑である感じは否めません。 WordPressを利用していてカスタムフィールドを必要とする多くのユーザにとって、プラグインの力を借りてようやく手が届くレベルの機能だと思っています。
カスタムフィールドとリレーショナルデータベース(RDB)
なぜカスタムフィールドは我々からこんなにも遠いところにあるのでしょう?
ここからはより技術寄りの話になります。
CMSを設置するレンタルサーバの仕様上、多くのケースでデータベースとしてがRDBを選ばざるを得ないのが実情です。 カスタムフィールドの(エレガントな)実装の困難さはこのRDBのスキーマに依るところが大きいと考えています。RDBは永続化させるデータの型(スキーマ)を確定させてから運用するものであり、後のスキーマの変更に弱いデータストアです。 逆に言えばスキーマによって設計した通りの決まったデータ型しか挿入されないことが担保されていることがRDBの大きな魅力でもあります。
つまりカスタムフィールドはその性質からして、RDBに真正面から喧嘩を売るような機能であるということです。
MongoDBなどのNoSQL系データベースであれば、アプリケーションの設計時には予測不可能なデータの挿入に向いている(=カスタムフィールドの実装にも向いている)ものも多くありますが、それはRDBのスキーマが果たしていたデータ型チェックの一部をアプリケーション側で担保するということであり、下手な設計をすると別の問題を生む可能性もあります。
RDBであっても、文字列型のフィールドを用いてKey-Value型のNoSQLデータベースと同じように任意のデータ型を同じフィールドへ格納することは可能です。 しかしこれは、Entity Attribute Valueと呼ばれるRDB設計のアンチパターンであり、同種の問題を孕みます。 RDB上に独自のデータストアを構築しているようなものです。
他の方法として、
- カスタムコンテンツの定義から半自動的に対応するテーブルを設計・作成し、カスタムコンテンツの定義が更新されるたびにテーブルのスキーマとデータの変換を行う
- カスタムフィールドをXMLやJSONの形式でまとめて文字列型などのLOB型のフィールドに格納する(半構造化データ)
ということも考えられます。 この2つの実装方針もそれぞれ、データベース内のデータの変換と不整合、個々の属性へのアクセス可能性などといったハードルを持っています。
WordPressやMovableTypeはEntity Attribute Value、今回紹介するBoltはカスタムコンテンツごとに1テーブルという実装方法を採用しています。
前者2つは元々のデータベース構造を気軽に変えるわけにはいかないためEAV以外の選択肢はほぼありえなかったといってもいいでしょう。EAVはいろいろと手間や落とし穴が増えるアンチパターンではありますが、熟練のプログラマ達が揃っているならば何とかなってしまうようです。
BoltはDB抽象化レイヤーとして実績のあるDoctrineの上にテーブルの更新や正当性チェックを実装しています。 このアプローチも、Boltが打ち出している"正攻法"的であると言えます。
Boltの魅力
さて、前置き(という名の本当に書きたかったこと)が長くなりましたがWeb製作者から見たBoltの魅力をご紹介します。
Yamlファイルによる読みやすい設定の記述
Boltのすべての設定はYamlファイルに格納されます。 Yamlは人間にとっても非常に読みやすいファイル形式です。
柔軟なコンテンツタイプ(ContentTypes)
こちらがカスタムフィールドやカスタム投稿タイプに当たる機能です。 後付けではなく、CMSのユーザーが自由にフィールドを設定してコンテンツの形を独自に定義し運用することを想定して作られています。 フィールドに合わせてコンテンツの編集フォームも自動生成されますし、データベースのテーブル構造も非常にシンプルです。 こちらの設定もYamlで記述され、冗長な記述は必要ありません。
設定できるフィールドの例
テキスト・テキストエリア・HTML・Markdown・整数・浮動小数点数・位置情報・画像・画像リスト・動画・動画リスト・ファイル・ファイルリスト・日時・日付・タクソノミー(カテゴリ・タグ)・リレーション(他のコンテンツとの関連付け)
簡明なテーマファイル
テンプレートエンジンTwigとオブジェクト指向型の記述により、テンプレートも非常に読みやすくすっきりと書けます。 コンテンツタイプを自分で設定する際に自分で指定したフィールド名をそのままテンプレートに利用できるため、独自の関数や仕様を覚えるという手間も非常に少なくなっていると感じます。
base-2013テーマのentry.twigの一部
※"record"が1つのブログ投稿を表しています。
<article>
<h2>{{ record.title }}</h2>
{% if record.image!="" %}
<div class="four columns imageholder">
<a href="{{ image(record.image) }}">
<img src="{{ thumbnail(record.image, 400, 260) }}">
</a>
</div>
{% endif %}
予想以上に記事が長くなってきたので本日はこのあたりで。
本記事中のスクリーンショットも日本語化されている部分がありますが、実は先日、Boltの日本語訳ファイルを作成しました。 次回のBoltの記事は「Boltの管理画面の日本語化とインストール」の予定です。