かんたんコンテンツジェネレータ Nim に入門してみたB!

今年の 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!