ThinkIT「SledgeによるWebアプリケーションフレームワーク入門」を書かせて頂きました。今回から数回にわたってWebアプリケーションについて紹介しながら、Sledgeではどう実現するのかについて、にぽたん研究所な人、#!shebang.jpな人 、自分の三人で書かせて頂く予定です。 この連載では、主題が「Webアプリケーションフレームワーク」なのでSledgeの詳しい説明を盛り込んでいません。そこで、この際なのであちらでは書ききれなかったSledgeの設定方法についての説明をこのページで書こうかと思います。 とりあえずSledgeを使ってページが表示できるまでを書いていきます。 途中で挫折したらすみません…。 今回の目標としてhttp://sledge.example.com/index.cgiにアクセスをしたら Hello World と表示するだけのアプリケーションを作成することとします。 とりあえず、ThinkITにも書かせてもらったSledgeのインストールに関しての説明は省かせて頂きます。基本的には下記のコマンドでインストールできると思います。流れとしては「Sledgeで使用するCPANモジュールのインストール」「Makefileの生成」「make」「テスト」「インストール」です。
Sledgeのソースをダウンロード後
% tar zxvf Sledge-1.11.tar.gz
% cd Sledge-1.11
# eg/cpan_install.pl
% perl Makefile.PL
% make
% make test
# make install
プロジェクトの作成手順を説明する前に、基本情報として下記を想定しています。
  • プロジェクト名
  • helloプロジェクト(うーむ…w、ライブラリのネームスペースはHelloとさせていただきます)
  • プロジェクトディレクトリ
  • /home/clouder/hello
  • プロジェクトディレクトリ以下の構造
  • hello
     +- view   テンプレートを置くディレクトリ
     +- htdocs ドキュメントルート
     +- lib    ライブラリを置くディレクトリ
    
  • データベース
  • mysql-4.0.2
  • サーバ
  • apache-1.3.33 mod_perl-1.29
ではプロジェクトを作成していきたいと思います。 まずはSledgeのプロジェクトを生成します。sledge-setupというコマンドがインストールされているはずですので、それを使ってプロジェクトの雛形を作成します。この作業は/home/clouder/hello/libに移動してから下記のコマンドを実行します。
% sledge-setup Hello
これを実行するとlibの中に下記のようなファイルとディレクトリが自動生成されます。
hello
 +- view
 +- htdocs
 +- lib
     +- Hello
         +- Pages.pm
         +- Config.pm
         +- Config
             +- _common.pm
次にmysqlにプロジェクト用のデータベースを作成し、そのデータベースにセッション保持用のテーブルを作成します。Sledgeのソースのegディレクトリの中にあるsessions.sqlにmysql用のセッションテーブルのCREATE文が書かれていますので、それを使用します。
% mysqladmin -u root create hello
% mysql -u root hello < sessions.sql
次にライブラリを書いていきます。まずは設定ファイルに「テンプレートのディレクトリ($C{TMPL_PATH})」「DBのデータソース($C{DATASOURCE})」「クッキーの情報($C{COOKIE_NAME}, $C{COOKIE_PATH}, $C{COOKIE_DOMAIN})」を設定します。 lib/Hello/Config/_common.pm
package Hello::Config::_common;
 
use strict;
use vars qw(%C);
*Config = \%C;
 
$C{TMPL_PATH}     = '/home/clouder/hello/view';
$C{DATASOURCE}    = [ 'dbi:mysql:hello','root', '' ];
$C{COOKIE_NAME}   = 'hello_sid';
$C{COOKIE_PATH}   = '/';
$C{COOKIE_DOMAIN} = '.example.com';
 
1;
Configディレクトリは、アプリケーションの設定をするファイルを入れておくディレクトリになります。sledge-setupを実行した際に作成される_common.pmは全般的な(ステージング、プロダクション環境に依存しない)設定を書いておくファイルになります。その上でステージングとプロダクションなど、環境毎に設定を読み分けるためには、Configディレクトリに_production.pmや_staging.pm等のファイルを作成し、それぞれに設定を書いておくとよいでしょう。 この設定ファイルの読み分けは、Config.pmを見るとわかると思いますが「SLEDGE_CONFIG_NAME」という環境変数によって行ないます。SLEDGE_CONFIG_NAMEに_productionと設定すれば「_common.pmと_production.pm」を、_stagingと設定すれば「_common.pmと_staging.pm」を読み込みます。ですので特に_production.pmや_staging.pmという名前である必要はありません。 SLEDGE_CONFIG_NAMEを設定する場所ですが、主に/etc/Hello-conf.plかapacheの設定ファイル等になります。Config.pmがロードされる際に設定されているSLEDGE_CONFIG_NAMEの設定ファイルが読み込まれるようになっています。ちなみに_common.pmと_production.pmに同じ設定値がある場合には、_production.pmの値の方が設定されます(_common.pmで設定した値は上書きされます)。 今回は特にステージング、プロダクションの違いがないアプリケーションを作成しますので、_common.pm以外のConfigファイルは作成しませんでした。 次にトリガーとなるCGIファイルとそれに対応するPagesクラス、テンプレートを作成します。 Pagesクラスとは、ページの基本となる関数(ビジネスロジック)を定義するクラスのことです。簡単に説明をすると、http://sledge.example.com/index.cgiというページを作成したい場合には、htdocs/index.cgiというファイルに下記のような内容を書き、それがトリガーとなり、Hello::Pages::Root(ファイルではlib/Hello/Pages/Root.pm)というクラスに定義されたdispatch_indexという関数が呼びだされるいった具合です。htdocs/index.cgi、lib/Hello/Pages/Root.pm、view/index.htmlは下記のような内容になります。 htdocs/index.cgi
#!/usr/local/bin/perl
 
