Mojolicious最速マスター

PerlのWeb Application Frameworkである **Mojolicious** でアプリをつくる場合に必要な基礎的な使用法を紹介します。1枚スクリプトから書けるMojolicious::Liteを前提としていますが大きなモノにも対応出来ます。

***

### イントロ

#### インストールする

`cpanm` コマンドでコアモジュール以外の依存関係無しで一発。

```
$ cpanm Mojolicious
```

#### 雛形をつくる

Mojoliciousディストリビューションに同封されている `mojo` コマンドを使ってアプリの雛形をつくりましょう。

```
$ mojo generate lite_app myapp.pl
```

#### 立ち上げてみる

```myapp.pl``` 自身が実行可能なスクリプトになっているので

```
$ ./myapp.pl daemon
```

とすることで実行したホストの3000番ポートでアプリが立ち上がります。その他 [plackupで立ち上げる方法など](http://qiita.com/yusukebe/items/c9fb34096e61976f062f) があります。

***

### ルーティング

#### GET/POSTのメソッドで振り分ける

Mojolicious::LiteだとDSLが提供されるのでその中の `getメソッド` と `postメソッド` 使いましょう。他にもPUTやDELETEもサポートされているのですが、まー最初はget/post知っとけばいいでしょう。

```pl
get '/entry' => sub {
    my $self = shift;
    # ちなみに $self はMojolicious::Controllerを継承したインスタンス
    ...;
};

post '/entry' => sub {
    my $self = shift;
    ...;
};
```

#### URLの一部をキャプチャする - path の placeholder

`/entry/1` とか `/entry/2` とか `/entry/3` とかURLの一部、この場合だと `/entry/{数字の部分}` をキャプチャしてコントローラの中で使いたい時はこのようにします。

```pl
get '/entry/:id' => [ id => qr/\d+/ ] => sub {
    my $self = shift;
    my $id = $self->stash->{id};
    $self->render( text => "Entry ID is $id!" );
};
```

ちなみに `$self->stash` を使わずに `$self->param(“id”)` でも可能。

***

### コントローラ

#### リクエストパラメータ値を取得する

`$self->req->param` もしくはショートカットである `$self->param` を使います。

```pl
post '/entry' => sub {
    my $self = shift;
    my $body = $self->req->param('body');
    ...;
};
```

#### デバグ用のログを出力する

`logディレクトリ` があればそこにファイル出力、無ければ立ち上げているサーバの標準出力に印字されます。また `debug` ログだけではなくエラーログなどログレベルを指定することが出来て `MOJO_MODE` の環境変数等に決まるモードによってどのレベルのログが出力されるかが制御されます。

```pl
get '/' => sub {
    my $self = shift;
    $self->app->log->debug('This is debug log!');
    ...;
};
```

#### テンプレートをレンダリングする

後ほど説明するテンプレートファイルに値を渡しつつレンダリングする方法です。

```pl
get '/' => sub {
    my $self = shift;
    my $self->stash->{message} = 'Hello Mojolicious';
    $self->render('index');
};
```

`$self->stash` にデータ構造を入れるとそれがそのままテンプレートで変数化します。また `renderメソッド` で対象のテンプレートファイルを指定します。

#### JSONを出力する

先ほどの `render` メソッドの呼び方をちょいと変えて、ハッシュリファレンスや配列リファレンスなどを与えます。

```pl
get '/json' => sub {
    my $self = shift;
    my $result = { status => 'OK', message => 'I am Fine!' };
    $self->render( json => { result => $result  } );
};
```

#### リダレイクトさせる

`redirect_to` メソッドを使います。パスだけ書いて同じアプリケーション内へ、`http://` からはじめてフルでURLを書くと外部サイトへ飛びます。

```pl
get '/dummy' => sub {
    $self = shift;
    $self->redirect_to('/');
};
```

***

### テンプレート

#### 変数の展開

Perl-rish、つまり、Perlがそのまま書けてしまうMojo::Templateに習います。コントローラから渡ってきた変数の展開は基本このように書きます。

```html
<p> Message : <%= $message %></p>
```

`<%= $value %>` とすることで自動的にエスケープが走ります。どうしてもエスケープさせたくない場合は `<%== $value %>` を使いますがあんま機会はないでしょう。ちなみに今回「変数」と言ってますがオブジェクトをstashで渡してそのメソッドもそのまま実行出来ます。

#### ループ

Perlがそのまま書けるので for文で回しちゃいます。`entries` に配列リファレンスが入っているとして

```html
<ul>
% for my $entry (@$entries) {
  <li><%= $entry->{title} %></li>
% }
</ul>
```

でイケますね。

#### レイアウトの適応

テンプレート内で`layoutメソッド`や`contentメソッド`を利用するとヘッダーやフッターを含んだ「外枠」と「コンテンツ」を分けて記述することになります。

```html
@@ layouts/default.html.ep
<html><body>
  <div id=“content”>
    <%= content %>
  </div>
</body></html>

@@ index.html.ep
% layout ‘default’;

<p>This is content section!</p>
```

***

### その他

####  セッションを使う

Mojoliciousデフォルトのセッションを使う場合は必ず `app->secret()` メソッドでアプリケーション独自の秘密のパスワードみたいなのを設定してから使いましょう。

```pl
use Mojolicious::Lite;

app->secret('secret_password');

get '/' => sub {
    my $self = shift;
    $self->session->{count}++;
    $self->render('index');
};

app->start();
__DATA__

@@ index.html.ep
Count: <%= session 'count' %>
```

#### User-Agent名を取得する

リクエストオブジェクトが `$self->req` で取れるのでそこから辿ります。

```pl
get 'ua' => sub {
    my $self = shift;
    my $ua = $self->req->headers->user_agent;
    $self->stash->{ua};
    $self->render();
};
```

***

あとはチュートリアル見てください。

- [Mojolicious::Lite - search.cpan.org](http://search.cpan.org/~sri/Mojolicious-4.62/lib/Mojolicious/Lite.pm#TUTORIAL)
- [Mojolicious::Lite - Real-time micro web framework - metacpan.org - Perl programming language](https://metacpan.org/pod/Mojolicious::Lite#TUTORIAL)

以下は昨日食べた「ねぎま鍋」の様子です。本文との関連はありません。

![IMG_2523.JPG](https://qiita-image-store.s3.amazonaws.com/0/22289/683a4240-81fd-dcf1-6561-0e3d9d5f9e0a.jpeg)