#?SuikaWikiConfig/2.0 Plugin: @Name: WikiResource @Description: @@@: Wiki resource text support @@lang:en @License: %%Perl%% @Author: @@Name: @@@@: Wakaba @@@lang:ja @@@script:Latn @@Mail[list]: w@suika.fam.cx @Date.RCS: $Date: 2004/03/11 10:12:39 $ @RequiredPlugin[list]: SuikaWikiConst09 @Use: use Message::Util::Error; my $RESOURCE_CACHE; our $NestLevel; PluginConst: @NS_XHTML1: http://www.w3.org/1999/xhtml FormattingRule: @Category[list]: view view-resource page-link link-to-resource form-input form-template @Name: res @Description: @@@: Resource @@lang: en @Parameter: @@Name: name @@Type: CDATA @@Default: #REQUIRED @@Description: @@@@: Resource name @@@lang:en @Formatting: __ATTRTEXT:%name__; __FUNCPACK__->get (name => $p->{name}, wiki => $o->{wiki}, formatter_context => 'view_resource', formatter_option => {param => $o, -parent => $p->{-parent}}); FormattingRule: @Category[list]: view view-resource page-link link-to-resource form-input form-template @Name: resource-as-plain-text @Description: @@@: Resource @@lang: en @Parameter: @@Name: name @@Type: CDATA @@Default: #REQUIRED @@Description: @@@@: Resource name @@@lang:en @Formatting: __ATTRTEXT:%name__; __FUNCPACK__->get (name => $p->{name}, wiki => $o->{wiki}); Function: @Name: logging_template_error @Description: @@@: Logging formatting-template-text error @@lang:en @Main: my (undef, $err, $wiki, %opt) = @_; my $error = {}; my $dl = $error->{description} = new Message::Markup::XML::Node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'dl'); ## TODO: Use resource $dl->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'dt') ->append_text ('Resource name'); $dl->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'dd') ->append_text ($opt{resource_name}); $dl->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'dt') ->append_text ('Error condition'); $dl->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'dd') ->append_text ($err->text); $dl->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'dt') ->append_text ('Formatting context'); $dl->append_new_node (type => '#element', namespace_uri => $NS_XHTML1, local_name => 'dd') ->append_text (qq($err->{-formatter}->{-category_name})); push @{$wiki->{var}->{error}||=[]}, $error; Function: @Name: get_text @Main: my (undef, %opt) = @_; __FUNCPACK__->get (%opt); ## TODO: Implements formatter. Function: @Name: append_node @Main: my (undef, %opt) = @_; __FUNCPACK__->get (%opt, formatter_context => 'view_resource', formatter_option => {param => $opt{param}, -parent => $opt{parent}}); Function: @Name: get_op @Description: @@@: Simple version of "get" @@lang: en @Main: my (undef, $name, $o, $parent, %opt) = @_; __FUNCPACK__->get (%opt, name => $name, o => $o, wiki => $o->{wiki}, formatter_context => 'view_resource', formatter_option => {param => $o, -parent => $parent}); Function: @Name: get @Main: my (undef, %opt) = @_; local $NestLevel = $NestLevel + 1; if (1000 < $NestLevel) { SuikaWiki::Plugin->module_package ('Error') ## TODO: ->report_error_simple ($opt{wiki} || $opt{o}->{wiki}, 'Condition' => 'Resource nesting too deep', ResourceName => $opt{name}, -trace => 1); return defined $opt{default} ? $opt{default} : $opt{name}; } my $text = __FUNCPACK__->temp_get_resource_text (resource_ns => $opt{wiki}->name ($opt{ns} || [qw/Wiki Resource/]), name => $opt{name}, wiki => $opt{wiki}); if (defined $text) { # } elsif (defined $opt{default}) { $text = $opt{default}; } else { $text = $opt{name}; } return $text unless $opt{formatter_context}; try { $text = SuikaWiki::Plugin->formatter ($opt{formatter_context}) ->replace ($text, %{$opt{formatter_option}}); } catch Message::Util::Formatter::error with { my $err = shift; if ($err->{-formatter}->{-category_name} eq $opt{formatter_context}) { __FUNCPACK__->logging_template_error ($err, $err->{-option}->{param}->{wiki}, resource_name => $opt{name}); undef; } else { $err->throw; } }; return $text; Function: @Name: temp_get_resource_text @Main: my (undef, %opt) = @_; CORE::die "Buggy implementation: \$opt{wiki} required ".Carp::longmess() unless ref $opt{wiki}; $opt{accept_language} ||= __FUNCPACK__->temp_get_accept_language (%opt); $opt{resource} ||= $RESOURCE_CACHE ||= {}; my $v; my $SWC09; try { $SWC09 = SuikaWiki::Plugin->module_package ('SuikaWikiConst09'); } catch SuikaWiki::Plugin::error with { my $err = shift; $err->raise unless $err->{-type} eq 'PLUGIN_NOT_FOUND'; }; for my $lang (sort {$opt{accept_language}->{$b} <=> $opt{accept_language}->{$a}} grep {$opt{accept_language}->{$_} != 0} keys %{$opt{accept_language}}) { while (length $lang) { unless ($opt{accept_language}->{defined $opt{accept_language}->{$lang} ? $lang : '*'} == 0) { ## WikiPage defined resource text (SuikaWikiConst/0.9) if (not $opt{resource}->{$lang} and ref $opt{wiki}->{db} and $SWC09) { try { $v = $opt{wiki}->{db}->get (content => [@{$opt{resource_ns}}, $lang]); } catch SuikaWiki::DB::Util::Error with { my $err = shift; $err->throw if $err->{-type} eq 'ERROR_REPORTED'; $v = undef; }; $opt{resource}->{$lang} = {}; $SWC09->text_to_hash (text => \$v, hash => $opt{resource}->{$lang}); } $v = $opt{resource}->{$lang}->{$opt{name}}; last if defined $v; ## WikiPlugin defined resource text (SuikaWiki 3 WikiPlugin) if (defined $SuikaWiki::Plugin::Resource::BaseResource->{$lang}->{''}->{$opt{name}}) { $v = $SuikaWiki::Plugin::Resource::BaseResource->{$lang}->{''}->{$opt{name}}; last; } } $lang =~ s/[^+-]*$//; $lang =~ s/[+-]$//; } last if defined $v; } # Accepted languages if (defined $v) { return $v; } else { ## Plugin defined resource text or undef return $SuikaWiki::Plugin::Resource::BaseResource->{und}->{''}->{$opt{name}}; } Function: @Name: temp_get_language_resource_from_array @Main: my (undef, %opt) = @_; CORE::die "Buggy implementation: \$opt{o} required ".Carp::longmess() unless ref $opt{o}; $opt{source} ||= []; if (@{$opt{source}} < 2) { return ($opt{source} || [])->[0]; } $opt{accept_language} ||= __FUNCPACK__->temp_get_accept_language (wiki => $opt{o}->{wiki}, %opt); my $und; for my $lang (sort {$opt{accept_language}->{$b} <=> $opt{accept_language}->{$a}} grep {$opt{accept_language}->{$_} != 0} keys %{$opt{accept_language}}) { while (length $lang) { unless ($opt{accept_language}->{defined $opt{accept_language}->{$lang} ? $lang : '*'} == 0) { for (@{$opt{source}}) { if ($_->[1] eq $lang) { return $_; ## TODO: Script support } elsif ($_->[1] eq 'und') { $und = $_; } } } $lang =~ s/[^+-]*$//; $lang =~ s/[+-]$//; } } # Accepted languages return $und || []; Function: @Name: temp_get_accept_language @Main: my (undef, %opt) = @_; ## Accept language specification my $alang; if ($opt{wiki}->{input}) { $alang = $opt{wiki}->{input}->meta_variable ('HTTP_ACCEPT_LANGUAGE'); } $alang ||= q; ## Old user agent support my %alang = (ja => 0.0002, en => 0.0001); if ($opt{wiki}->{var}->{client}->{user_agent_name} =~ m#^Mozilla/0\.#) { $alang{ja} = 0.00001; } ## Parse accept language specification 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; } } return \%alang;