HTML::MobileJP::Filter::DoCoMoGUIDで同一ホスト内でのguid=ONを有効にするには
今やってるやつでCatalyst::View::MobileJpFilterを使って実装しようと思ってるんだけどHTML::MobileJP::Filter::DoCoMoGUIDで下記のようなケースではguid=ONがついてくれないのです。
<a href="http://example.com/">link</a>
どうやらhttpから始まるURLに対してはつかないようですが、これは元となるHTML::StickyQueryモジュールのabsオプションを使えばついてくれるみたい。
my $html = '<a href="http://example.com/">link</a>'; my $sticky = HTML::StickyQuery::DoCoMoGUID->new; local $sticky->{sticky}->{abs} = 1; $sticky->sticky( scalarref => \$html ); # <a href="http://example.com/?guid=ON">link</a>
ただし、absオプションを使うと問答無用でguidが付いてしまいます。
外部のURLへリンクの場合にはguidが付いて欲しくないことが殆どだとおもうので、それに対応するためにHTML::MobileJP::Filter::DoCoMoGUIDOnHost(名前は適当)を考えてみました。
package HTML::MobileJp::Filter::DoCoMoGUIDOnHost; use Moose; with 'HTML::MobileJp::Filter::Role'; sub filter { my ($self, $html) = @_; unless ($self->mobile_agent->is_docomo) { return $html; } my $sticky = HTML::MobileJp::Filter::DoCoMoGUIDOnHost::_Private->new; local $sticky->{sticky}->{host} = $self->mobile_agent->get_header('host'); $sticky->sticky( scalarref => \$html ); } package HTML::MobileJp::Filter::DoCoMoGUIDOnHost::_Private; use base qw/HTML::StickyQuery::DoCoMoGUID/; sub sticky { my($self, %args) = @_; $args{param} ||= {}; $args{param}->{guid} = 'ON' unless $args{disable_guid}; local $self->{sticky}->{use_xhtml} = exists $args{xhtml} ? $args{xhtml} : 1; local *HTML::StickyQuery::DoCoMoGUID::_start = *HTML::StickyQuery::start; local *HTML::StickyQuery::start = *start; $self->{sticky}->sticky( %args ); } sub start { my $self = shift; my($tagname, $attr, $attrseq, $orig) = @_; my $url = $attr->{href} || $attr->{action} || ''; if ( $url =~ m{^https?://$self->{host}} ) { local $self->{abs} = 1; return $self->HTML::StickyQuery::DoCoMoGUID::start(@_); } $self->HTML::StickyQuery::DoCoMoGUID::start(@_); } 1;
実装ですが、HTML::StickyQuery::DoCoMoGUIDが元々ハック的な実装方法で作られているため、さらにハックハックしちゃって混沌となってしまっています。
もはやここまできたらHTML::StickyQueryとHTML::StickyQuery::DoCoMoGUIDにhostオプションみたいなのを実装するほうが綺麗でしょうね。
# HTML::StickyQuery-v0.12 --- StickyQuery.pm Wed Oct 8 18:46:55 2003 +++ _StickyQuery.pm Mon Aug 18 15:11:34 2008 @@ -88,6 +88,12 @@ $self->{output} .= $orig; return; } + + if ($self->{host} && $u->host ne $self->{host} ) { + $self->{output} .= $orig; + return; + } + # when URI has other scheme (ie. mailto ftp ..) if(defined($u->scheme) && $u->scheme !~ m/^https?/) { $self->{output} .= $orig;
で、HTML::StickyQuery::DoCoMoGUIDもHTML::StickyQueryに引数を渡せるように変更&hostオプションに対応して・・・
# HTML::StickyQuery::DoCoMoGUID-v0.01 --- DoCoMoGUID.pm Tue Apr 8 21:39:12 2008 +++ _DoCoMoGUID.pm Mon Aug 18 15:24:00 2008 @@ -9,7 +9,7 @@ sub new { my $class = shift; bless { - sticky => HTML::StickyQuery->new( regexp => qr/./ ), + sticky => HTML::StickyQuery->new( regexp => qr/./, @_ ), }, $class; } @@ -44,6 +44,11 @@ if (!$self->{abs} && $u->scheme) { $self->{output} .= $orig; return; + } + + if ($self->{host} && $u->host ne $self->{host} ) { + $self->{output} .= $orig; + return; } # when URI has other scheme (ie. mailto ftp ..)
で、さらにHTML::MobileJp::Filter::DoCoMoGUIDもHTML::StickyQuery::DoCoMoGUIDに引数を渡せるように変更すれば・・・
--- DoCoMoGUID.pm Tue Jul 8 06:10:48 2008 +++ _DoCoMoGUID.pm Mon Aug 18 15:20:05 2008 @@ -12,7 +12,10 @@ return $html; } - HTML::StickyQuery::DoCoMoGUID->new->sticky( scalarref => \$html ); + my $config = %{$self->config || {}}; + $config->{host} = $self->mobile_agent->get_header('host') if $config->{host_auto}; + + HTML::StickyQuery::DoCoMoGUID->new(%$config)->sticky( scalarref => \$html ); } 1; __END__ filters: module: DoCoMoGUID config: host_auto: 1
ってな感じで、いけそうです。
ちなみに上記3パッチのみ脳内実装なので動くかわかりません><
追記
id:tomi-ruさんからコメント頂きました。
なるほど、根本解決ではないものの、明らかにそっちの方が楽ですね^^;
Catalyst限定ですが、Catalyst::Plugin::SmartURIを使ってuri_forにて相対URLを返すことよって、そもそも絶対URLを使わないようにして上記の問題を切り抜けるという対策ですね。
とりあえず僕もコレ使います。
ありがとうございました!