Nephia入門講座, 第3回目です.
前回は, 「占いアプリ」に必要な機能を, lib/Uranai.pmに実装していきました.
今回は, index.htmlとuranai.htmlという2つのテンプレートを用意して, 「占いアプリ」をひとまず完成させましょう.
テンプレートは, viewディレクトリの中に格納されています.
初期状態ではindex.htmlというテンプレートが用意されているので, まずはこれを「占いアプリ」向けに編集します.
? my $c = shift;
<html>
<head>
<link rel="stylesheet" href="/static/style.css" />
<link rel="shortcut icon" href="/static/favicon.ico" />
<title><?= $c->{title} ?> - powerd by Nephia</title>
</head>
<body>
<div class="title">
<span class="title-label"><?= $c->{title} ?></span>
<span class="envname"><?= $c->{envname} ?></span>
</div>
<div class="content">
<h2>今日の運勢を占おう!</h2>
<form action="/uranai">
<input type="text" name="name">
<input type="submit" value="占う!">
</form>
</div>
<address class="generated-by">Generated by Nephia</address>
</body>
</html>こんな感じです.
ごくシンプルに, 名前を入力するテキストフォームと, 「占う!」と表示された送信ボタンを配置しています.
送信ボタンがクリックされた場合, /uranaiに対してGETメソッドでアクセスを行います.
この状態でplackupコマンドでアプリを立ちあげてしてブラウザで確認すると, 次のように表示されるはずです.
うまくフォームが表示されていますね!
では, この状態でテキストフォームに適当な値を入れて, 「占う!」ボタンを押すとどうなるでしょうか.
/uranaiの実装はlib/Uranai.pmに書いてありますが, まだuranai.htmlのテンプレートが用意できていませんね.
「テンプレートファイルuranai.htmlが見つかりません!」というエラーが表示されます.
このように, development環境(plackupに-Eオプションを与えない)だと, このようにエラーのトレースが表示されます.
一方, production環境(plackupに-E productionというオプションを指定)だと,
このように, 最小限のエラーだけが表示されます(ちなみに, plackupを動かしているコンソールに出力されるログも, -Eオプションによって変化します).
development環境で出るエラートレースはデバッグに有用ですが, サーバー上でこのような情報が出てしまうと, 脆弱性を発見される情報源になりかねませんので, 気をつけましょう.
それでは, view/uranai.htmlを作って行きましょう.
? my $c = shift;
<html>
<head>
<link rel="stylesheet" href="/static/style.css" />
<link rel="shortcut icon" href="/static/favicon.ico" />
<title><?= $c->{title} ?> - powerd by Nephia</title>
</head>
<body>
<div class="title">
<span class="title-label"><?= $c->{title} ?></span>
<span class="envname"><?= $c->{envname} ?></span>
</div>
<div class="content">
<h2><?= $c->{name} ?>さんの今日の運勢は...</h2>
<?= $c->{result} ?>です!!!!!
</div>
<address class="generated-by">Generated by Nephia</address>
</body>
</html>こんな感じです.
前回, lib/Uranai.pmに実装した/uranaiページへアクセスした際の処理において, 最後はこのようになっていました.
return {
template => 'uranai.html',
name => $req->param('name'),
result => $result,
title => config->{appname},
envname => config->{envname},
};実はこのハッシュが, テンプレートの1行目にある? my $c = shift;によって, $cに格納されています.
その為, テンプレートの中で<?= $c->{name} ?>や<?= $c->{result} ?>といった形で利用できるのです.
さて, ここで改めて, テンプレートの中で使える記法について説明しておきます.
Nephiaがデフォルトで利用するテンプレートエンジン, Text::MicroTemplateでは, テンプレート中の行の先頭に?を付けると, その行はPerlのコードとして処理されます.
また, <?= $i ?>このように書くと, 生成するHTMLの中に, $iという変数の中身を埋め込むことができます.
これさえ覚えておけば, 後はPerlで色々と細かい処理をすることができます. 例えば,
<div class="content">
? for my $i (1..10) {
<?= $i ?>
? }
</div>このように書けば, <?= $i ?>の部分は$iが1から10の間まで繰り返し実行されるので,
<div class="content">
1
2
3
4
5
6
7
8
9
10
</div>テンプレートからはこのようなHTMLが生成され,
このように表示されます.
さあ, テンプレートの実装も終わりました.
plackupコマンドで起動して, 動作を確認してみましょう!
localhost:5000にアクセスして, テキストボックスに適当な名前を入力し, 占う!ボタンをクリックすると...
出来ましたね! このように, 占いの結果が表示されます. これでひとまず, 占いアプリは完成です.
もちろん, 占いアプリはこれで完璧, とは言えません.
例えば, テキストボックスに何も入力しない状態で占う!ボタンをクリックしてみると...
このように表示されてしまいます.
いろいろな対策方法がありますが, 今回はシンプルに, 「テキストボックスが空だったら, /uranaiから/indexにリダイレクトさせる」という方針を取ります.
というわけで, lib/Uranai.pmのうち, /uranaiにアクセスした際に処理される部分を, 次のように書き換えます.
path '/uranai' => sub {
my $req = shift;
my @results = qw/ 大凶 凶 吉 小吉 中吉 大吉 /;
my $result = $results[int rand(@results)];
my $name = $req->param('name');
if ($name eq '') { # ... (1)
return res { redirect('/'); }
}
return {
template => 'uranai.html',
name => $req->param('name'),
result => $result,
title => config->{appname},
envname => config->{envname},
};
};テキストフォームに文字列が入っていない場合, $req->param('name')のような形でアクセスすると, undefではなく空文字('')が返ります.
その為, (1)の部分で, テキストフォームから受け取ったデータが空文字かどうかをチェックしています.
return res { redirect('/'); }この部分が, 実際にリダイレクトを指示している部分です.
redirect('/')で, /にリダイレクトすることを示し, これをresに与えることで, /uranaiから/にリダイレクトすることができます.
実際に動かしてみると, テキストボックスに文字列が入っていた場合/uranaiに遷移して結果を表示し, 何も入力しなかった場合はそのまま/に戻ってくることが確認できるはずです.
さて, resの中には, 他にもbodyやcontent_type, content_encodingなどを入れることができます.
例えば,
return res {
content_type('text/plain');
content_encoding('utf-8');
body('foobar');
}こんな感じにすると,
このようなテキストを表示させることができます.
今回作った占いアプリは, まだまだ改造の余地があります. 例えば...
- テキストボックスが空欄だった場合,
/にリダイレクトした上で「テキストボックスが空欄です!」と表示させる - アクセスするごとに占いの結果が変わるので, その日の間は同じ結果を表示するようにする(結果をキャッシュする)
- twitterと連携して, 占い結果をツイートできるようにする
...などです.
次回の「Nephia入門 (4)」では, テンプレートの機能を使って複雑なデータをテーブルで表示する練習をしてみたいと思います.






