テンプレートエンジン
- CAFEMILK SHOPPING CART V5 製品には独自のテンプレートエンジンが搭載されており、通常の HTML ソースに独自タグによる表記を加え、それをテンプレートエンジンに通すことによってウエブ表示等のテキスト出力が完成するという仕組みになっています。
タグ
<#key#>.......... : 低層テンプレートタグ
<##key##>........ : 中層テンプレートタグ
<###key###>...... : 高層テンプレートタグ
<####key####>.... : 低層プラグインタグ
<#####key#####>.. : 中層プラグインタグ
<######key######> : 高層プラグインタグ
- テンプレートタグは主に文字列の出力に用います。
- プラグインタグは plugin 型プラグイン (用語に注意) を呼び出すタグで、プログラムの実行とスキン部品の出力を行います。
- テンプレートタグが簡易、プラグインタグが高度、という位置づけになります。
- # 記号の多さは実行の優先度を表します。つまり、# 記号が多いタグほど優先して実行されます。
- どのタグにも必要に応じてオプションをつけることができます。
- オプションは : (コロン) 区切りで複数を指定できます。
- 以下はオプションの付いたタグの一例です。
<#####mail_cart_record:package#####>
構成
- テンプレートエンジンは、ウェブ処理用とメール処理用の 2 種類あります。
- 基本的な振る舞いはどちらも同じとなります。
- ウェブ用テンプレートエンジンのファイル名は以下の通りとなります。
cafemilk_skin_html.pl
- cafemilk_skin_html.pl は以下のファイルを参照します。
cafemilk_tag_html.pl
- これらのファイルのあるディレクトリは以下の通りです。
[Apache_server]
└ [cgi-bin]
└ [pl]
- メール用テンプレートエンジンのファイル名は以下の通りとなります。
cafemilk_skin_mail.pl
- cafemilk_skin_mail.pl は以下のファイルを参照します。
cafemilk_tag_mail.pl
- これらのファイルのあるディレクトリは以下の通りです。
[Apache_server]
└ [cgi-bin]
└ [pl]
- 基本エンジン (コントローラ) は、 execute の HTML テンプレート処理を肩代わりする仕様となっており、専用のテンプレートコントローラが用意されています。(用語注意)
- MAIL テンプレート処理のテンプレートコントローラはありません。execute 側がコントローラを内包することになります。
- plugin は常にテンプレートコントローラを内包します。
- 内包することを望まない場合、execute 用のテンプレートコントローラを呼び出して使用することが可能です。
- テンプレートコントローラのファイル名は以下の通りとなります。
cafemilk_template_html.pl
- cafemilk_template_html.pl のあるディレクトリは以下の通りです。
[Apache_server]
└ [cgi-bin]
└ [pl]
設定
- テンプレートタグおよびプラグインタグは、実行を許可されなければなりません。
- あらかじめ規定値(許可のリスト)が設定されています。
- WEB テンプレートタグの規定値は以下に設定されています。
$config->{list}{tag}{html}
- $config->{list}{plugin} を設定しているファイルは以下の通りです。
[Apache_server]
└ [cgi-bin]
└ [config]
└ [admin]
└ config_basic.pl
- MAIL テンプレートタグの規定値は以下に設定されています。
$config->{list}{tag}{mail}
- $config->{list}{plugin} を設定しているファイルは以下の通りです。
[Apache_server]
└ [cgi-bin]
└ [config]
└ [admin]
└ config_basic.pl
$config->{list}{plugin}
- $config->{list}{plugin} を設定しているファイルは以下の通りです。
[Apache_server]
└ [cgi-bin]
└ [config]
└ [admin]
└ config_basic.pl
コントローラ
- テンプレートコントローラは、モジュールとして外部に持つことも、内部に持つこともできます。
- テンプレートエンジンはフレームワークですので操作 (コントロール) の方法がわかれば十分です。
- 以下は、外部モジュールとなる cafemilk_template_html.pl のソースとなります。
- cafemilk_template_html.pl はコントローラとしての機能をすべて備えていますので、コントローラを plugin に内包させる場合などに参考にしてください。
################################################################################
# #
# CAFEMILK SHOPPING CART V5 #
# SOHO WORKSHOP CAFEMILK 全権留保 #
# #
################################################################################
use strict;
# use warnings;
use utf8;
# use encoding "utf8";
use open ":utf8";
require './pl/cafemilk_skin_html.pl';
package Cafemilk_template_html;
sub template
{
my $argument = shift;
my $config = $argument->{config};
my $userdata = $argument->{userdata};
my $log_error = $argument->{log_error};
my $log_alert = $argument->{log_alert};
my $status = $argument->{status};
スキンのパスの受け取り。
my $path = $argument->{skinpath};
テンプレートエンジンを操作するソースはここから
# HTML スキンファイルを読み込みます。
まずはオブジェクト作成。
my $skin_html_main = Cafemilk_skin_html->new
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
name は任意の文字列を充てる。
ここでは execute 名が使われている。
name => "$userdata->{request_values}{execute}[0]",
});
スキンの読み込み。
$path は相対パスで指定する。
$skin_html_main->set_path($path);
プラグインタグ (plugin 型プラグイン) の処理。
# 高層プラグインを抽出。
$skin_html_main->load_plugin_high();
# 高層プラグインを置換。
$skin_html_main->replace_plugin_high
({
allow => $config->{list}{plugin},
plugin_path => "./$config->{path}{plugin}/",
package => 'Cart_plugin',
});
# 中層プラグインを抽出。
$skin_html_main->load_plugin_middle();
# 中層プラグインを置換。
$skin_html_main->replace_plugin_middle
({
allow => $config->{list}{plugin},
plugin_path => "./$config->{path}{plugin}/",
package => 'Cart_plugin',
});
# 下層プラグインを抽出。
$skin_html_main->load_plugin_low();
# 下層プラグインを置換。
$skin_html_main->replace_plugin_low
({
allow => $config->{list}{plugin},
plugin_path => "./$config->{path}{plugin}/",
package => 'Cart_plugin',
});
テンプレートタグの処理。
# 高層タグを抽出。
$skin_html_main->load_tag_high();
# 高層タグを置換。
$skin_html_main->replace_tag_high
({
allow => $config->{list}{tag}{html},
package => "Cafemilk_tag_html",
});
# 中層タグを抽出。
$skin_html_main->load_tag_middle();
# 中層タグを置換。
$skin_html_main->replace_tag_middle
({
allow => $config->{list}{tag}{html},
package => "Cafemilk_tag_html",
});
# 下層タグを抽出。
$skin_html_main->load_tag_low();
# 下層タグを置換。
$skin_html_main->replace_tag_low
({
allow => $config->{list}{tag}{html},
package => "Cafemilk_tag_html",
});
# HTML スキンの処理済みソースを取得します。
my $source = $skin_html_main->get_source();
ここまで。
}
1;
- 次の例は plugin におけるコントローラの実装例です。
################################################################################
# #
# CAFEMILK SHOPPING CART V5 #
# SOHO WORKSHOP CAFEMILK 全権留保 #
# #
################################################################################
use strict;
# use warnings;
use utf8;
# use encoding "utf8";
package Cart_plugin;
sub user_inquiry_step1_html
{
my $package = shift;
my $argument = shift;
my $config = $argument->{config};
my $userdata = $argument->{userdata};
my $log_error = $argument->{log_error};
my $log_alert = $argument->{log_alert};
my $status = $argument->{status};
my $pin_name = 'user_inquiry_step1_html';
my $path = "./$config->{path}{skin}/user/cgi/$config->{default}{user_type}/$userdata->{device_type}/$userdata->{language_type}/$userdata->{currency_type}/$userdata->{template_type}/pin_user_inquiry_step1.html";
my %input_values;
my @list =
qw(
input_1_email_1 input_1_email_2 input_inquiry
);
foreach (@list)
{
$input_values{$_} = $userdata->{request_values}{$_}[0];
}
テンプレートタグ temporal に各情報を格納
格納は $userdata->{tag_data}{temporal}{$key} に行う
foreach (keys %input_values)
{
$userdata->{tag_data}{temporal}{$_} = $input_values{$_};
}
if (($input_values{input_1_email_1} eq '')
and ($input_values{input_1_email_2} eq ''))
{
$userdata->{tag_data}{temporal}{input_1_email_1} = $userdata->{user_registry_values}{'1_email_1'};
$userdata->{tag_data}{temporal}{input_1_email_2} = $userdata->{user_registry_values}{'1_email_1'};
}
ここからテンプレート処理 (コントローラ)
オブジェクト作成
my $skin = Cafemilk_skin_html->new
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
name => $pin_name,
});
スキン読み込み
$skin->set_path($path);
中層テンプレートタグの取得
$skin->load_tag_middle();
許可リストの作成
ここでは temporal のみ許可
my @list = qw(temporal);
中層テンプレートタグの処理
$skin->replace_tag_middle
({
allow => \@list,
package => "Cafemilk_tag_html",
});
コーディングルールにしたがいテンプレートタグ temporal の内容を消去
undef $userdata->{tag_data}{temporal};
処理されたスキンの出力
my $source = $skin->get_source();
}
sub user_inquiry_step1_mail
{
# none
}
1;
- この plugin では、plugin に固有の情報をすべて中層テンプレートタグ temporal にて出力しています。
- そのため、コントローラ部分から必要のない処理は一切省かれています。
- そのため、中層テンプレートタグしか処理されていません。
- また、規定の設定値 $config->{list}{tag}{html} は使用されていません。
- plugin での処理が省かれることにより、plugin で処理されなかった各種タグの処理は execute に回されます。
- たとば、テンプレートタグ path_material はスキン内に大量に出てきますが、これを繰り返し処理するとリソースを食うから、というのが理由です。最終的に execute のコントローラがすべてのタグを処理するので、上記のような処理でタグ処理に漏れがあったとしても問題はなく、plugin は plugin に固有のタグの処理に専念できるというわけです。
- plugin に固有の情報はテンプレートタグは temporal に格納することになります。コーディングルールにより temporal は逐次内容を undef することになっており、その情報が外部に干渉することはありません。
- たとえば、異なる plugin が <##temporal:hoge##> といった同じタグを用いても、あるいは、同じ plugin が複数実行されてその都度同じタグが異なる内容を出力する場合でも、干渉はないということです。
- 他のプラグインで情報を利用する必要がある場合は message を使います。message は undef しないので値を使いまわせます。
- 次の例はメール送信処理の例です。
- メール送信処理はフレームワーク化されているので手間がかかりません。
任意の処理名を設定
my $mail_name = 'user_inquiry_step3_shop';
スキンのパスの指定
my $path = "./$config->{path}{skin}/user/cgi/$config->{default}{user_type}/$userdata->{device_type}/$userdata->{language_type}/$userdata->{currency_type}/$userdata->{template_type}/mail_user_inquiry_step3_shop.txt";
オブジェクト作成
my $skin = Cafemilk_skin_mail->new
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
name => $mail_name,
});
中略
スキンの読み込み
$skin->set_path($path);
中層テンプレートタグの取得
$skin->load_tag_middle();
規定値の取得
my @list = @{$config->{list}{tag}{mail}};
中層テンプレートタグの処理
$skin->replace_tag_middle
({
allow => \@list,
package => "Cafemilk_tag_mail",
});
temporal は uendf する
undef $userdata->{tag_data}{temporal};
処理されたスキンの取得
my $source = $skin->get_source();
メール送信処理
my $from = $config->{sendmail}{address}{shop}{from}[0];
my $to = $input_values{input_1_email_1};
my $cc = '';
my $bcc = '';
my $return = $config->{sendmail}{address}{shop}{return}[0];
Cafemilk_mail::skin_sendmail
({
config => $config,
userdata => $userdata,
log_error => $log_error,
log_alert => $log_alert,
status => $status,
from => $from,
to => $to,
cc => $cc,
bcc => $bcc,
source => $source,
return => $return,
});
最終更新:2009年10月12日 15:02