Perl入門ゼミ

テキスト処理、Linuxサーバー管理、Web開発ならPerl
  1. Perl
  2. Mojolicious

アプリケーションとコントローラーの機能 | Mojolicious入門

MojoliciousはWebアプリケーションを作る為の便利な機能をたくさん持っています。その中でも、使用頻度が高いものを紹介したいと思います。最初にこれらを覚えておけば、どうしたらいいかを迷わなくてすむと思います。

アプリケーションオブジェクト

アプリケーションの本体を表すオブジェクトをapp関数で取得することができます。app関数はMojolicious::Liteを読み込んだときに、自動的にインポートされます。

use Mojolicious::Lite;

# アプリケーションオブジェクト
my $app = app;

アプリケーションオブジェクトはMojoliciousクラスに属しており、Mojoliciousクラスのメソッドを呼び出すことができます。メソッドの一覧についてはMojolicious API リファレンスを参考にしてください。

ホームオブジェクト

まずMojoliciousのホームディレクトリを表現するhomeオブジェクトを、homeメソッドを使って取得することができます。ホームオブジェクトは、Mojo::Homeクラスに属します。

# ホームオブジェクトの取得
my $home = $app->home;

ホームオブジェクトからは、Mojo::Homeクラスのメソッドを呼び出すことができます。Mojo::Homeはrel_fileというメソッドを持っており、ホームディレクトリからの相対パスで指定したパスを絶対パスに変換してくれます。

my $path_abs = $home->rel_file('db/myapp.db');

これは、データベースファイルなどのパスを取得するときに便利です。

ログファイル

Mojoliciousはログを出力する機構を備えています。アプリケーションと同じディレクトリにlogというディレクトリを作成してみてください。

myapp.pl
log

するとこのディレクトリの中にdevelopment.logというファイルが作成され、ここにアプリケーションのログが出力されます。

log/development.log

このログファイルに自分で出力することもできますが、そのためにはアプリケーションオブジェクトからlogメソッドを使って、ログオブジェクトを取得します。

my $log = $app->log;

ログオブジェクトはMojo::Logクラスに属しています。Mojo::Logクラスは、レベルに応じたログの出力を行うことができます。以下のメソッドを使ってレベルに応じてログを出力することができます。

$log->debug($messgae);
$log->info($messgae);
$log->warn($messgae);
$log->error($messgae);
$log->fatal($messgae);

デバッグのときだけ出力したい情報はdebugで出力します。通常はinfoメソッドで情報を出力して、警告、エラー、致命的なエラーの場合にはwarnメソッド、errorメソッド、fatalメソッドを利用するとよいでしょう。

何がエラーで、何が警告なのかは、プログラマである各自が判断して決めます。

設定ファイル

Mojoliciousでは設定ファイルを簡単に記述することができます。スクリプトと同じディレクトリに、スクリプトと同じ名前で拡張子がconfのファイルを作成してください。

myapp.pl
myapp.conf

この設定ファイルはPerlで記述することができます。

{
  name => 'kimoto',
  age => 19
}

ハッシュリファレンスを記述することに注意してください。また日本語を利用する場合は、ファイルはUTF-8で保存してください。

設定ファイルの読み込み

設定ファイルの読み込みは、Configプラグインを利用することで読み込みます。プラグインとは、Mojoliciousの機能を追加する仕組みのことで、Configプラグインは、設定ファイルを読み込むために最初から容易されているプラグインです。

プラグインを利用するにはplugin関数またはアプリケーションオブジェクトからpluginメソッドを呼び出します。

plugin('Config');
$app->plugin('Config');

これで、設定ファイルが読みこまれ、configメソッドで設定を取得することができます。

# ひとつづつ取得
my $name = $app->config('name');
my $age = $app->config('age');

# 全部を取得
my $config = $app->config;

またアプリケーション上で設定を行うことも可能です。

# 設定
$app->config('name' => 'Ken');

コントローラーでアプリケーションオブジェクトを取得

コントローラーからアプリケーションオブジェクトを取得するには、コントローラーオブジェクトからappメソッドを利用します。

my $app = $c->app;

たとえば、以下のように取得できます。アプリケーションオブジェクトを取得できれば、ここからhomelogを呼び出すこともできますね。

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

  my $app = $self->app;
  $app->log->info('Info');
};

