First test of creating a wrapper for Template Toolkit that handles l() and other...
authorPasi Kallinen <pasi.kallinen@pttk.fi>
Thu, 11 Jul 2013 14:20:18 +0000 (17:20 +0300)
committerPasi Kallinen <pasi.kallinen@pttk.fi>
Wed, 14 Aug 2013 17:55:55 +0000 (20:55 +0300)
TODO: remember to rm EGWeb/EGI18N.pm and EGWeb/CGI_utf8.pm

Signed-off-by: Pasi Kallinen <pasi.kallinen@pttk.fi>
Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar/CGI_utf8.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar/I18NFilter.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
Open-ILS/src/sql/Pg/950.data.seed-values.sql

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar.pm
new file mode 100644 (file)
index 0000000..ac608a4
--- /dev/null
@@ -0,0 +1,162 @@
+package OpenILS::Utils::Templar;
+
+use strict; use warnings;
+use diagnostics;
+
+use Encode;
+use Template;
+
+use OpenSRF::Utils::Logger qw(:logger);
+use OpenILS::Utils::CStoreEditor q/:funcs/;
+
+
+use Data::Dumper;
+
+# cache string bundles
+my %registered_locales;
+
+sub set_text_handler {
+    my $locale = shift;
+    return sub {
+       my $lh = OpenILS::Utils::Templar::I18N->get_handle($locale);
+       return $lh->maketext(@_) if ($lh);
+       return '['.join(',', @_).']';
+    };
+}
+
+sub get_registered_locales { my $self=shift; return \%registered_locales; }
+
+sub process {
+    my $self = shift;
+    my $parm = shift || {};
+    my $ttc = shift || {};
+    my $ttparams = shift || {}; # params for TT
+
+    my $template = $parm->{template} || '';
+
+    my $output = $parm->{output} || undef;
+
+    my $locale = $parm->{locale} || 'en_us';
+    my $text_handler = set_text_handler($locale);
+
+    $ttc->{encode_utf8} = sub {return encode_utf8(shift())};
+    $ttc->{ctx}->{encode_utf8} =  sub {return encode_utf8(shift())} if (!exists($ttc->{ctx}->{encode_utf8}));
+    $ttc->{ENV} = \%ENV;
+
+    if (!exists($ttparams->{FILTERS}->{l}) && !exists($ttc->{l})) {
+       $ttc->{l} = $text_handler;
+       $ttparams->{FILTERS}->{l} = [
+           sub {
+               my ($ttc, @args) = @_;
+               return sub { $text_handler->(shift(), @args); }
+           }, 1
+           ];
+    }
+
+    $ttparams->{PLUGINS}->{CGI_utf8} = 'OpenILS::Utils::Templar::CGI_utf8' if (!exists($ttparams->{PLUGINS}->{CGI_utf8}));
+
+    my $tt = Template->new($ttparams);
+
+    if (!$tt) {
+       #warn "Templar: Error creating template processor: $@";
+       return 1;
+    }
+    if (!$tt->process($template, $ttc, $output)) {
+       my $error;
+        ($error = $tt->error()) =~ s/\n/ /og;
+        $logger->error("Error processing template: $error");
+       #print "<pre>Templar: Error processing: " . $tt->error() . "\n";
+       #print Dumper($template)."\n";
+       #print Dumper($ttc)."\n";
+       return 2;
+    }
+    return 0;
+}
+
+
+
+# Create an I18N sub-module for each supported locale
+# Each module creates its own MakeText lexicon by parsing .po/.mo files
+sub load_locale_handlers {
+    my $self = shift;
+    my %locales = @_;
+
+    #print 'load_locale_handlers:locales='.Dumper(%locales)."<br>";
+
+    my $editor = new_editor();
+    my @locale_tags = sort { length($a) <=> length($b) } keys %locales;
+
+    # always fall back to en_us, the assumed template language
+    push(@locale_tags, 'en_us');
+
+    for my $idx (0..$#locale_tags) {
+
+        my $tag = $locale_tags[$idx];
+        next if grep { $_ eq $tag } keys %registered_locales;
+
+        my $res = $editor->json_query({
+            "from" => [
+                "evergreen.get_locale_name",
+                $tag
+            ]
+        });
+
+        my $locale_name = $res->[0]->{"name"} if exists $res->[0]->{"name"};
+        next unless $locale_name;
+
+       #print "locale_name=$locale_name, $tag<br>";
+
+        my $parent_tag = '';
+        my $sub_idx = $idx;
+
+        # find the parent locale if possible.  It will be 
+        # longest left-anchored substring of the current tag
+        while( --$sub_idx >= 0 ) {
+            my $ptag = $locale_tags[$sub_idx];
+            if( substr($tag, 0, length($ptag)) eq $ptag ) {
+                $parent_tag = "::$ptag";
+                last;
+            }
+        }
+
+        my $messages = $locales{$tag} || '';
+
+       #print "load_locale_handlers: $tag, $parent_tag, $locale_name, $messages<br>";
+
+        # TODO Can we do this without eval?
+        my $eval = <<"        EVAL";
+            package OpenILS::Utils::Templar::I18N::$tag;
+            use base 'OpenILS::Utils::Templar::I18N$parent_tag';
+            if(\$messages) {
+                use Locale::Maketext::Lexicon {
+                    _decode => 1
+                };
+                use Locale::Maketext::Lexicon::Gettext;
+                if(open F, '$messages') {
+                    our %Lexicon = (%Lexicon, %{ Locale::Maketext::Lexicon::Gettext->parse(<F>) });
+                    close F;
+                } else {
+                   #print "EGWeb: unable to open messages file: $messages<br>";
+                    warn "EGWeb: unable to open messages file: $messages"; 
+                }
+            }
+        EVAL
+        eval $eval;
+
+        if ($@) {
+            warn "$@\n" if $@;
+        } else {
+            $registered_locales{"$tag"} = $locale_name;
+        }
+    }
+    return 0;
+}
+
+
+
+# base class for all supported locales
+package OpenILS::Utils::Templar::I18N;
+use base 'Locale::Maketext';
+our %Lexicon = (_AUTO => 1);
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar/CGI_utf8.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar/CGI_utf8.pm
new file mode 100644 (file)
index 0000000..3dfc6c1
--- /dev/null
@@ -0,0 +1,44 @@
+package OpenILS::Utils::Templar::CGI_utf8;
+
+# The code in this module is copied from (except for a tiny modification)
+# Template::Plugin::CGI, which is written by:
+#
+# Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
+#
+# Copyright (C) 1996-2007 Andy Wardley.  All Rights Reserved.
+#
+# This module is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+
+use strict;
+use warnings;
+use base 'Template::Plugin';
+use CGI qw(:all -utf8);
+
+sub new {
+    my $class   = shift;
+    my $context = shift;
+    new CGI(@_);
+}
+
+# monkeypatch CGI::params() method to Do The Right Thing in TT land
+
+sub CGI::params {
+    my $self = shift;
+    local $" = ', ';
+
+    return $self->{ _TT_PARAMS } ||= do {
+        # must call Vars() in a list context to receive
+        # plain list of key/vals rather than a tied hash
+        my $params = { $self->Vars() };
+
+        # convert any null separated values into lists
+        @$params{ keys %$params } = map { 
+            /\0/ ? [ split /\0/ ] : $_ 
+        } values %$params;
+
+        $params;
+    };
+}
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar/I18NFilter.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/Templar/I18NFilter.pm
new file mode 100644 (file)
index 0000000..d9f86a0
--- /dev/null
@@ -0,0 +1,12 @@
+package OpenILS::Utils::Templar::I18NFilter;
+use Template::Plugin::Filter;
+use base qw(Template::Plugin::Filter);
+our $DYNAMIC = 1;
+
+sub filter {
+    my ($self, $text, $args) = @_;
+    return $maketext->($text, @$args);
+}
+
+1;
+
index e5d5bb2..de9031f 100644 (file)
@@ -1,5 +1,6 @@
 package OpenILS::WWW::EGWeb;
 use strict; use warnings;
