ROUTE 3390

備忘録的な用途で書いていますが、どなたかの役に立つ事があれば嬉しいです。

Mojoliciousを使ってみたよ

PerlフレームワークMojoliciousを使ってみたので、そのメモ。
マシンはMac OS X


ちなみに、Mojoliciousはドキュメントが日本語訳されていますよ
Home · yuki-kimoto/mojolicious-guides-japanese Wiki · GitHub


まずはCPANからインストール

$ sudo cpan
cpan[1]> install Mojolicious


次にドキュメントルートで、Webアプリケーションの雛形を作るコマンドを実行しました。

$ cd /var/www/
$ mojo generate app MojoTest
  [mkdir] /var/www/mojo_test/script
  [write] /var/www/mojo_test/script/mojo_test
  [chmod] mojo_test/script/mojo_test 744
  [mkdir] /var/www/mojo_test/lib
  [write] /var/www/mojo_test/lib/MojoTest.pm
  [mkdir] /var/www/mojo_test/lib/MojoTest
  [write] /var/www/mojo_test/lib/MojoTest/Example.pm
  [mkdir] /var/www/mojo_test/t
  [write] /var/www/mojo_test/t/basic.t
  [mkdir] /var/www/mojo_test/log
  [mkdir] /var/www/mojo_test/public
  [write] /var/www/mojo_test/public/index.html
  [mkdir] /var/www/mojo_test/templates/layouts
  [write] /var/www/mojo_test/templates/layouts/default.html.ep
  [mkdir] /var/www/mojo_test/templates/example
  [write] /var/www/mojo_test/templates/example/welcome.html.ep

自動で色々作られます。


ちなみにアプリケーション名はキャメルケースで指定する必要があります。
下記のようにアンダーバーとかを含めるとエラーになります。

$ mojo generate app mojo_test
Your application name has to be a well formed (camel case) Perl module name
like "MyApp".


さて、作成されたディレクトリやファイルについて簡単に説明

mojo_test/lib
コントローラーやモデルなど、これから作るWebアプリケーションの様々な処理をここに作っていきます。
mojo_test/t
テストモジュールはここに
mojo_test/log
ログの格納場所かなぁ?まだ分かってません。
mojo_test/public
静的コンテンツの置き場所。htmlとかjavascriptcss、画像なんかも?
mojo_test/template
動的コンテンツを表示するためのテンプレート。
mojo_test/script/mojo_test
index.cgiの原型みたいなの。ではこれを早速。。。

そのままでもいいんだろうけど、僕はひとつ上の階層にindex.cgiとしてコピー

$ cp mojo_test/script/mojo_test mojo_test/index.cgi

ファイルの場所を変えたので、ライブラリの指定を修正。

$ vi mojo_test/index.cgi
use FindeBin;
use lib "$FindBin::Bin/../lib";

ここんところを、、
こう!

use FindeBin;
use lib "$FindBin::Bin/lib";


MojoliciousにはHTTPサーバーが付いているので、morboコマンドでスグに確認が出来る。

$ morbo index.cgi
Server available at http://127.0.0.1:3000.

表示されたURLにブラウザでアクセスすればOK


では、index.cgiが実行されて、このような画面が表示されるまでの流れをざっ!と説明。
まずindex.cgiですが、MojoTest.pmを呼んでいるだけなので省略。

mojo_test/lib/MojoTest.pm

package MojoTest;
use Mojo::Base 'mojolicious';

# This method will run once at server start
sub startup {
  my $self = shift;

  # Documentation browser under "/perldoc"
  $self->plugin('PODRenderer');

  # Router
  my $r = $self->routes;

  # Normal route to controller
  $r->get('/')->to('example#welcome');
}

1;

呼ばれるのは、このstartupメソッドですね。

デフォルトだとPODRendererというプラグインを読み込んでいるようです。
これはブラウザでMojoliciousの使い方を見るためのものらしく、
アプリケーション作る際は消しちゃっていい箇所です。


このプラグインを読み込んでいると、さっきのURLに/perldocを追加すると
このように表示されます。

さて、処理の続きを、
$self->routes;というので、Mojolicious::Routesオブジェクトを取得します。
URLによって処理を枝分かれさせる、ルーティングを行います。

$r->get('/')->to('example#welcome');

これだと
http://127.0.0.1:3000/ へのGETメソッドリクエストであれば、
exampleコントローラーのwelcomeアクションを呼び出します。


このtoメソッドの引数は色々な指定方法があるようです。
また、get以外にpostだけでなく、putやdeleteもあるので、RestAPIを提供する場合にも利用出来ます。
更にgetやpostのようなリクエストメソッドに関係なく、指定したい場合はrouteというのを使えます。


詳しい用法は日本語訳のガイドを参考にすると良いですよ。
Mojolicious::Routes · yuki-kimoto/mojolicious-guides-japanese Wiki · GitHub


というわけで、次は mojo_test/lib/MojoTest/Example.pmです。
コントローラーと呼ばれるものです。

package MojoTest::Example;
use Mojo::Base 'Mojolicious::Controller';

# This action will render a template
sub welcome {
  my $self = shift;

  # Render template "example/welcome.html.ep" with message
  $self->render(
    message => 'Welcome to the Mojolicious real-time web framework!');
}

1;

先ほどのルーティングの指定により、welcomeアクションが呼ばれるわけですが、
ここでは単純にrenderというメソッドにより、レンダリングの指示と
その際にmessageというkeyと値を持つ、ハッシュを渡していて、これはこの後テンプレートで使えるようになります。


ここでポイントですが、コメントにもあるように、利用されるテンプレートは
mojo_test/templates/example/welcome.html.ep になります。
どうやらデフォルトではルーティングの時に指定された コントローラー名、アクション名がそのままテンプレートを決める事になります。


つっても、柔軟にテンプレート変更したいとかあると思います。
そんな時の詳しい用法は日本語訳のガイドを参考にすると良いですよ。
Mojolicious::Guides::Rendering · yuki-kimoto/mojolicious-guides-japanese Wiki · GitHub


さぁ最後です。テンプレート!
呼ばれたのは mojo_test/templates/example/welcome.html.ep

% layout 'default';
% title 'Welcome';
<h2><%= $message %></h2>
This page was generated from the template "templates/example/welcome.html.ep"
and the layout "templates/layouts/default.html.ep",
<a href="<%== url_for %>">click here</a> to reload the page or
<a href="/index.html">here</a> to move forward to a static page.

だいたいさっきブラウザで表示された内容ですね。
ポイントだけ説明します。

% layout 'default';
% title 'Welcome';

この1行目はレイアウトの指定で、mojo_test/templates/layout/default.html.ep を選んでいます。
2行目でそのレイアウトに対しtitleという変数を渡してる感じです。


テンプレートの中では <%= 変数名 %> とする事で、その値を埋め込む事が出来ます。

layout/default.html.epは下記のようになっています

<!DOCTYPE html>
<html>
  <head><title><%= title %></title></head>
  <body><%= content %></body>
</html>

なんか知らない変数がありますね。
実は <%= content %> というのは、このレイアウトを指定したテンプレートの事になります。

なので、さっきのテンプレートが、このレイアウトテンプレートの<%= content %>部分にガボッとハマる感じですね。


実際にページを作成する時はcssjavascriptを使うと思いますが、
それはmojo_test/public/の下に置いて、そこへのパスをlayoutテンプレートのヘッダで指定したりするわけです。


これで基本編おわり!