Mojoliciousが存在しないテンプレートを読みに行こうとする

結論から

結論から言いますと、render()メソッドを使って複数のテンプレートを作成するような場合は、formathandlerをちゃんと指定した方がいい、ということです。

Mojoliciousを使っていく上で必ずハマるんじゃないかと私は勝手に思ってるんですが、ネット上ではあまり見かけない情報のようなので、私だけかもしれないですね・・・。でも一応書いておきます。

解説

まず、以下のようなMojoliciousプログラムがあります。 テンプレートを読み込み、画面に表示するだけの単純なプログラムです。

#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
    my $self = shift;
    my $mail_body;

    # -- メールテンプレートからメール本文を作り出す
#   $mail_body = $self->render('contact', format=>'mail', partial=>1);

    # -- レンダー
    $self->render('index', mail_body=>$mail_body);
};

app->start;
__DATA__

@@ index.html.ep
<html>
<div>メールの内容</div>
<textarea><%= $mail_body %></textarea>
</html>

@@ contact.mail.ep
メールテンプレート!
ほげほげ

実際にこのプログラムをmorboコマンドで起動しましょう。

Kazaoki-MBA:Desktop kazaoki$ morbo sample.pl
[Wed Apr  2 22:18:16 2014] [info] Listening at "http://*:3000".
Server available at http://127.0.0.1:3000.

ブラウザから http://127.0.0.1:3000 にアクセスすると、上記のMojoliciousアプリが実行され、空っぽのテキストエリアが表示されている状態になればOKです。

次に、以下のようにコメントアウトしてた部分を行頭の「#」を削除して有効にしてください。

〜
    my $mail_body;

    # -- メールテンプレートからメール本文を作り出す
    $mail_body = $self->render('contact', format=>'mail', partial=>1);

    # -- レンダー
〜

これで、メール本文がテキストエリアに入ってくると思うじゃないですか普通。 ところが、ブラウザを更新させると、Mojoliciousのエラー画面が表示されます。 ターミナル画面をよく見てみると、

Template "index.mail.ep" not found.

なんていうエラーメッセージが見つかるかと思います。 そりゃそうです。index.mail.epなんてファイル用意してませんがな。

なぜそうなる?

これは、Mojoliciousの特性と言いますか、クセといいますか、render()に渡すformatやらhandlerやらは、ただの一過性の引数ではなく、スタッシュの値が書き換えられるものだからです。 つまり、最初の9行目で一度、スタッシュの値($self->stash->{format})がmailになったんです。 だもんで、次のrender()の時(12行目)に、スタッシュに保存されていたmailの値がそのまま使われ、index.mail.epなんていうありえないテンプレートが指されたわけです。
9行目をコメントアウトしてた状態(renderがひとつのみ)の時は、特にformatを指定してなかったので、標準でhtmlがレンダー対象となっていたようです。

ということで、render()2つ目もformatを指定した正しいソースはこちらになります。

〜
    # -- メールテンプレートからメール本文を作り出す
    $mail_body = $self->render('contact', format=>'mail', partial=>1);

    # -- レンダー
    $self->render('index', mail_body=>$mail_body, format=>'html');
};
〜

めでたしめでたし!

余談ですが、このMojoliciousのスタッシュというものは、ルーティングの時点で自動でセットできたり、to()メソッドで振り分け用に使ったり、テンプレート中に展開できたり、発想次第でかなり色々な使い方ができます。その分、最初ちょこちょこ躓く原因になるのですが、慣れてくるとかなり強力で、Perlらしいフレームワークだなぁと感じさせてくれる機能のひとつです。

確認したバージョン

  • Mojolicious 4.91