+use diagnostics;
 use Template;
 use XML::Simple;
 use XML::LibXML;
@@ -11,12 +12,16 @@ use OpenSRF::EX qw(:try);
 use OpenILS::Utils::CStoreEditor q/:funcs/;
 use List::MoreUtils qw/uniq/;
 
+use OpenILS::Utils::Templar;
+
+use Data::Dumper;
+
 use constant OILS_HTTP_COOKIE_SKIN => 'eg_skin';
 use constant OILS_HTTP_COOKIE_THEME => 'eg_theme';
 use constant OILS_HTTP_COOKIE_LOCALE => 'eg_locale';
 
 # cache string bundles
-my %registered_locales;
+#my %registered_locales;
 
 sub handler {
     my $r = shift;
@@ -31,56 +36,118 @@ sub handler {
     return $stat unless $stat == Apache2::Const::OK;
     return Apache2::Const::DECLINED unless $template;
 
-    my $text_handler = set_text_handler($ctx, $r);
+#    my $text_handler = set_text_handler($ctx, $r);
 
-    my $tt = Template->new({
+    my %ttparams = (
         ENCODING => 'utf-8',
         OUTPUT => ($as_xml) ?  sub { parse_as_xml($r, $ctx, @_); } : $r,
         INCLUDE_PATH => $ctx->{template_paths},
-        DEBUG => $ctx->{debug_template},
-        PLUGINS => {
-            EGI18N => 'OpenILS::WWW::EGWeb::I18NFilter',
-            CGI_utf8 => 'OpenILS::WWW::EGWeb::CGI_utf8'
-        },
-        FILTERS => {
-            # Register a dynamic filter factory for our locale::maketext generator
-            l => [
-                sub {
-                    my($ctx, @args) = @_;
-                    return sub { $text_handler->(shift(), @args); }
-                }, 1
-            ]
-        }
-    });
+        DEBUG => $ctx->{debug_template}
+       );
 
-    if (!$tt) {
-        $r->log->error("Error creating template processor: $@");
-        return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
-    }   
+    my $TR = 'OpenILS::Utils::Templar';
 
-    $ctx->{encode_utf8} = sub {return encode_utf8(shift())};
+    if ($TR->load_locale_handlers(%{$ctx->{oils_locales}})) {
+       #print "error at load_locale_handlers\n";
+    } else {
+       my $cgi = CGI->new;
+       # Set a locale cookie if the requested locale is valid
+       my $set_locale = $cgi->param('set_eg_locale') || '';
 
-    unless($tt->process($template, {ctx => $ctx, ENV => \%ENV, l => $text_handler})) {
-        $r->log->warn('egweb: template error: ' . $tt->error);
-        return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
+       $ctx->{locales} = $TR->get_registered_locales();
+       #print "locales: ".Dumper($ctx->{locales})."<br>";
+
+       #print "set_locale = $set_locale<br>";
+
+       #print "locales keys: ".Dumper(keys $ctx->{locales})."<br>";
+
+       if (!(grep {$_ eq $set_locale} keys $ctx->{locales})) {
+           $set_locale = '';
+       } else {
+           my $slc = $cgi->cookie({
+               '-name' => OILS_HTTP_COOKIE_LOCALE,
+               '-value' => $set_locale,
+               '-expires' => '+10y'
+                                  });
+           $r->headers_out->add('Set-Cookie' => $slc);
+       }
+
+       $ctx->{locale} = $set_locale ||
+           $cgi->cookie(OILS_HTTP_COOKIE_LOCALE) || $ctx->{oils_default_locale} ||
+           parse_accept_lang($r->headers_in->get('Accept-Language'));
+
+       #print "set_locale = $set_locale<br>";
+
+       #print "ctx.locale=".Dumper($ctx->{locale})."<br>";
+
+       # set the editor default locale for each page load
+       $OpenILS::Utils::CStoreEditor::default_locale = parse_eg_locale($ctx->{locale});
+
+       my %parm = (
+           template => $template,
+           locale => $ctx->{locale}
+       );
+
+       my %ttc = (
+           ctx => $ctx    
+           );
+       my $xx = $TR->process(\%parm, \%ttc, \%ttparams);
+       #print "XX = $xx<br>";
     }
 
+
+    #return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR if ($xx);
+
+    # my $tt = Template->new({
+    #     ENCODING => 'utf-8',
+    #     OUTPUT => ($as_xml) ?  sub { parse_as_xml($r, $ctx, @_); } : $r,
+    #     INCLUDE_PATH => $ctx->{template_paths},
+    #     DEBUG => $ctx->{debug_template},
+    #     PLUGINS => {
+    #         EGI18N => 'OpenILS::WWW::EGWeb::I18NFilter',
+    #         CGI_utf8 => 'OpenILS::WWW::EGWeb::CGI_utf8'
+    #     },
+    #     FILTERS => {
+    #         # Register a dynamic filter factory for our locale::maketext generator
+    #         l => [
+    #             sub {
+    #                 my($ctx, @args) = @_;
+    #                 return sub { $text_handler->(shift(), @args); }
+    #             }, 1
+    #         ]
+    #     }
+    # });
+
+    # if (!$tt) {
+    #     $r->log->error("Error creating template processor: $@");
+    #     return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
+    # }   
+
+    # $ctx->{encode_utf8} = sub {return encode_utf8(shift())};
+
+    # unless($tt->process($template, {ctx => $ctx, ENV => \%ENV, l => $text_handler})) {
+    #     $r->log->warn('egweb: template error: ' . $tt->error);
+    #     return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
+    # }
+
     return Apache2::Const::OK;
 }
 
-sub set_text_handler {
-    my $ctx = shift;
-    my $r = shift;
 
-    my $locale = $ctx->{locale};
 
-    $r->log->debug("egweb: messages locale = $locale");
+# sub set_text_handler {
+#     my $ctx = shift;
+#     my $r = shift;
 
-    return sub {
-        my $lh = OpenILS::WWW::EGWeb::I18N->get_handle($locale);
-        return $lh->maketext(@_);
-    };
-}
+#     my $locale = $ctx->{locale};
+
+#     $r->log->debug("egweb: messages locale = $locale");
+
+#     return sub {
+#         my $lh = OpenILS::WWW::EGWeb::I18N->get_handle($locale);
+#         return $lh->maketext(@_);
+#     };
+# }
 
 
 
@@ -151,29 +218,12 @@ sub load_context {
     $ctx->{template_paths} = [ reverse @template_paths ];
 
     my %locales = $r->dir_config->get('OILSWebLocale');
-    load_locale_handlers($ctx, %locales);
+    #load_locale_handlers($ctx, %locales);
 
-    $ctx->{locales} = \%registered_locales;
+    $ctx->{oils_locales} = \%locales;
+    $ctx->{oils_default_locale} = $default_locale;
 
-    # Set a locale cookie if the requested locale is valid
-    my $set_locale = $cgi->param('set_eg_locale') || '';
-    if (!(grep {$_ eq $set_locale} keys %registered_locales)) {
-        $set_locale = '';
-    } else {
-        my $slc = $cgi->cookie({
-            '-name' => OILS_HTTP_COOKIE_LOCALE,
-            '-value' => $set_locale,
-            '-expires' => '+10y'
-        });
-        $r->headers_out->add('Set-Cookie' => $slc);
-    }
-
-    $ctx->{locale} = $set_locale ||
-        $cgi->cookie(OILS_HTTP_COOKIE_LOCALE) || $default_locale ||
-        parse_accept_lang($r->headers_in->get('Accept-Language'));
-
-    # set the editor default locale for each page load
-    $OpenILS::Utils::CStoreEditor::default_locale = parse_eg_locale($ctx->{locale});
+    #print "oils_locales: ".Dumper(%locales)."<br>";
 
     my $mprefix = $ctx->{media_prefix};
     if($mprefix and $mprefix !~ /^http/ and $mprefix !~ /^\//) {
@@ -261,77 +311,79 @@ sub find_template {
 
 # Create an I18N sub-module for each supported locale
 # Each module creates its own MakeText lexicon by parsing .po/.mo files
-sub load_locale_handlers {
-    my $ctx = shift;
-    my %locales = @_;
-
-    my $editor = new_editor();
-    my @locale_tags = sort { length($a) <=> length($b) } keys %locales;
-
-    # always fall back to en_us, the assumed template language
-    push(@locale_tags, 'en_us');
-
-    for my $idx (0..$#locale_tags) {
-
-        my $tag = $locale_tags[$idx];
-        next if grep { $_ eq $tag } keys %registered_locales;
-
-        my $res = $editor->json_query({
-            "from" => [
-                "evergreen.get_locale_name",
-                $tag
-            ]
-        });
-
-        my $locale_name = $res->[0]->{"name"} if exists $res->[0]->{"name"};
-        next unless $locale_name;
-
-        my $parent_tag = '';
-        my $sub_idx = $idx;
-
-        # find the parent locale if possible.  It will be 
-        # longest left-anchored substring of the current tag
-        while( --$sub_idx >= 0 ) {
-            my $ptag = $locale_tags[$sub_idx];
-            if( substr($tag, 0, length($ptag)) eq $ptag ) {
-                $parent_tag = "::$ptag";
-                last;
-            }
-        }
-
-        my $messages = $locales{$tag} || '';
-
-        # TODO Can we do this without eval?
-        my $eval = <<"        EVAL";
-            package OpenILS::WWW::EGWeb::I18N::$tag;
-            use base 'OpenILS::WWW::EGWeb::I18N$parent_tag';
-            if(\$messages) {
-                use Locale::Maketext::Lexicon {
-                    _decode => 1
-                };
-                use Locale::Maketext::Lexicon::Gettext;
-                if(open F, '$messages') {
-                    our %Lexicon = (%Lexicon, %{ Locale::Maketext::Lexicon::Gettext->parse(<F>) });
-                    close F;
-                } else {
-                    warn "EGWeb: unable to open messages file: $messages"; 
-                }
-            }
-        EVAL
-        eval $eval;
-
-        if ($@) {
-            warn "$@\n" if $@;
-        } else {
-            $registered_locales{"$tag"} = $locale_name;
-        }
-    }
-}
+# sub load_locale_handlers {
+#     my $ctx = shift;
+#     my %locales = @_;
+
+#     my $editor = new_editor();
+#     my @locale_tags = sort { length($a) <=> length($b) } keys %locales;
+
+#     # always fall back to en_us, the assumed template language
+#     push(@locale_tags, 'en_us');
+
+#     for my $idx (0..$#locale_tags) {
+
+#         my $tag = $locale_tags[$idx];
+#         next if grep { $_ eq $tag } keys %registered_locales;
+
+#         my $res = $editor->json_query({
+#             "from" => [
+#                 "evergreen.get_locale_name",
+#                 $tag
+#             ]
+#         });
+
+#         my $locale_name = $res->[0]->{"name"} if exists $res->[0]->{"name"};
+#         next unless $locale_name;
+
+#      warn "locale_name=$locale_name, $tag\n";
+
+#         my $parent_tag = '';
+#         my $sub_idx = $idx;
+
+#         # find the parent locale if possible.  It will be 
+#         # longest left-anchored substring of the current tag
+#         while( --$sub_idx >= 0 ) {
+#             my $ptag = $locale_tags[$sub_idx];
+#             if( substr($tag, 0, length($ptag)) eq $ptag ) {
+#                 $parent_tag = "::$ptag";
+#                 last;
+#             }
+#         }
+
+#         my $messages = $locales{$tag} || '';
+
+#         # TODO Can we do this without eval?
+#         my $eval = <<"        EVAL";
+#             package OpenILS::WWW::EGWeb::I18N::$tag;
+#             use base 'OpenILS::WWW::EGWeb::I18N$parent_tag';
+#             if(\$messages) {
+#                 use Locale::Maketext::Lexicon {
+#                     _decode => 1
+#                 };
+#                 use Locale::Maketext::Lexicon::Gettext;
+#                 if(open F, '$messages') {
+#                     our %Lexicon = (%Lexicon, %{ Locale::Maketext::Lexicon::Gettext->parse(<F>) });
+#                     close F;
+#                 } else {
+#                     warn "EGWeb: unable to open messages file: $messages"; 
+#                 }
+#             }
+#         EVAL
+#         eval $eval;
+
+#         if ($@) {
+#             warn "$@\n" if $@;
+#         } else {
+#             $registered_locales{"$tag"} = $locale_name;
+#         }
+#     }
+# }
 
 
 # base class for all supported locales
-package OpenILS::WWW::EGWeb::I18N;
-use base 'Locale::Maketext';
-our %Lexicon = (_AUTO => 1);
+#package OpenILS::WWW::EGWeb::I18N;
+#use base 'Locale::Maketext';
+#our %Lexicon = (_AUTO => 1);
 
 1;
index 433fbfd..bc1145e 100644 (file)
@@ -8785,11 +8785,11 @@ $$
     [% END %]
     [% FOR xact_id IN xact_mp_hash.keys.sort %]
         [% SET xact = xact_mp_hash.$xact_id.xact %]
-        <li>Transaction ID: [% xact_id %]
+        <li>[% l('Transaction ID: [_1]', xact_id) %]
             [% IF xact.circulation %][% helpers.get_copy_bib_basics(xact.circulation.target_copy).title %]
-            [% ELSE %]Miscellaneous
+            [% ELSE %][% l('Miscellaneous') %]
             [% END %]
-            Line item billings:<ol>
+            [% l('Line item billings:') %]<ol>
                 [% SET mb_type_hash = {} %]
                 [% FOR mb IN xact.billings %][%# Group billings by their btype %]
                     [% IF mb.voided == 'f' %]
@@ -8803,18 +8803,20 @@ $$
                 [% END %]
                 [% FOR mb_type IN mb_type_hash.keys.sort %]
                     <li>[% IF mb_type == 1 %][%# Consolidated view of overdue billings %]
-                        $[% mb_type_hash.$mb_type.sum %] for [% mb_type_hash.$mb_type.billings.0.btype.name %] 
-                            on [% mb_type_hash.$mb_type.first_ts %] through [% mb_type_hash.$mb_type.last_ts %]
+                   [% l('$[_1] for [_2] on [_3] through [_4]',
+                          mb_type_hash.$mb_type.sum, mb_type_hash.$mb_type.billings.0.btype.name,
+                          mb_type_hash.$mb_type.first_ts, mb_type_hash.$mb_type.last_ts) %]
                     [% ELSE %][%# all other billings show individually %]
                         [% FOR mb IN mb_type_hash.$mb_type.billings %]
-                            $[% mb.amount %] for [% mb.btype.name %] on [% mb.billing_ts %] [% mb.note %]
+                       [% l('$[_1] for [_2] on [_3] [_4]',
+                            mb.amount, mb.btype.name, mb.billing_ts, mb.note) %]
                         [% END %]
                     [% END %]</li>
                 [% END %]
             </ol>
-            Line item payments:<ol>
+            [% l('Line item payments:') %]<ol>
                 [% FOR mp IN xact_mp_hash.$xact_id.payments %]
-                    <li>Payment ID: [% mp.id %]
+                    <li>[% l('Payment ID: [_1]', mp.id) %]
                         Paid [% mp.amount %] via [% SWITCH mp.payment_type -%]
                             [% CASE "cash_payment" %]cash
                             [% CASE "check_payment" %]check