NAME
Waft - A simple web application framework
SYNOPSIS
Waft は、アプリケーションクラスの基底クラスとなって動作する、CGI用の フレームワークである。
package MyWebApp;
use base qw( Waft );
__PACKAGE__->use_utf8;
__PACKAGE__->set_default_content_type('text/html; charset=UTF-8');
sub __default__direct {
my ($self) = @_;
return 'TEMPLATE';
}
クラスメソッド waft
は、アプリケーションクラスに属するオブジェクトを 生成して、リクエストに応じたメソッドをディスパッチする。
MyWebApp->waft;
また、テンプレート処理も実装している。
<%
use strict;
use warnings;
my ($self) = @_;
%>
<h1><% = $self->page %></h1>
<p>
Howdy, world!
</p>
DESCRIPTION
Waft は、1ファイルのみで構成された軽量の Webアプリケーションフレームワークであり、Perl 5.005 以上で動作する。(ただし、 UTF-8 を扱うには 5.8.1 以上の Perl と 3.21 以上の CGI が必要。)
リクエストに応じたメソッドのディスパッチ、 オブジェクト変数の保持、 テンプレート処理 等の機能を有する。
DISPATCH
Waft は、リクエストに応じたメソッドをディスパッチする。
CGI が QUERY_STRING を指定されずに単純に GET リクエストされた場合、 Waftは、__default__direct
という名前のメソッドを起動する。
http://www/mywebapp.cgi
$self->__default__direct を起動する
form.html というページをリクエストされた場合は、__form__direct
という名前の メソッドを起動する。
http://www/myapp.cgi?p=form.html
$self->__form__direct を起動する
form.html から "send" という名前の SUBMIT によりリクエストされた場合は、 __form__send
という名前のメソッド。
http://www/myapp.cgi?s=form.html&v=&send=
$self->__form__send を起動する
メソッド __form__send
が、"confirm.html" を戻した場合は、Waft は次に、 __confirm__indirect
という名前のメソッドを起動する。
sub __form__send {
my ($self) = @_;
return 'confirm.html';
}
$self->__confirm__indirect を起動する
ACTION METHOD
Waft がディスパッチするメソッドをアクションメソッドと呼ぶ。 アクションメソッドの名前は、page_id
と action_id
で構成する。
page
Web の 1ページに相当する単位で、アクションメソッド名の構成と テンプレートの選択のために使用する。
$self->page
で取得できる。page_id
page
の英数字以外の文字をアンダースコアに変換し、拡張子を除いた文字列。 form.html の場合は "form"、form/header.html の場合は、"form_header" となる。$self->page_id
で取得できる。action
page
へのリクエストの種別。page
とともに、 アクションメソッド名を構成する。リンクによるリクエストの場合は "direct"、 FORM からの SUBMIT によるリクエストの場合はその SUBMIT の NAME(以下の例では "send")、<input type="submit" name="send" /> ^^^^
クライアントからのリクエストではなく、メソッドの戻り値で指定された
page
への内部のページ遷移の場合は "indirect" となる。なお、FORM からの SUBMIT によるリクエストにおいて、SUBMIT に NAME が指定されていない場合、
action
は "submit" となる。<input type="submit" />
action_id
action
の先頭から . までの文字列。direct の場合は "direct"、move.map.x の場合は "move" となる。
アンダースコア 2つ、page_id
、アンダースコア 2つ、action_id
を連結した文字列をアクションメソッドの名前とする。
__ page_id __ action_id
return $page
アクションメソッドの戻り値を次に処理する page
として、 引き続きアクションメソッドのディスパッチを行う。この場合、action
は "indirect" とする。
return 'confirm.html'; # Waft は次に __confirm__indirect を起動する
ただし、戻り値を以下のように指定する事で、action
に "indirect" 以外の値も指定できる。
return ['form.html', 'direct']; # Waft は次に __form__direct を起動する
もしくは、
return { page => 'form.html', action => 'direct' }; # same as above
'CURRENT'
"CURRENT" は、"現在のページ" を意味する。すなわち return 'CURRENT'
は、 return $self->page
と同義である。
return 'CURRENT';
return $self->page; # same as above
return 'TEMPLATE'
アクションメソッドの戻り値が "TEMPLATE" の場合、 Waft はアクションメソッドのディスパッチを終了して、page
のテンプレート処理に移行する。
sub __form__direct {
return 'TEMPLATE'; # form.html のテンプレート処理に移行する
}
Waft は、"CURRENT" の場合と同様に page
を 変更せず、action
を "template" として処理する。すなわち return 'TEMPLATE'
は以下と同義である。
return ['CURRENT', 'template'];
もしくは、
return { page => 'CURRENT', action => 'template' };
begin
Waft の処理の開始時にディスパッチされるメソッド。
begin
|
|<---------------------------+
before |
| |
ACTION METHOD return 'other.html' |
+----------------------------+
| return 'TEMPLATE'
|
before
|
TEMPLATE PROCESS
|
|
end
begin
と before
の戻り値は、アクションメソッドのそれと同様に処理される。
sub begin {
return 'TEMPLATE'; # アクションメソッドをディスパッチせずにテンプレー
# ト処理に移行する
}
before
アクションメソッドをディスパッチする前、およびテンプレート処理を行う前に ディスパッチされるメソッド。
sub before {
my ($self) = @_;
return if $self->page eq 'login.html';
return 'login.html' if not $self->login_ok;
return;
}
end
Waft の処理の終了時にディスパッチされるメソッド。
OBJECT VALUE
Waft が生成するオブジェクトが持つ値をオブジェクト変数と呼ぶ。 オブジェクト変数は QUERY_STRING および FORM に展開され、 ページ遷移後に生成されるオブジェクトに引き継がれる。
sub __default__direct {
my ($self) = @_;
$self->{page} = 0;
$self->{sort} = 'id';
return 'TEMPLATE';
}
<a href="<% = $self->url('page.html', 'ALL_VALUES') %>">
page.html へ遷移するリンクの QUERY_STRING にオブジェクト変数が展開される
sub __page__direct {
my ($self) = @_;
$self->{page} # 0
$self->{sort} # 'id'
QUERY_STRING の場合は、引き継ぐ値、もしくは "ALL_VALUES" の指定が 必要であるが、FORM の場合はメソッド compile_template
が自動的に展開する。
<form action="<% = $self->url %>">
<input type="submit" />
</form>
compile_template が <form></form> の中に自動的に展開する
オブジェクト変数は 1次元のハッシュ変数で管理されるため、 リファレンスを引き継ぐ事はできない。また、undef
も引き継ぐ事ができない。
ただし、メソッド set_values
、get_values
により 1つのキーでリストを扱う事 ができる。
$self->set_values( sort => qw( id ASC ) );
$self->{sort} # 'id'
$self->get_value('sort') # same as above
$self->get_values('sort') # ('id', 'ASC')
$self->get_values('sort', 1) # ('ASC')
TEMPLATE PROCESS
Waft は、Perl コードをスクリプトレットとして処理するテンプレート処理機能を 持つ。
page
をテンプレートファイルとして処理する。 テンプレートファイルはアプリケーションクラスおよびその基底クラスのモジュールが 配置されているディレクトリから検索される。
アプリケーションクラス "MyWebApp" が、基底クラス "Waft::CGISession"、"Waft" を 継承している場合、default.html は以下の順に検索される。
lib/MyWebApp.template/default.html
lib/MyWebApp/default.html
lib/Waft/CGISession.template/default.html
lib/Waft/CGISession/default.html
lib/Waft.template/default.html
lib/Waft/default.html
page
が @Waft::Allow_template_file_exts
に定義されていない拡張子 (.html、.css、.js、.txt 以外の拡張子)である場合は、検索されるディレクトリは .template のみとなる。
lib/MyWebApp.template/module.pm
lib/Waft/CGISession.template/module.pm
lib/Waft.template/module.pm
最初に見つかったファイルをテンプレートファイルとして処理する。
テンプレートファイル内の "<%" と "%>" で囲まれた部分はスクリプトレットとして 処理される。
<% for ( 1 .. 10 ) { %>
<br />
<% } %>
"<%word=" と "%>" で囲まれた部分は、評価結果がエスケープされて出力される。
<% for ( 1 .. 4 ) { %>
<%word= $_ %> * 2 = <%word= $_ * 2 %><br />
<% } %>
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
<% my $break = '<br />'; %>
<%word= $break %>
<br />
"<%word=" は "<%w=" もしくは "<%=" に省略できる。スペースを空ける事もできる。
<%word=$self->url%>
<%w= $self->url %> <!-- same as above -->
<% = $self->url %> <!-- same as above -->
"<%text=" と "%>" で囲まれた部分は、評価結果がエスケープされ、 さらにタブ文字の展開と改行タグの挿入が行われて出力される。
<% my $text = "Header\n\tItem1\n\tItem2"; %>
<%text= $text %>
Header<br />
Item1<br />
Item2
"<%text=" は "<%t=" に省略できる。 "<%word=" と同様にスペースを空ける事もできる。
<%text=$self->{text}%>
<% t = $self->{text} %> <!-- same as above -->
"<%jsstr=" と "%>" で囲まれた部分は、JavaScript に必要なエスケープが行われる。
alert('<%jsstr= '</script>' %>');
alert('\x3C\/script\x3E');
"<%jsstr=" は "<%j=" に省略できて、他と同様にスペースも空けられる。
METHODS
set_waft_backword_compatible_version
引数: $version
クラスメソッド。Waft の過去のバージョンを保持する。いくつかのメソッドと処理が 指定バージョンの仕様になる。
use_utf8
クラスメソッド。内部処理を UTF-8 で行う。5.8.1 以上の Perl と 3.21 以上の CGI が必要。
set_allow_template_file_exts
引数: @extensions
クラスメソッド。クラスのモジュールが配置されているディレクトリから検索する 対象とするテンプレートファイルの拡張子を保持する。詳細は "TEMPLATE PROCESS" を参照の事。
set_default_content_type
引数: $content_type
クラスメソッド。"header" で Content-Type が指定されない場合の値を保持する。 デフォルトは text/html。
waft
引数: @arguments?
戻り値: @return_values
オブジェクトの生成("new")、初期化("initialize")を行い、Waft の処理を 行う。オブジェクトメソッドの場合は Waft の処理のみを行う。Waft の処理の詳細は "DISPATCH" を参照の事。指定された引数を最初に呼ぶメソッドに渡し、最後に 呼んだメソッドの戻り値を戻す。
new
戻り値: $object
クラスメソッド。オブジェクトの生成を行う。
initialize
戻り値: $object
オブジェクトの初期化を行う。
cgi
戻り値: $cgi
CGI オブジェクトを戻す。
set_value
引数: $key, $value
オブジェクト変数に値を保持する。
set_values
引数: $key, @values?
オブジェクト変数に複数の値を保持する。
get_value
引数: $key, $i?
戻り値: $value
オブジェクト変数の値を戻す。指定された引数を複数の値に対する添え字とする。
get_values
引数: $key, @i?
戻り値: @values
オブジェクト変数の複数の値を戻す。指定された引数を添え字とする。
clear_values
オブジェクト変数を全て削除する。
page
戻り値: $page
page を戻す。
action
戻り値: $action
action を戻す。
header
引数: $response_header
レスポンスヘッダを保持する。"output" が呼ばれるまでに呼ばれる必要がある。 add_header という別名もある。
call_template
引数: $page or $template_path, @arguments?
戻り値: @return_values
引数に指定されたページ、またはパスのファイルのテンプレート処理を行う。詳細は "TEMPLATE PROCESS" を参照の事。include という別名もある。
url
引数: $page, \@keys? and/or @key_value_pairs?
戻り値: $url
URL を戻す。引数に指定されたページとオブジェクト変数のキー、キー値ペアを クエリ文字列に構成する。
$self->{page} = 0;
$self->{sort} = 'id';
$self->url('CURRENT', ['page', 'sort']);
# { page => 0, sort => 'id' } となる URL
$self->url('CURRENT', ['page']);
# { page => 0 } となる URL
$self->url('CURRENT', ['page'], sort => 'name');
# { page => 0, sort => 'name' } となる URL
$self->url('CURRENT', page => 1, sort => 'name');
# { page => 1, sort => 'name' } となる URL
absolute_url
引数: $page, \@keys? and/or @key_value_pairs?
戻り値: $absolute_url
http://、または https:// から始まる URL を戻す。
output
引数: @strings?
引数に指定された値を出力する。テンプレート処理でも使用する。最初に 呼ばれた時には、"header" で指定されたレスポンスヘッダも出力する。
get_content
引数: $coderef, @arguments?
戻り値: $content, @return_values
引数で指定された無名サブルーチンを呼ぶ。その間 "output" に値を出力させずに バッファリングさせて、バッファの内容を戻す。
stash
引数: $class?
戻り値: $hashref
クラスの名前(引数に指定されたクラス、引数が指定されない場合は呼び出し元の クラスの名前)毎に保持する stash のリファレンスを戻す。stash は アプリケーションが自由に使用できるハッシュ変数。
html_escape
引数: @values
戻り値: @escaped_values
エスケープを行う。テンプレート処理でも使用する。
jsstr_escape
引数: @values
戻り値: @escaped_values
JavaScript に必要なエスケープを行う。テンプレート処理でも使用する。
url_encode
引数: @values
戻り値: @encoded_values
URL エンコードを行う。"url"、"absolute_url" でも使用する。
warn
引数: @messages?
アプリケーションクラスを呼び出し元とする警告メッセージを出力する。
package MyWebApp::Base;
use base qw( Waft );
use Carp;
sub foo {
my ($self) = @_;
warn 'error'; # error at - line 10. # here
carp 'error'; # error at - line 31
$self->warn('error'); # error at - line 24.
return;
}
package MyWebApp;
use base qw( MyWebApp::Base );
sub foo {
my ($self) = @_;
$self->next; # line 24
return;
}
package main;
MyWebApp->new->foo; # line 31
die
引数: @messages?
"warn" と同様のメッセージを出力して例外を発生する。
next
引数: @arguments
戻り値: @return_values
継承元の同名のメソッドを呼ぶ。
AUTHOR
Yuji Tamashiro, <yuji@tamashiro.org>
COPYRIGHT AND LICENSE
Copyright (C) 2007-2009 by Yuji Tamashiro
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.