かんたんコンテンツジェネレータ Nim に入門してみた
今年の jperl advent calendar はnimという typester さんが開発しているツールを使って生成しているのですが、これが便利らしいので入門してみる事にしました。
インストール
github にリポジトリがあるので、 git が使える場合は以下のようにして取ってきます。以下、~/tmp を起点に作業する事にしますので、ご自分の環境に合わせて読み替えてください。
% mkdir ~/tmp % cd ~/tmp % git clone git://github.com/typester/nim.git
git が使えない場合は http://github.com/typester/nim にアクセスして「download」ボタンを押せば最新版がダウンロードできます。
とってきた後は、 nim のディレクトリに入って
% cd ~/tmp/nim % perl Makefile.PL % make installdeps
とすると依存モジュールがインストールできます。うまくやるためにも昨日の otsune さんの記事も読みましょう。
Hello World
では、いつも通り hello world いってみましょうか。
ディレクトリ
まず今回のサイト用のディレクトリを作ります。 helloworld ディレクトリを作成し、その中の data ディレクトリにデータを格納し、 public ディレクトリに nim が公開用の HTML を生成する事にします。
% mkdir -p ~/tmp/helloworld/{,data,public} % cd ~/tmp/helloworld % ls data public
.nim ファイル
つぎに .nim ファイルを作成します。このファイルに nim の設定を記述します。書式は YAML です。
% cat ~/tmp/helloworld/.nim # .nim file data_dir: ./data site_dir: ./public plugins: - module: Entry::File - module: Render::Entry
data_dir と site_dir は先ほど作ったディレクトリを指定します。 plugins にはどのプラグインを使うかを指定します。ひとまずファイルから html を生成するために必要なプラグインだけを指定しておきます。
テンプレート
nim はテンプレートに Text::MicroTemplate::Extended を使っています。テンプレートファイルの中の「<?=」と「?>」に囲まれた部分が Text::MicroTemplate::Extend によってデータに置き換えられます。それでは記事ページ用のテンプレートを data/entry.html として作成します。
% cat ~/tmp/helloworld/data/entry.html <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title><?= encoded_string $entry->title ?></title> </head> <body> <?= encoded_string $entry->body ?> </body> </html>
$entry というのが記事のデータを格納したオブジェクトです。そこからタイトルと本文を取り出してそれぞれ埋め込んでいます。
記事ファイル
それでは記事を書きましょう。 data/hello.txt というファイルを作ると、 nim が public/hello.html というファイルを作ってくれる予定です。1行目がタイトル、2行目以降が本文になります。
% cat ~/tmp/helloworld/data/entry.html こんにちは、世界! うまくいくかなぁ
ファイル生成、確認
準備が整ったので、 nim で html を生成してみましょう。 helloworld ディレクトリ直下で nim コマンドをたたきます。
% cd ~/tmp/helloworld % ~/tmp/nim/bin/nim [info] Nim::Plugin::Entry::File: find: data/hello.txt [info] Nim::Plugin::Render::Entry: render: public/hello.html
ログを見ると data/hello.txt をみつけて public/hello.html を生成した事が分かります。見てみましょう。
% cat ~/tmp/helloworld/public/hello.html <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>こんにちは、世界!</title> </head> <body> うまくいくかなぁ </body> </html>
おお、うまくいきました!
サーバーを起動して確認
以下のように nim コマンドに --server オプションを渡してやると、 nim に内蔵のウェブサーバーが立ち上がって、ブラウザで簡単に確認できます。
% cd ~/tmp/helloworld % ~/tmp/nim/bin/nim --server [info] Nim::Plugin::Entry::File: find: data/hello.txt [info] Nim::Plugin::Render::Entry: render: public/hello.html [info] main: Starting build-in server Accepting connections at http://0.0.0.0:4423/
ブラウザで http://localhost:4423/hello.html にアクセスしてみてください。
Plugin でいろいろやる
ひとまず Hello World ができましたが、これだけではあんまり便利じゃありませんね。もうちょっと便利そうな事をしてみましょう。
AutoIndex プラグイン
先ほどの .nim ファイルに以下のように一行追記します。
% cat ~/tmp/helloworld/.nim # .nim file data_dir: ./data site_dir: ./public plugins: - module: Entry::File - module: Render::Entry - module: AutoIndex
次に インデックス用のテンプレートを data/index.html として作成します。
% cat ~/tmp/helloworld/data/index.html <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>index</title> </head> <body> <ul> ? my @entries = sort { $b->datetime <=> $a->datetime } ? @{ $page->entries || [] }; ? for my $entry (@entries) { <li> <a href="<?= $entry->filename ?>.html"> <?= $entry->title ?> </a> </li> ? } </ul> </body> </html>
$page->entries でインデックスで出力する記事のリストが取得できるので、それをいい感じにループでまわしてリンクを出力しています。
これでもう一度 nim コマンドを実行すると、インデックスページが生成されるはずです。
% cd ~/tmp/helloworld % ~/tmp/nim/bin/nim [info] Nim::Plugin::Entry::File: find: data/hello.txt [info] Nim::Plugin::Render::Entry: render: public/hello.html [info] Nim::Plugin::Index: render: public/index.html
public/index.html が生成されているのが分かりますね。それでは見てみましょう。
% cat ~/tmp/helloworld/public/index.html <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>index</title> </head> <body> <ul> <li><a href="hello.html">こんにちは、世界!</a> </ul> </body> </html>
ふむ。もう一個記事を書いて nim を再実行してみましょう。
% cat ~/tmp/helloworld/data/second.txt 二つ目の記事 ズサーc⌒っ゚Д゚)っ % cd ~/tmp/helloworld % ~/tmp/nim/bin/nim [info] Nim::Plugin::Entry::File: find: data/hello.txt [info] Nim::Plugin::Entry::File: find: data/second.txt [info] Nim::Plugin::Render::Entry: render: public/hello.html [info] Nim::Plugin::Render::Entry: render: public/second.html [info] Nim::Plugin::Index: render: public/index.html % cat ~/tmp/helloworld/public/index.html <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>index</title> </head> <body> <ul> <li><a href="second.html">二つ目の記事</a> <li><a href="hello.html">こんにちは、世界!</a> </ul> </body> </html>
うまくいきました!
Hatena プラグイン
これまでは記事の中に HTML を埋め込もうとすると手書きの HTML を書かなくちゃいけなくて実は面倒でした。そこで、次はみんな大好きはてな記法で書けるようにしましょう。
.nim ファイルを編集します。
% cat ~/tmp/helloworld/.nim # .nim file data_dir: ./data site_dir: ./public plugins: - module: Entry::File - module: Render::Entry - module: AutoIndex - module: Hatena
data/hello.txt をはてな記法で書き換えて nim を実行してみましょう。
%cat ~/tmp/helloworld/data/hello.txt こんにちは、世界! * Hello World を書いてみるよ うまくいくかな? >|| #!/bin/sh echo hello world ||< % cd ~/tmp/helloworld % ~/tmp/nim/bin/nim --server [info] Nim::Plugin::Entry::File: find: data/hello.txt [info] Nim::Plugin::Entry::File: find: data/second.txt [info] Nim::Plugin::Render::Entry: render: public/hello.html [info] Nim::Plugin::Render::Entry: render: public/second.html [info] Nim::Plugin::Index: render: public/index.html [info] main: Starting build-in server Accepting connections at http://0.0.0.0:3000/
ブラウザで確認してみましょう。いい感じに H1 やスーパーpreができているはずです。ほかに Markdown にも対応しているので、試してみましょう。
まとめ
ここまで、 nim の使い方のさわりの部分をご紹介しました。
- Text::MicroTemplate::Extended で柔軟なテンプレートを書けます。
- 記事をかくのもはてな記法や Markdown に対応しているので書きやすいです。
- 静的にデータを作るので、 ftp でまるっとレンタルサーバーにアップロードするとかもできます。
- ソースコードがきれいで読みやすいので、勉強になります。
さらに詳しくは、ソースコードを読むか、以下のようにして jperl advent calendar をダウンロードしてどんな使い方をしているかを見てみるといいと思います。
git clone http://git.coderepos.org/share/websites/jperl-advent-calendar-2009.git/
以上、 nim のご紹介でした。 Enjoy!