use strict;
use Hello::Pages::Root;
Hello::Pages::Root->new->dispatch('index');
lib/Hello/Pages/Root.pm
package Hello::Pages::Root;
 
use strict;
use base qw(Hello::Pages);
 
__PACKAGE__->tmpl_dirname('.');
 
sub dispatch_index {
    my $self = shift;
    $self->tmpl->param(string => 'Hello World!');
}
 
1;
view/index.html
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h1>[% string %]</h1>
</body>
</html>
テンプレートとPagesクラスの結び付きに関しては、Pagesクラス毎に設定されるパッケージ変数「tmpl_dirname」に設定されたディレクトリとConfigファイルで定義したテンプレートのディレクトリ名($C{TMPL_PATH})を連結したディレクトリの中のファイルを読み込むようになっていて、ファイル名はdispatch_indexのindexに.htmlを付けたもの、つまりindex.htmlというファイルを読み込み、表示させるようになっています。 上記のHello::Pages::Rootの場合には、tmpl_dirnameには「.」が定義されていますので、/home/clouder/hello/view/./index.htmlというテンプレートファイルが読み込まれます。今回は「.」を設定していますが、これは特別な例です。「/」以下のページ用のクラスのみtmpl_dirnameを設定しなくても動作しますし、「.」と設定しても動作します。それ以外のURIの場合、例えばhttp://sledge.example.com/foo/index.cgiの場合には、Hello::Pages::Fooのtmpl_dirnameにfooを設定し、そうすることで/home/clouder/hello/view/foo/以下のテンプレートを読み込むようになります。 ちなみに、http://sledge.example.com/foo/index.cgiだからといって、必ずしもそれに対応するクラスをHello::Pages::Fooとする必要はなく、どんなクラス名でも問題ありません。index.cgiの中で、それをuseしてキック(dispatch)してやればいいだけです。ただ、クラスを階層構造にした方がメンテナンス性は向上すると思います ここでPagesクラスの書き方について、もうちょっと詳しく説明すると、dispatch_indexの中ではテンプレートに表示するための変数をDBから取得したり、DBにレコードを生成したり、いろいろな計算をしたり、セッションの値をgetしたりsetしたり、テンプレートへ渡す値をセットしたり、といったビジネスロジックを記述するのですが、上記の例では、テンプレートに「string」という変数で「Hello World!」という値をセットしています。SledgeではデフォルトでTemplate-Toolkitがテンプレートエンジンとなっているため、view/index.htmlのテンプレートで、[% string %]という記述を書いておくことにより、Hello::Pages::Root::dispatch_indexでセットした値を表示することができます。 ここまで作成ができたら、あとはapacheの設定でこのWebアプリケーションを表示できるように設定をするだけです。今回はFQDNをsledge.example.comとし、Webアプリケーションのベースディレクトリを/home/clouder/helloにしていますので、下記のように設定します。 httpd.conf
ServerName sledge.example.com
DocumentRoot /home/clouder/hello/htdocs
 
<Directory /home/clouder/hello/htdocs>
DirectoryIndex index.cgi index.html
PerlSetEnv PERL5LIB /home/clouder/hello/lib
 
<Files ~ \.cgi$>
Options +ExecCGI
SetHandler perl-script
PerlHandler Apache::Registry
</Files>
</Directory>
ちなみに先程話したConfigで使用されるSLEDGE_CONFIG_NAMEをここで設定することもできます。設定をする場合には、
PerlSetEnv SLEDGE_CONFIG_NAME _production
とします。 さて、httpd.confの設定が終ったらapacheを起動させます。起動が完了したらhttp://sledge.example.com/index.cgiにアクセスしてみましょう。「Hello World!」と表示されたらば成功です。表示されない場合には、apacheのerror_log等を見て問題がなにか調べてみましょう。 このWebアプリケーションの処理の流れをまとめると、
  1. index.cgiがトリガーとなり
  2. Hello::Pages::Rootのdispatch_indexが呼ばれ、string変数に'Hello World!'がセットされ
  3. /home/clouder/hello/view/index.htmlがテンプレートエンジンによって処理され、stringがセットされ
  4. 最後に表示される
といった感じです。 その他にも今回は使用していないAuthorizerのフェーズや各種トリガーポイントでの処理をはさんだりといろいろな処理をすることができますが、とりあえずはこれでSledgeが動くことが体感できると思います。 疲れた…。 続く…(たぶん…)