2006年03月07日
SledgeでUTF8なサイトを作る。
Sledgeはプログラム内で扱うデータがEUC-JPにエンコードされたバイナリデータを前提としていて、テンプレートもEUC-JPで作成する必要があります。
これだけが原因ではないのですが、UTF-8なサイトを作ろうとすると、結構いろいろなワナがあります。
このことはSledgeのメーリングリストでも、過去にいろいろ議論されています。
http://lists.sourceforge.jp/mailman/archives/sledge-users/2004-March/000281.html
http://lists.sourceforge.jp/mailman/archives/sledge-users/2004-March/000292.html
http://lists.sourceforge.jp/mailman/archives/sledge-users/2004-March/000294.html
これらの議論は2004年の3月に行われているので、もう2年も前。これだけ時間がたっているので、SledgeでUTF-8をガンガン使っている人もたくさんいると思うのですが、最近ふと、SledgeでUTF8なサイトを作ろうと思い、情報集めのためにググッてみた際、「SledgeでUTF-8扱うにはこうすればいい!」というようなそのものずばりな解決法が見つからなかったので、僕がSledgeでUTF8なサイトを作ったその過程と成果物をさらしてみたいと思います。
* 過程
まず、SledgeでUTF-8を扱うにあたって、以下のような暗黙のルールを定義しました。
- プログラム内で扱うデータはFlagged UTF-8
- テンプレートの文字コードはUTF-8
- RequestクラスでインプットデータをFlagged UTF-8にデコード
- アウトプット時にUnflagged UTF-8にエンコード
- mod_perlで運用すること前提。CGIでの動作は無視
次に上記を実現するようなモジュールを書いてみました。
* Sledge::Pages::Apache::I18N
まずは、インプットデータをFlagged UTF-8にデコードするRequestクラスを作ってみました。これはSledgeに標準でついているSledge::Charset::UTF8を使うとできそうですが、Sledge::Charset::UTF8でインプットデータをFlagged UTF-8にデコードしてもApache::RequestがUnflaggedなデータにしてしまうため、うまくいかないようです。
なので、Apache::Requestをどうにかしないといけないのですが、CPANを眺めていたら、Apache::Request::I18Nというまさにそのものずばりなモジュールがあったのでこいつを使ってみました。
こいつを使って書いたSledge::Pages::Apacheの代替モジュールはこんな感じです。
package Sledge::Pages::Apache::I18N;
use strict;
use base qw(Sledge::Pages::Base);
use Apache;
use Apache::Request::I18N;
sub create_request {
my ($self, $r) = @_;
my $req = Apache::Request::I18N->new(
$r || Apache->request,
DECODE_PARMS => 'utf-8',
);
# $req->param; do parse here
return $req;
}
1;
* Sledge::Charset::UTF8::I18N
次に、Sledge::Pages::Apache::I18Nでインプットデータのデコードをやってくれるようになったので、
アウトプットの際のエンコードのみを行うSledge::Charsetサブクラスを作りました。
package Sledge::Charset::UTF8::I18N;
use strict;
use base qw(Sledge::Charset::Null);
use vars qw($VERSION);
$VERSION = '0.01';
use Encode;
sub content_type {
return 'text/html; charset=UTF-8';
}
sub output_filter {
my($self, $content) = @_;
return Encode::encode("UTF-8", $content);
}
1;
* Sledge::Template::TT::I18N
最後に、UTF-8なテンプレートを読み込んで内部ではFlagged UTF-8として扱ってくれるSledge::Template::TTの代替モジュールを作成しました。Sledge::Template::TTだとUTF-8なテンプレートを読み込んでも内部では、UnflaggedなUTF-8として扱われるので、Flagged UTF-8な文字列を埋め込むと文字化けを起こしてしまいます。
package Sledge::Template::TT::I18N;
use strict;
use base qw(Sledge::Template::TT);
use vars qw($VERSION);
$VERSION = '0.01';
sub output {
my $self = shift;
my %config = %{$self->{_options}};
my $input = delete $config{filename};
$config{LOAD_TEMPLATES} = [Sledge::Template::TT::I18N::Provider->new(\%config)];
my $template = Template->new(\%config);
unless (-e $input) {
Sledge::Exception::TemplateNotFound->throw(
"No template file detected. Check your template path.",
);
}
$template->process($input, $self->{_params}, \my $output)
or Sledge::Exception::TemplateParseError->throw($template->error);
return $output;
}
package Sledge::Template::TT::I18N::Provider;
use strict;
use base qw(Template::Provider);
sub _load {
my $self = shift;
my ($data, $error) = $self->SUPER::_load(@_);
if(defined $data) {
$data->{text} = utf8_upgrade($data->{text});
}
return ($data, $error);
}
sub utf8_upgrade {
my @list = map pack('U*', unpack 'U0U*', $_), @_;
return wantarray ? @list : $list[0];
}
1;
* MyProj::Pagesクラスに組み込む
今まで作成したモジュールはこんな感じでPagesクラスに組み込みました。
package YourProj::Pages;
use strict;
use base qw(Sledge::Pages::Apache::I18N);
use Sledge::Template::TT::I18N;
use Sledge::Charset::UTF8::I18N;
....
sub create_charset {
my $self = shift;
Sledge::Charset::UTF8::I18N->new($self);
}
これでとりあえず、SledgeでUTF-8を扱うことができました。
* 成果物
今回作成したモジュールたちです。
Continuing the discussion...
このエントリーのトラックバックURL:
http://hori-uchi.com/mt/trackback/421
Comments
Торговый дом "АрмСнаб" реализует со склада в г.Москве трубопроводную арматуру, детали трубопровода и насосное оборудование. Оптовая реализация счетчиков воды, теплосчетчиков, задвижек стальных и клапанов. Технические характеристики водосчетчика, задвижки, клапана и шарового крана на сайте [url=http://www.armsnab.ru]www.armsnab.ru[/url]. Доска объявлений сайта АрмСнаб. Купить задвижку, продать задвижки на доске объявлений сайта АрмСнаб
Трубопроводная арматура Клапаны регулирующие
Счетчики воды импульсный водосчетчик
Задвижки стальные Задвижки стальные 30с599нж Pn 25
Задвижки из легированной стали Задвижки из легированной стали 30лс99нж
Задвижки из нержавеющей стали Задвижки из нержавеющей стали 30нж964нж
Задвики чугунные МЗВГ
КРАНЫ ШАРОВЫЕ Кран шаровой 11с17бк
КЛАПАНЫ ЗАПОРНЫЕ (ВЕНТИЛИ) Клапан запорный (Вентиль) 15с51п3
КЛАПАНЫ ОБРАТНЫЕ ПОДЪЕМНЫЕ Клапан обратный подъемный 16с28нж
КЛАПАНЫ ОБРАТНЫЕ ПОВОРОТНЫЕ Клапан обратный поворотный 19с53нж
ЭЛЕКТРОПРИВОДЫ Электропривод В-Д
СЧЕТЧИКИ ГОРЯЧЕЙ ВОДЫ Счетчики горячей воды ОСВУ
СЧЕТЧИКИ ХОЛОДНОЙ ВОДЫ Счетчики холодной воды Siemenss
ДЕТАЛИ ТРУБОПРОВОДА Трубы чугунные безнапорные
Энергетическая арматура 1057-65-0
Шаровые краны шаровые краны ctpl
Теплосчетчики (Счетчики тепла) теплосчетчик км
Водосчетчики обслуживание водосчетчиков
Счетчики тепла бытовые счетчики тепла
Сварочное оборудование ооо сварочное оборудование
Диспетчеризация проблемы диспетчеризации
Кран кран шаровой 11с67п прайс
Задвижки 30с964нж ду500ру25 алексин
Клапан митральный клапан
Posted by Geomiaziluele at 2008年08月07日 15:20
