Name: WikiResource FullName: WikiResource interface URI: IW:SuikaWiki:"Wiki//Resource" Description: This module provides "WikiResource" support. A resource is a record data in the resource database. Using resource database, human readable text is easily customizable and multilingualizationable (With conneg, user preferred language can be automatically selected). Require: SuikaWiki::Plugin::WikiConst main Initialize: my $HAS_XML = SuikaWiki::Plugin->feature ('SuikaWiki::Markup::XML'); my $NS_XHTML1 = 'http://www.w3.org/1999/xhtml'; { Name: wikiform_input/res FullName: Get text from resource Format: $r = $o->resource ($p->{name},escape=>1); } { Name: wikiview/res wikiview-resource/res wikipage_list_item/res wikipage-link/res FullName: Get text from resource Format: $r = $o->formatter('view-resource')->replace ($o->resource ($p->{name}), $o); $r = SuikaWiki::Markup::XML->new (type => '#text', value => $r) unless ref $r; } { Name: wikiview-resource/-bare_text FullName: HTML escape for bare text Format: if ($HAS_XML) { $r = SuikaWiki::Markup::XML->new (type => '#text', value => $p->{-bare_text}); } else { $r = $o->escape ($p->{-bare_text}); } } { Name: wikiview-resource/span wikipage-link/span FullName: Give class name Format: $r = SuikaWiki::Markup::XML->new (namespace_uri => $NS_XHTML1, local_name => 'span'); $r->set_attribute (class => $p->{class}); $r->append_node ($p->{content}, node_or_text => 1); } { Name: wikiview-resource/text FullName: Give class name Format: $r = SuikaWiki::Markup::XML->new (type => '#text', value => $p->{cdata}); } MODULE: my %_Resource; my $default_ns = $main::PageName{ResourceNS}; sub get_resource ($$;%) { my (undef, $s, %o) = @_; $o{ns} ||= $default_ns; unless (defined $_Resource{$o{ns}}->{$s}) { $_Resource{'.//option'}->{$o{ns}}->{resource_ns} = $o{ns}; $_Resource{$o{ns}}->{$s} = wiki::resource::get ($s, $_Resource{'.//option'}->{$o{ns}}); } return $_Resource{$o{ns}}->{$s}; } ## TODO: implement inherit default_ns ?? sub SuikaWiki::Plugin::resource ($$;%) { my (undef, $s, %o) = @_; my $s = __PACKAGE__->get_resource ($s, %o); $o{escape} ? SuikaWiki::Plugin->escape ($s) : $s; } sub main::Resource ($;%) { my ($s, %o) = @_; unless (defined $_Resource{$default_ns}->{$s}) { $_Resource{$default_ns}->{$_[0]} = &wiki::resource::get ($s, $_Resource{'.//option'}->{$default_ns}); } $o{escape} ? SuikaWiki::Plugin->escape ($_Resource{$default_ns}->{$s}) : $_Resource{$default_ns}->{$s}; } sub wiki::resource::get ($;$) { my ($resname, $option) = @_; $option->{accept_language} ||= &wiki::conneg::get_accept_lang (); $option->{resource} ||= {}; $option->{resource_ns} ||= $default_ns; my $v; for my $lang (sort {$option->{accept_language}->{$b} <=> $option->{accept_language}->{$a}} grep {$option->{accept_language}->{$_}!=0} keys %{$option->{accept_language}}) { while (length $lang) { unless ($option->{accept_language}->{defined $option->{accept_language}->{$lang} ? $lang : '*'} == 0) { $option->{resource}->{$lang} ||= SuikaWiki::Plugin::WikiConst::to_hash ($main::database{$option->{resource_ns}.$lang}); $v = $option->{resource}->{$lang}->{$resname}; last if defined $v; } $lang =~ s/[^+-]*$//; $lang =~ s/[+-]$//; } last if defined $v; } defined $v ? $v : $resname; } package wiki::conneg; ## BUG: this parser isn't strict. sub get_accept_lang (;$) { my $alang = shift || $main::ENV{HTTP_ACCEPT_LANGUAGE}; my %alang = (ja => 0.0002, en => 0.0001); if ($main::UA =~ m#Mozilla/0\.#) { $alang{ja} = 0.00001; } my $i = 0.1; for (split /\s*,\s*/, $alang) { tr/\x09\x0A\x0D\x20//d; if (/((?:(?!;q=).)+)(?:;q="?([0-9.]+)"?)?/) { my $l = lc $1; $l =~ tr/\x22\x5C//d; $alang{$l} = (defined $2 ? $2 : 1.000)*1000; $alang{$l} += $i unless $alang{$l} == 0; $i -= 0.001; } } \%alang; } POD:TO DO: - Refine wiki::* functions. - Separate conneg functions. - Persistent caching of retrived resource. POD:LICENSE: Copyright 2002-2003 Wakaba %%GNUGPL2%%