前回の
MojoliciousとMVC
ここではmyapp.
ファイルのコードをもとに、
コントローラ
myapp.
においてコントローラに相当するのはリスト1のサブルーチン部分です。
get '/' => sub {
my $c = shift;
$c->render(template => 'index');
};
リクエストとコントローラを紐付けるルーティングの定義の基本的な形式は次のようになります。
HTTP メソッド 'URL パターン' => sub { ... };
get '/'
部分で処理すべきリクエストを定義し、/
というパターンにマッチするURLにリクエストがきたときに、
Mojoliciousの内部において、Mojolicious::Routes
が担当し、
が担当します。Mojolicious::Controller
実行されるサブルーチンの第1引数にはMojolicious::Controller
のインスタンスが渡されます。このインスタンスを利用して、
Mojolicious::Routes
ではプレースホルダやネストしたルーティングを活用した認証処理など、
ビュー
ビューはMojolicious::Controller
のrender
メソッドで呼び出します。myapp.
ではリスト1の次の部分です。
$c->render(template => 'index');
Mojolicious 内部において、Mojolicious::Renderer
が担当し、Mojo::Template
がレンダリングします。このコードではtemplate => 'index'
によって、index.
をテンプレートとしてレンダリングします
@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!
テンプレートの命名規則はテンプレート名.フォーマット.ハンドラ
です。引数による指定がない場合、コントローラ名/アクション名
もしくはルート名
、ep
となります。myapp.
ではコントローラ名やアクション名、template
によってテンプレート名を指定しています。
テンプレートではリスト3のようなEmbedded Perlと呼ばれる形式でPerlコードを埋め込むことができます。また、Mojolicious::Plugin::DefaultHelpers
やMojolicious::Plugin::TagHelpers
、Mojolicious::Plugin::DefaultHelpers
のlayout
ヘルパーとtitle
ヘルパーを使用しています。
<% Perl コード %>
<%= Perl コードを評価しXML エスケープして置換 %>
<%== Perl コードを評価して置換 %>
<%# コメント %>
<%% "<%" に置換 %>
% 行単位の"<% Perl コード %>"
%= 行単位の"<%= Perl コード %>"
%== 行単位の"<%== Perl コード %>"
%# コメント行
%% "%" に置換
Mojolicious::Renderer
ではこのほかにもJSON
モデル
Mojolicious はモデルをサポートしていません。myapp.
でもモデルに相当する部分はありません。モデルは開発者側で設計して実装する必要があります。
プロトタイプや小規模開発ではコントローラ内部にモデルのロジックを書いてもさほど問題はありませんが、
MojoliciousによるWebアプリケーション開発
ここでは簡単な掲示板の作成を通して、
事前に次のコマンドを実行して、
$ mojo generate lite_app mojo_bbs.pl
データベースを用意する
今回作成するアプリケーションではデータベースにSQLite3を利用します。各プラットフォームに合わせてインストールしてください。
掲示板のスキーマはリスト4になります。mojo_
ファイルにSQLを保存して、mojo_
を作成してください。
$ cat mojo_bbs.sql | sqlite3 mojo_bbs.db
CREATE TABLE IF NOT EXISTS "comment" (
"id" INTEGER PRIMARY KEY,
"body" TEXT NOT NULL,
"created_at" DATETIME NOT NULL
);
データベースを設定する
続いて、
接続するデータベースの情報は外部ファイルで管理できたほうが取り回しが良いため、mojo_
ファイルにJSONフォーマットでリスト5の内容を記述します。
{
"connect_info": [
"dbi:SQLite:dbname=mojo_bbs.db", "", "",
{
"AutoCommit": 1,
"PrintError": 0,
"RaiseError": 1,
"sqlite_unicode": 1
}
]
}
mojo_
にはリスト6の内容を追加します。JSONConfig
プラグインを利用することで、mojo_
ファイルの内容を参照できます。また、dbh
という属性を用意し、
use DBI;
plugin 'JSONConfig';
app->attr(
dbh => sub {
my $self = shift;
my $dbh = DBI->connect(
@{$self->config->{connect_info}}
) or die $DBI::errstr;
return $dbh;
}
);
コントローラを実装する
ルーティングとコントローラの実装はリスト7のようになります。コントローラ内部では、$c->app->dbh
からデータベースハンドラを取得して操作を行います。
use Time::Piece;
get '/' => sub {
my $c = shift;
$c->redirect_to('list');
} => 'index';
get '/comments' => sub {
my $c = shift;
my $comments = $c->app->dbh->selectall_arrayref(
q{SELECT id, body, created_at FROM comment},
{Slice => {}},
);
$c->stash(comments => $comments);
$c->render;
} => 'list';
post '/comments' => sub {
my $c = shift;
my $url = $c->url_for('list');
if (my $body = $c->param('body')) {
my $sth = $c->app->dbh->prepare(
q{INSERT INTO comment (body, created_at) VALUES (?, ?)});
$sth->execute($body, localtime->strftime('%F %T'));
my $id = $c->app->dbh->last_insert_id('', '', '', '');
$url->fragment($id);
}
else {
$url->fragment('post');
}
$c->redirect_to($url);
} => 'post';
get '/comments'
ではテンプレートでも利用できるように、stash
に渡します。post '/comments'
は少々長いコードですが、/comments#id
にリダイレクトしています。
テンプレートを追加する
最後の仕上げにコメントの一覧と投稿フォームを描画するためのテンプレートをDATAセクションに追加します
@@ list.html.ep
% layout 'default';
% title 'MojoBBS';
<dl>
% for my $comment (@$comments) {
<dt id="<%= $comment->{id} %>">
<a href="#<%= $comment->{id} %>"><%= $comment->{id} %></a>
<%= $comment->{created_at} %>
</dt>
<dd><pre><%= $comment->{body} %></pre></dd>
% }
<dl>
<hr>
<form id="post" action="<%= url_for('post') %>" method="POST">
<div><textarea name="body" rows="5"></textarea></div>
<div><input type="submit" value="Post"></div>
</form>
一覧表示のためのget '/comments'
にはlist
というルート名を設定してあるので、list.
となります。テンプレートではstash
を通して渡されたデータをもとにコメント一覧をレンダリングします。
動作を確認する
それではアプリケーションを実行してみましょう。前節と同様にmorbo
を使います。今回は実行時に
$ morbo mojo_bbs.pl
Server available at http://127.0.0.1:3000
[Tue Apr 7 20:02:19 2015] [debug] Reading configuration file "/path/to/mojo_bbs.json"
Ctrl-Cで終了
ブラウザでhttp://
にアクセスして、
<続きの