現在の自分の制作の多くが、静的HTMLファイルの納品もしくはCMSに組み込むためのHTMLの納品です。静的ではありますが、共通部はincludeファイルなどで分けて納品してもOKというような状況がほとんどです。
そのため、これまでは共通部をSSIやPHPのincludeなどを使ってコーディングをしていたのですが、 jekyll や middleman などをちらほら聞くようになった2年ほど前から、静的サイトジェネレータを利用するようになりました。
今回は、最近利用してみた静的サイトジェネレータの 「metalsmith」 を利用してみたので、メモとしてエントリーしておきます。
metalsmith
最初は jekyll を grunt のタスクに組み込んで使っていたのですが、ページ数が増えたりしてくると、書き出しに時間がかかるようになってきたりして、なんとか改善できないかなと考えていました。
grunt や gulp が Node で動いているので、 同じ Node で動作するものがいいなーと探してみたところ、今ってものすごくたくさんあるのですね。
で、いろいろ調べたところ、 HTML ファイルをそのままの形でも使いまわせそうなのが、 Metalsmith だってことで使ってみました。
導入
metalsmith 本体はいろいろなプラグインと合わせることで、好みの形式にできるようなので、私は jekyll 形式を利用することにしてみました。
静的ページを用意したいだけなので、以下のように最小限で。
package.json
{
"devDependencies": {
"metalsmith": "~1.0.1",
"metalsmith-templates": "~0.6.0",
"swig": "~1.4.2"
},
"private": true
}
上記ファイルを用意して
$ npm install
もしくは package.json に入れる用として
$ npm install --save-dev metalsmith metalsmith-templates swig
swig
というテンプレートを使うことで、 jekyll ライクなテンプレート構成が出来る様子。
Swig - A Node.js and Browser JavaScript Template Engine
ファイル構成
テンプレートを利用するためのファイル構成は以下のようにしてみました。
- _layouts
- default.html
- _source
- index.html
- metalsmith.json
- package.json
テンプレートのファイルは _layputs のフォルダに、実際のソースは _source フォルダに。
設定ファイル:metalsmith.json
設定は metalsmith.json
にまとめておくと楽のようなので以下のように用意。
metalsmith.json
{
"source": "_source",
"destination": "html",
"plugins": {
"metalsmith-templates": {
"engine": "swig",
"directory": "_layouts"
}
}
}
テンプレート:default.html
テンプレートは、ひとまずシンプルに
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
{{ contents | safe }}
</body>
</html>
テンプレートを利用するファイル
---
template: default.html
title: テスト
---
本文テスト
書き出し用コマンド
以下のコマンドを叩いて書き出し
$ node node_modules/.bin/metalsmith
metalsmith を -g
つきのグローバルでインストールしていたら、上記のコマンドも
$ metalsmith
だけでOK。
書き出し後
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テスト</title>
</head>
<body>
本文テスト
</body>
</html>
ひとまずこれで導入は問題なさそう
共通部( header や footer )を include する場合
include する方法がいまいちわからなかったのですが、以下のようにすることで include させることができました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
{% include 'header.html' %}
{{ contents | safe }}
{% include 'footer.html' %}
</body>
</html>
※追記(2015/01/20 22:00)
{{ contents }}
で読み込むだけでは、htmlの要素がエスケープされて出力されてしまいます。エスケープしないでHTML要素として出力するために {{ contents | safe }}
とする必要があるのですが記載がぬけてしまっていたため、追記しました。