--- trunk/lib/WebPAC/Output/TT.pm 2005/07/17 22:28:11 21 +++ trunk/lib/WebPAC/Output/TT.pm 2005/12/01 13:58:04 201 @@ -6,7 +6,9 @@ use base qw/WebPAC::Common/; use Template; +use List::Util qw/first/; use Data::Dumper; +use URI::Escape qw/uri_escape_utf8/; =head1 NAME @@ -14,11 +16,11 @@ =head1 VERSION -Version 0.01 +Version 0.03 =cut -our $VERSION = '0.01'; +our $VERSION = '0.03'; =head1 SYNOPSIS @@ -69,9 +71,11 @@ my $text = $tt->apply( template => 'text.tt', - data => @ds + data => $ds ); +It also has follwing template toolikit filter routies defined: + =cut sub apply { @@ -85,6 +89,140 @@ $log->logconfess("need $a") unless ($args->{$a}); } +=head3 tt_filter_type + +filter to return values of specified from $ds, usage from TT template is in form +C, where C is optional, like this: + + [% d('Title') %] + [% d('Author',', ' %] + +=cut + + sub tt_filter_type { + my ($data,$type) = @_; + + die "no data?" unless ($data); + $type ||= 'display'; + + my $default_delimiter = { + 'display' => '¶
', + 'index' => '\n', + }; + + return sub { + + my ($name,$join) = @_; + + die "no data hash" unless ($data->{'data'} && ref($data->{'data'}) eq 'HASH'); + # Hm? Should we die here? + return unless ($name); + + my $item = $data->{'data'}->{$name} || return; + + my $v = $item->{$type} || return; + + if (ref($v) eq 'ARRAY') { + if ($#{$v} == 0) { + $v = $v->[0]; + } else { + $join = $default_delimiter->{$type} unless defined($join); + $v = join($join, @{$v}); + } + } else { + warn("TT filter $type(): field $name values aren't ARRAY, ignoring"); + } + + return $v; + } + } + + $args->{'d'} = tt_filter_type($args, 'display'); + $args->{'display'} = tt_filter_type($args, 'display'); + +=head3 tt_filter_search + +filter to return links to search, usage in TT: + + [% search('FieldToDisplay','FieldToSearch','optional delimiter') %] + +=cut + + sub tt_filter_search { + + my ($data) = @_; + + die "no data?" unless ($data); + + return sub { + + my ($display,$search,$delimiter) = @_; + + # default delimiter + $delimiter ||= '¶
', + + die "no data hash" unless ($data->{'data'} && ref($data->{'data'}) eq 'HASH'); + # Hm? Should we die here? + return unless ($display); + + my $item = $data->{'data'}->{$display} || return; + + return unless($item->{'display'}); + die "error in TT template: field $display didn't insert anything into search, use d('$display') and not search('$display'...)" unless($item->{'search'}); + + my @warn; + foreach my $type (qw/display search/) { + push @warn, "field $display type $type values aren't ARRAY" unless (ref($item->{$type}) eq 'ARRAY'); + } + + if (@warn) { + warn("TT filter search(): " . join(",", @warn) . ", skipping"); + return; + } + my @html; + + my $d_el = $#{ $item->{'display'} }; + my $s_el = $#{ $item->{'search'} }; + + # easy, both fields have same number of elements or there is just + # one search and multiple display + if ( $d_el == $s_el || $s_el == 0 ) { + + foreach my $i ( 0 .. $d_el ) { + + my $s; + if ($s_el > 0) { + $s = $item->{'search'}->[$i] || die "can't find value $i for type search in field $search"; + } else { + $s = $item->{'search'}->[0]; + } + #$s =~ s/([^\w.-])/sprintf("%%%02X",ord($1))/eg; + $s = uri_escape_utf8( $s ); + + my $d = $item->{'display'}->[$i] || die "can't find value $i for type display in field $display"; + + push @html, <<__JS_LINK_SEARCH__ +$d +__JS_LINK_SEARCH__ + } + + return join($delimiter, @html); + } else { + my $html = qq{
WARNING: we should really support if there is $d_el display elements and $s_el search elements, but currently there is no nice way to do so, so we will just display values
}; + my $v = $item->{'display'}; + + if ($#{$v} == 0) { + $html .= $v->[0]; + } else { + $html .= join($delimiter, @{$v}); + } + return $html; + } + } + } + + $args->{'search'} = tt_filter_search($args); + my $out; $self->{'tt'}->process( @@ -104,7 +242,7 @@ $tt->to_file( file => 'out.txt', template => 'text.tt', - data => @ds + data => $ds ); =cut