静的ファイルの配置

CSSやJavaScriptや画像などの静的なファイルを利用したい場合は、アプリケーションと同じディレクトリにpublicディレクトリを作成します。

myapp.pl
public

そしてこの中にCSSなどの静的ファイルを配置します。

public/css/common.css
public/js/common.js

静的ファイルはMojoliciousによって自動的にディスパッチされます。次のURLでアクセスすると、これらのファイルを取得できます。

http://localhost:3000/css/common.css
http://localhost:3000/js/common.js

テンプレートの外部ファイル化

Mojolicious::Liteではテンプレートをひとつのファイルの中に書いていましたが、アプリケーションが大きくなってきたときには、外部のファイルに書きたくなってくると思います。

次のアプリケーションを見てください。

use Mojolicious::Lite;

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

  $self->render('info');
};

app->start;

__DATA__

@@ info.html.ep
Information

info.html.epはデータセクションに書かれていますが、このテンプレートを外部ファイル化してみましょう。

まずスクリプトと同じディレクトリにtemplatesというディレクトリを作成します。

myapp.pl
templates

この中に、テンプレートファイルを配置します。

templates/info.html.ep

そして、データセクションは削除してしまいます。

use Mojolicious::Lite;

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

  $self->render('info');
};

app->start;

このようにテンプレートファイルを外部化すると、文法のエラーが発生した行番号などがわかりやすくなるので、便利です。

リダイレクト

リダイレクトとは、他のURLに転送する機能のことです。Mojolicious::Controllerクラスのredirect_toメソッドを使うとリダイレクトを行うことができます。

$c->redirect_to('/other');

これらの機能を使ったサンプル

では最後に、ここで紹介した機能を使ったサンプルを作成してみます。

myapp.pl

最初にアプリケーションの本体を記述します。

use Mojolicious::Lite;

# 設定ファイルの読み込み
plugin('Config');

# ログへの出力
app->log->info('Start application');

# データベースファイルのパスを取得
my $db_file = app->home->rel_file('db/myapp.db');

# / へのアクセス
get '/' => sub {
  my $self = shift;

  # アプリケーション
  my $app = $self->app;

  # ログへ出力
  $app->log->info('Access infomation');
  
  # データベースファイルのパスを取得
  my $db_file = $app->home->rel_file('db/myapp.db');

  # 設定ファイルから取得
  my $name = $app->config('name');
  my $age = $app->config('age');

  # テンプレートの描画
  $self->render(
    'info',
    name => $name,
    age => $age,
    db_file => $db_file
  );
};

# リダイレクト
get '/some' => sub {
  my $self = shift;

  $self->redirect_to('/other');
};

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

  $self->render(text => 'Other');
};

app->start;

log

ログファイルのためのlogディレクトリを作成してください。

myapp.conf

設定ファイルです。myapp.plと同じディレクトリに配置します。

{
  name => 'Kimoto',
  age => 32
}

public/css/common.css

スタイルシートです。publicディレクトリを作成してその中に配置します。

body {
  background:#FFFFEE;
}

templates/info.html.ep

テンプレートファイルです。templatesディレクトリを作成してその中に配置します。

<%
  my $name = stash('name');
  my $age = stash('age');
  my $db_file = stash('db_file');
%>

<html>
  <head>
    <title>Information</title>
    %= stylesheet '/css/common';
  </head>
  <body>
    <b>Name</b>: <%= $name %><br>
    <b>Age</b>: <%= $age %><br>
    <b>Database file</b>: <%= $db_file %><br>
  </body>
</html>

stylesheet関数はここでは解説していませんが、スタイルシートを読み込むためのテンプレートのヘルパーです。

アプリケーションの実行

ディレクトリ構成が以下のようになっているかを確認してください。

myapp.pl
myapp.conf
templates/info.html.ep
public/css/common.css
log

アプリケーションを実行して「/」にアクセスすれば、次のような結果を得ることができます。

Name: Kimoto
Age: 32
Database file: /home/kimoto/labo/db/myapp.db

「/some」にアクセスすれば「/other」にリダイレクトされて、「/other」の内容が表示されます。

Other
Giblog