Merge remote branch 'kc/master' into new/enh/bug_5917
authorChris Cormack <chrisc@catalyst.net.nz>
Mon, 21 Mar 2011 06:54:11 +0000 (19:54 +1300)
committerChris Cormack <chrisc@catalyst.net.nz>
Mon, 21 Mar 2011 06:54:11 +0000 (19:54 +1300)
Conflicts:
installer/data/mysql/en/mandatory/sysprefs.sql

C4/Auth.pm
C4/Output.pm
C4/Templates.pm [new file with mode: 0644]
admin/preferences.pl
installer/data/mysql/fr-FR/1-Obligatoire/unimarc_standard_systemprefs.sql
installer/data/mysql/pl-PL/mandatory/sysprefs.sql
installer/data/mysql/ru-RU/mandatory/system_preferences_full_optimal_for_install_only.sql
installer/html-template-to-template-toolkit.pl [new file with mode: 0755]
koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc

index 06806ff..482ca16 100644 (file)
@@ -387,6 +387,15 @@ sub get_template_and_user {
         } elsif($mylibraryfirst){
             $opac_name = C4::Branch::GetBranchName($mylibraryfirst);
         }
+       my $checkstyle = C4::Context->preference("opaccolorstylesheet");
+       if ($checkstyle =~ /http/)
+       {
+               $template->param( opacexternalsheet => $checkstyle);
+       } else
+       {
+               my $opaccolorstylesheet = C4::Context->preference("opaccolorstylesheet");  
+            $template->param( opaccolorstylesheet => $opaccolorstylesheet);
+       }
         $template->param(
             AmazonContent             => "" . C4::Context->preference("AmazonContent"),
             AnonSuggestions           => "" . C4::Context->preference("AnonSuggestions"),
@@ -426,7 +435,6 @@ sub get_template_and_user {
             hidelostitems             => C4::Context->preference("hidelostitems"),
             mylibraryfirst            => (C4::Context->preference("SearchMyLibraryFirst") && C4::Context->userenv) ? C4::Context->userenv->{'branch'} : '',
             opaclayoutstylesheet      => "" . C4::Context->preference("opaclayoutstylesheet"),
-            opaccolorstylesheet       => "" . C4::Context->preference("opaccolorstylesheet"),
             opacstylesheet            => "" . C4::Context->preference("opacstylesheet"),
             opacbookbag               => "" . C4::Context->preference("opacbookbag"),
             opaccredits               => "" . C4::Context->preference("opaccredits"),
@@ -912,6 +920,15 @@ sub checkauth {
     my $template_name = ( $type eq 'opac' ) ? 'opac-auth.tmpl' : 'auth.tmpl';
     my $template = gettemplate( $template_name, $type, $query );
     $template->param(branchloop => \@branch_loop,);
+    my $checkstyle = C4::Context->preference("opaccolorstylesheet");
+    if ($checkstyle =~ /\//)
+       {
+               $template->param( opacexternalsheet => $checkstyle);
+       } else
+       {
+               my $opaccolorstylesheet = C4::Context->preference("opaccolorstylesheet");  
+            $template->param( opaccolorstylesheet => $opaccolorstylesheet);
+       }
     $template->param(
     login        => 1,
         INPUTS               => \@inputs,
@@ -925,7 +942,6 @@ sub checkauth {
         opacreadinghistory   => C4::Context->preference("opacreadinghistory"),
         opacsmallimage       => C4::Context->preference("opacsmallimage"),
         opaclayoutstylesheet => C4::Context->preference("opaclayoutstylesheet"),
-        opaccolorstylesheet  => C4::Context->preference("opaccolorstylesheet"),
         opaclanguagesdisplay => C4::Context->preference("opaclanguagesdisplay"),
         opacuserjs           => C4::Context->preference("opacuserjs"),
         opacbookbag          => "" . C4::Context->preference("opacbookbag"),
index 9f5ed5e..abd8fc3 100644 (file)
@@ -32,8 +32,9 @@ use C4::Context;
 use C4::Languages qw(getTranslatedLanguages get_bidi regex_lang_subtags language_get_description accept_language );
 use C4::Dates qw(format_date);
 use C4::Budgets qw(GetCurrency);
+use C4::Templates;
 
-use HTML::Template::Pro;
+#use HTML::Template::Pro;
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
 
 BEGIN {
@@ -95,14 +96,16 @@ sub gettemplate {
     my $opacstylesheet = C4::Context->preference('opacstylesheet');
     my ( $htdocs, $theme, $lang, $filename ) = _get_template_file( $tmplbase, $interface, $query );
 
-    my $template       = HTML::Template::Pro->new(
-        filename          => $filename,
-        die_on_bad_params => 1,
-        global_vars       => 1,
-        case_sensitive    => 1,
-        loop_context_vars => 1, # enable: __first__, __last__, __inner__, __odd__, __counter__ 
-        path              => ["$htdocs/$theme/$lang/$path"]
-    );
+#    my $template       = HTML::Template::Pro->new(
+#        filename          => $filename,
+#        die_on_bad_params => 1,
+#        global_vars       => 1,
+#        case_sensitive    => 1,
+#        loop_context_vars => 1, # enable: __first__, __last__, __inner__, __odd__, __counter__ 
+#        path              => ["$htdocs/$theme/$lang/$path"]
+#    );
+    $filename =~ s/\.tmpl$/.tt/;
+    my $template = C4::Templates->new( $interface, $filename);
     my $themelang=( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' )
           . "/$theme/$lang";
     $template->param(
@@ -469,6 +472,8 @@ sub output_with_http_headers($$$$;$) {
     # remove SUDOC specific NSB NSE
     $data =~ s/\x{C2}\x{98}|\x{C2}\x{9C}/ /g;
     $data =~ s/\x{C2}\x{88}|\x{C2}\x{89}/ /g;
+    utf8::encode($data) if utf8::is_utf8($data);
+
     print $query->header($options), $data;
 }
 
diff --git a/C4/Templates.pm b/C4/Templates.pm
new file mode 100644 (file)
index 0000000..91b57fb
--- /dev/null
@@ -0,0 +1,118 @@
+package C4::Templates;
+
+use strict;
+use warnings;
+use Carp;
+
+# Copyright 2009 Chris Cormack and The Koha Dev Team
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+# Suite 330, Boston, MA  02111-1307 USA
+
+=head1 NAME 
+
+    Koha::Templates - Object for manipulating templates for use with Koha
+
+=cut
+
+use base qw(Class::Accessor);
+use Template;
+use Template::Constants qw( :debug );
+
+use C4::Context;
+
+__PACKAGE__->mk_accessors(qw( theme lang filename htdocs interface vars));
+
+sub new {
+    my $class     = shift;
+    my $interface = shift;
+    my $filename  = shift;
+    my $htdocs;
+    if ( $interface ne "intranet" ) {
+        $htdocs = C4::Context->config('opachtdocs');
+    }
+    else {
+        $htdocs = C4::Context->config('intrahtdocs');
+    }
+
+#    my ( $theme, $lang ) = themelanguage( $htdocs, $tmplbase, $interface, $query );
+    my $theme = 'prog';
+    my $lang = 'en';
+    my $template = Template->new(
+        {
+            EVAL_PERL    => 1,
+            ABSOLUTE     => 1,
+            INCLUDE_PATH => "$htdocs/$theme/$lang/includes",
+            FILTERS      => {},
+
+        }
+    ) or die Template->error();
+    my $self = {
+        TEMPLATE => $template,
+       VARS => {},
+    };
+    bless $self, $class;
+    $self->theme($theme);
+    $self->lang($lang);
+    $self->filename($filename);
+    $self->htdocs($htdocs);
+    $self->interface($interface);
+    $self->{VARS}->{"test"} = "value";
+    return $self;
+
+}
+
+sub output {
+    my $self = shift;
+    my $vars = shift;
+#    my $file = $self->htdocs . '/' . $self->theme .'/'.$self->lang.'/'.$self->filename;
+    my $template = $self->{TEMPLATE};
+    if ($self->interface eq 'intranet'){
+       $vars->{themelang} = '/intranet-tmpl';
+    }
+    else {
+       $vars->{themelang} = '/opac-tmpl';
+    }
+    $vars->{lang} = $self->lang;
+    $vars->{themelang}          .= '/' . $self->theme . '/' . $self->lang;
+    $vars->{yuipath}             = (C4::Context->preference("yuipath") eq "local"?$self->{themelang}."/lib/yui":C4::Context->preference("yuipath"));
+    $vars->{interface}           = ( $vars->{interface} ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' );
+    $vars->{theme}               = $self->theme;
+    $vars->{opaccolorstylesheet} = C4::Context->preference('opaccolorstylesheet');
+    $vars->{opacsmallimage}      = C4::Context->preference('opacsmallimage');
+    $vars->{opacstylesheet}      = C4::Context->preference('opacstylesheet');
+    #add variables set via param to $vars for processing
+    for my $k(keys %{$self->{VARS}}){
+       $vars->{$k} = $self->{VARS}->{$k};
+    }
+    my $data;
+    $template->process( $self->filename, $vars, \$data) || die "Template process failed: ", $template->error();; 
+    return $data;
+}
+
+# wrapper method to allow easier transition from HTML template pro to Template Toolkit
+sub param{
+    my $self = shift;
+    while(@_){
+       my $key = shift;
+       my $val = shift;
+        utf8::encode($val) if utf8::is_utf8($val);
+        if( ref($val) eq 'ARRAY' && ! scalar @$val ){ $val = undef; }
+        elsif( ref($val) eq 'HASH' && ! scalar %$val ){ $val = undef; }
+       $self->{VARS}->{$key} = $val;
+    }
+}
+
+1;
index a161203..d523c75 100755 (executable)
@@ -164,7 +164,7 @@ sub TransformPrefsToHTML {
                 }
             }
 
-            push @lines, { CHUNKS => \@chunks, NAMES => \@names };
+            push @lines, { CHUNKS => \@chunks, NAMES => \@names, is_group_title => 0 };
         }
     }
 
index cc1d954..b8d3bce 100644 (file)
@@ -83,7 +83,7 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('intranetbookbag','1','Si ce paramètre est activé, les adhérents peuvent créer des paniers à l''interface professionnelle','','YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacBrowser', '1', 'Active ou non le feuilletage du catalogue à l''OPAC (nécessite de lancer misc/cronjobs/build_browser_and_cloud.pl sur le serveur)', '', 'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacCloud', '1', 'Active ou non l''affichage des nuages de tag à l''OPAC (nécessite de lancer misc/cronjobs/build_browser_and_cloud.pl sur le serveur)', '', 'YesNo');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccolorstylesheet', '', 'Ce paramètre a la forme d''une URL. Il définit la feuille de style utilisée à l''OPAC. S''il est vide, vous aurez la feuille de style par défault de Koha', '', 'free');
+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccolorstylesheet', '', 'Définit une feuille de style auxiliaire pour l'OPAC qui prend le pas sur la feuille de style primaire. Entrez le nom du fichier (si le fichier est sur le serveur) ou une URL commencant par http (si le fichier est sur un serveur distant).', '', 'free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccredits', '', 'Ce paramètre contient du code HTML, qui apparaît en bas de la page d''accueil de l''OPAC. C''est un "pied de page" de la page d''accueil', '70|10', '');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaclanguages', 'fr-FR', 'Ce paramètre définit la langue par défaut de l''OPAC, ainsi que la langue de l''interface professionnelle', '', 'Languages');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaclanguagesdisplay', '1', 'Si ce paramètre est activé, les adhérents peuvent modifier la langue d''affichage de l''OPAC. Sinon, ils sont limités à la langue choisie par la bibliothèque', '', 'YesNo');
index cfbca16..9cff5c4 100644 (file)
@@ -70,7 +70,7 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('intranetbookbag','1','If ON, enables display of Cart feature in the intranet','','YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacBrowser',0,'If ON, enables subject authorities browser on OPAC (needs to set misc/cronjob/sbuild_browser_and_cloud.pl)',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacCloud',0,'If ON, enables subject cloud on OPAC',NULL,'YesNo');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccolorstylesheet','colors.css','Define the color stylesheet to use in the OPAC','','free');
+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccolorstylesheet','colors.css','Define an auxiliary stylesheet for OPAC use, to override specified settings from the primary opac.css stylesheet. Enter the filename (if the file is in the server's css directory) or a complete URL beginning with http (if the file lives on a remote server).','','free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccredits','','Define HTML Credits at the bottom of the OPAC page','70|10','Textarea');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opacSerialDefaultTab', 'subscriptions', 'Define the default tab for serials in OPAC.', 'holdings|serialcollection|subscriptions', 'Choice');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opacheader','','Add HTML to be included as a custom header in the OPAC','70|10','Textarea');
index 5ffcd7b..0820c2f 100644 (file)
@@ -100,7 +100,7 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opacbookbag',1,'If ON, enables display of Cart feature','','YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacBrowser',0,'If ON, enables subject authorities browser on OPAC (needs to set misc/cronjob/sbuild_browser_and_cloud.pl)',NULL,'YesNo');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacCloud',0,'If ON, enables subject cloud on OPAC',NULL,'YesNo');
-INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccolorstylesheet','colors.css','Define the color stylesheet to use in the OPAC','','free');
+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccolorstylesheet','colors.css','Define an auxiliary stylesheet for OPAC use, to override specified settings from the primary opac.css stylesheet. Enter the filename (if the file is in the server's css directory) or a complete URL beginning with http (if the file lives on a remote server).','','free');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaccredits','','Define HTML Credits at the bottom of the OPAC page','70|10','Textarea');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opacheader','','Add HTML to be included as a custom header in the OPAC','30|10','Textarea');
 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opaclayoutstylesheet','opac.css','Enter the name of the layout CSS stylesheet to use in the OPAC','','free');
diff --git a/installer/html-template-to-template-toolkit.pl b/installer/html-template-to-template-toolkit.pl
new file mode 100755 (executable)
index 0000000..ce65e97
--- /dev/null
@@ -0,0 +1,236 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Carp;
+use Data::Dumper;
+
+use Getopt::Long;
+use File::Basename;
+use File::Copy;
+
+my $help_msg = <<EOH;
+This script does a first-cut conversion of koha HTML::Template template files (.tmpl).
+It creates a mirror of koha-tmpl called koha-tt where converted files will be placed.
+By default all files will be converted: use the --file (-f) argument to specify
+  individual files to process.
+
+Options:
+    --koharoot (-r): Root directory of koha installation.
+    --type (-t): template file extenstions to match
+        (defaults to tmpl|inc|xsl).
+    --copyall (-c): Also copy across all files in template directory
+    --file (-f): specify individual files to process
+    --debug (-d): output more information.
+EOH
+
+my $tmpl_in_dir      = 'koha-tmpl';
+my $tmpl_out_dir     = 'koha-tt';
+
+# template toolkit variables NOT to scope, in other words, variables that need to remain global (case sensitive)
+my @globals = ("themelang");
+
+# Arguments:
+my $KOHA_ROOT;
+my $tmpl_extn_match  = "tmpl|inc|xsl"; # Type match defaults to *.tmpl plus *.inc if not specified
+my $copy_other_files = 0;
+my @template_files;
+my @files_w_tmpl_loops;
+my $verbose          = 0;
+GetOptions (
+    "koharoot=s"        => \$KOHA_ROOT,
+    "type|t=s"          => \$tmpl_extn_match,
+    "copyall|c"         => \$copy_other_files,
+    "file|f=s"          => \@template_files,         # array of filenames
+    "verbose+"          => \$verbose,                # incremental flag
+) or die $help_msg;
+
+if ( ! $KOHA_ROOT || ! -d $KOHA_ROOT ) {
+    croak "Koha root not passed or is not correct.";
+}
+if ( ! -d "$KOHA_ROOT/$tmpl_in_dir" ) {
+    croak "Cannot find template dir ($tmpl_in_dir)";
+}
+
+# Attempt to create koha-tt dir..
+if ( ! -d "$KOHA_ROOT/$tmpl_out_dir" ) {
+    mkdir("$KOHA_ROOT/$tmpl_out_dir") #, '0755'
+       or croak "Cannot create $tmpl_out_dir directory in $KOHA_ROOT: $!";
+}
+
+# Obtain list of files to process - go recursively through tmpl_in_dir and subdirectories..
+unless ( scalar(@template_files) ) {
+    @template_files = mirror_template_dir_structure_return_files("$KOHA_ROOT/$tmpl_in_dir", "$tmpl_extn_match");
+}
+foreach my $file (@template_files) {
+    (my $new_path = $file) =~ s/$tmpl_in_dir/$tmpl_out_dir/;
+    $new_path =~ s/\.tmpl/.tt/;
+    $new_path = "$KOHA_ROOT/$new_path" unless ( $new_path =~ m/^$KOHA_ROOT/ );
+
+    open my $ITMPL, '<', $file or croak "Can't open $file for input: $!";
+    open my $OTT, '>', $new_path or croak "Can't open $new_path for output: $!";
+
+    # allows 'proper' handling of for loop scope
+    # cur_scope is a stack of scopes, the last being the current
+    #   when opening a for loop push scope onto end, when closing for loop pop
+    my @cur_scope = ("");
+    # flag representing if we've found a for loop this iteration
+    my $for_loop_found = 0;
+
+    for my $input_tmpl(<$ITMPL>){
+        my @parts = split "<", $input_tmpl;
+        for( my $i=0; $i<=$#parts; ++$i ){
+            my $input_tmpl = $i ? "<" . $parts[$i] : $parts[$i]; # add < sign back in to every part except the first
+       $for_loop_found = 0;
+
+       # handle poorly names variable such as f1!, f1+, f1-, f1| and mod
+       $input_tmpl =~ s/"(\w+)\|"/"$1pipe"/ig;
+       $input_tmpl =~ s/"(\w+)\+"/"$1plus"/ig;
+       $input_tmpl =~ s/"(\w+)\-"/"$1minus"/ig;
+       $input_tmpl =~ s/"(\w+)!"/"$1exclamation"/ig;
+#      $input_tmpl =~ s/"(\w+),(\w+)"/"$1comma$2"/ig; #caused a problem in patron search
+       $input_tmpl =~ s/NAME="mod"/NAME="modname"/ig;
+       # handle 'naked' TMPL_VAR "parameter" by turning them into what they should be, TMPL_VAR NAME="parameter"
+       $input_tmpl =~ s/TMPL_VAR\s+"(\w+)"/TMPL_VAR NAME="$1"/ig;
+       # make an end (ESCAPE NAME DEFAULT) into a ned (NAME ESCAPE DEFAULT)
+       $input_tmpl =~ s/ESCAPE="(\w+?)"\s+NAME=['"](\w+?)['"]\s+DEFAULT=['"](.+?)['"]/NAME="$2" ESCAPE="$1" DEFAULT="$3"/ig;
+
+       # Process..
+       # NB: if you think you're seeing double, you probably are, *some* (read:most) patterns appear twice: once with quotations marks, once without.
+       #     trying to combine them into a single pattern proved troublesome as a regex like ['"]?(.*?)['"]? was causing problems and fixing the problem caused (alot) more complex regex
+
+       # variables
+       $input_tmpl =~ s/<[!-]*\s*TMPL_VAR\s+NAME\s?=\s?['"]?\s*(\w*?)\s*['"]?\s+ESCAPE=['"](\w*?)['"]\s+DEFAULT=['"]?(.*?)['"]?\s*-*>/[% DEFAULT $cur_scope[-1]$1="$3" |$2 %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_VAR\s+NAME\s?=\s?['"]\s*(\w*?)\s*['"]\s+ESCAPE=['"]?(\w*?)['"]?\s*-*>/[% $cur_scope[-1]$1 |$2 %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_VAR\s+NAME\s?=\s?(\w*?)\s+ESCAPE=['"]?(\w*?)['"]?\s*-*>/[% $cur_scope[-1]$1 |$2 %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_VAR\s+ESCAPE=['"]?(\w*?)['"]?\s+NAME\s?=\s?['"]?([\w-]*?)['"]?\s*-*>/[% $cur_scope[-1]$2 |$1 %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_VAR\s+NAME\s?=\s?['"]?(\w*?)['"]?\s+DEFAULT=['"](.*?)['"]\s*-*>/[% DEFAULT $cur_scope[-1]$1="$2" %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_VAR\s+NAME\s?=\s?['"]?\s*(\w*?)\s*['"]?\s+DEFAULT=(.*?)\s*-*>/[% DEFAULT $cur_scope[-1]$1=$2 %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL[_\s]VAR\s+NAME\s?=\s?['"]?\s*(\w*?)\s*['"]?\s*-*>/[% $cur_scope[-1]$1 %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL[_\s]VAR\s+EXPR\s?=\s?['"](.*?)['"]\s*-*>/[% $1 %]/ig;     # TMPL_VAR NAME and TMPL_VAR EXPR are logically equiv
+       $input_tmpl =~ s/<[!-]*\s*TMPL[_\s]VAR\s+EXPR\s?=\s?(.*?)\s*-*>/[% $1 %]/ig;
+
+       # if, elseif and unless blocks
+       $input_tmpl =~ s/<[!-]*\s*TMPL_IF\s+EXPR\s?=\s?['"](.*?)['"]\s*-*>/[% IF ( $1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_IF\s+EXPR\s?=\s?(.*?)\s*-*>/[% IF ( $1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_IF\s+NAME\s?=\s?['"]\s*(\w*?)\s*['"]\s*-*>/[% IF ( $cur_scope[-1]$1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_IF\s+NAME\s?=\s?(\w*?)\s*-*>/[% IF ( $cur_scope[-1]$1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_IF\s+['"](.*?)['"]\s*-*>/[% IF ( $cur_scope[-1]$1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_IF\s+([\w\s]*?)\s*-*>/[% IF ( $cur_scope[-1]$1 ) %]/ig;
+
+       $input_tmpl =~ s/<[!-]*\s*TMPL_ELSIF\s+EXPR\s?=\s?['"](.*?)['"]\s*-*>/[% ELSIF ( $1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_ELSIF\s+EXPR\s?=\s?(.*?)\s*-*>/[% ELSIF ( $1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_ELSIF\s+NAME\s?=\s?['"](\w*?)['"]\s*-*>/[% ELSIF ( $cur_scope[-1]$1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_ELSIF\s+NAME\s?=\s?(\w*?)\s*-*>/[% ELSIF ( $cur_scope[-1]$1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_ELSIF\s+['"](\w*?)['"]\s*-*>/[% ELSIF ( $cur_scope[-1]$1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_ELSIF\s+(\w*?)\s*-*>/[% ELSIF ( $cur_scope[-1]$1 ) %]/ig;
+
+       $input_tmpl =~ s/<[!-]*\s*TMPL_ELSE\s*-*>/[% ELSE %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*\/TMPL_IF\s*-*>/[% END %]/ig;
+
+       $input_tmpl =~ s/<[!-]*\s*TMPL_UNLESS\s+NAME\s?=\s?['"]?(\w*?)['"]?\s*-*>/[% UNLESS ( $cur_scope[-1]$1 ) %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*\/TMPL_UNLESS\s*-*>/[% END %]/ig;
+       # includes
+       $input_tmpl =~ s/<[!-]*\s*TMPL_INCLUDE\s+NAME\s?=\s?"(.*?\.inc)"\s*-*>/[% INCLUDE '$1' %]/ig;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_INCLUDE\s+NAME\s?=\s?"(.*?)"\s*-*>/[% INCLUDE $1 %]/ig;
+
+        #reverse scoping bug fix
+        for my $tag (@globals){
+            next unless $cur_scope[-1];
+            $input_tmpl =~ s/$cur_scope[-1]$tag/$tag/g;
+        }
+
+       if ($input_tmpl =~ m/<[!-]*\s*TMPL_LOOP/i ){
+           $for_loop_found = 1;
+       }
+
+       $input_tmpl =~ s/<[!-]*\s*TMPL_LOOP\s+NAME\s?=\s?['"](?<SCOPE>.*?)['"]\s*-*>/"[% FOREACH " . substr($+{SCOPE}, 0, -1) . " IN $cur_scope[-1]$1 %]"/ieg;
+       $input_tmpl =~ s/<[!-]*\s*TMPL_LOOP\s+NAME\s?=\s?(?<SCOPE>.*?)\s*-*>/"[% FOREACH " . substr($+{SCOPE}, 0, -1) . " IN $cur_scope[-1]$1 %]"/ieg;
+
+       # handle new scope
+       if($for_loop_found){
+           my $scope = substr($+{SCOPE}, 0, -1) . ".";
+           push(@cur_scope, $scope);
+           $for_loop_found = 0;
+       }
+
+       # handle loops and old scope
+       if ( $input_tmpl =~ m/<!--[\s\/]*TMPL_LOOP\s*-->/i ) {
+           push(@files_w_tmpl_loops, $new_path);
+           pop(@cur_scope);
+       }
+
+       $input_tmpl =~ s/<[!-]*\s*\/TMPL_LOOP\s*-*>/[% END %]/ig;
+
+       # misc 'patches'
+       $input_tmpl =~ s/\seq\s/ == /ig;
+       $input_tmpl =~ s/HTML/html/g;
+       $input_tmpl =~ s/URL/url/g;
+        $input_tmpl =~ s/dhtmlcalendar_dateformat/DHTMLcalendar_dateformat/ig;
+       $input_tmpl =~ s/\w*\.__first__/loop.first/ig;
+       $input_tmpl =~ s/\w*\.__last__/loop.last/ig;
+       $input_tmpl =~ s/\w*\.__odd__/loop.odd/ig;
+       $input_tmpl =~ s/\w*\.__even__/loop.even/ig;
+       $input_tmpl =~ s/\w*\.__counter__/loop.count/ig; #loop.count gives the range (0..max) whereas loop.index gives the range (1..max+1), __counter__ is unknown
+
+       # hack to get around lack of javascript filter
+       $input_tmpl =~ s/\|\s*JS/|replace("'", "\\'") |replace('"', '\\"') |replace('\\n', '\\\\n') |replace('\\r', '\\\\r')/ig;
+    
+       # Write out..
+        print $OTT $input_tmpl;
+        }
+    }
+    close $ITMPL;
+    close $OTT;
+}
+
+if ( scalar(@files_w_tmpl_loops) && $verbose ) {
+    print "\nThese files contain TMPL_LOOPs that need double checking:\n";
+    foreach my $file (@files_w_tmpl_loops) {
+        print "$file\n";
+    }
+}
+
+## SUB-ROUTINES ##
+
+# Create new directory structure and return list of template files
+sub mirror_template_dir_structure_return_files {
+    my($dir, $type) = @_;
+
+    my @files = ();
+    if ( opendir(DIR, $dir) ) {
+        my @dirent = readdir DIR;   # because DIR is shared when recursing
+        closedir DIR;
+        for my $dirent (@dirent) {
+            my $path = "$dir/$dirent";
+            if ( $dirent =~ /^\./ ) {
+              ;
+            }
+            elsif ( -f $path ) {
+                (my $new_path = $path) =~ s/$tmpl_in_dir/$tmpl_out_dir/;
+                $new_path = "$KOHA_ROOT/$new_path" unless ( $new_path =~ m/^$KOHA_ROOT/ );
+                if ( !defined $type || $dirent =~ /\.(?:$type)$/) {
+                    push(@files, $path);
+                }
+                elsif ( $copy_other_files ) {
+                    copy($path, $new_path)
+                      or croak "Failed to copy $path to $new_path: $!";
+                }
+            }
+            elsif ( -d $path ) {
+                (my $new_path = $path) =~ s/$tmpl_in_dir/$tmpl_out_dir/;
+                $new_path = "$KOHA_ROOT/$new_path" unless ( $new_path =~ m/^$KOHA_ROOT/ );
+                if ( ! -d $new_path ) {
+                    mkdir($new_path) #, '0755'
+                      or croak "Failed to create " . $new_path ." directory: $!";
+                }
+                my @sub_files = mirror_template_dir_structure_return_files($path, $type);
+                push(@files, @sub_files) if ( scalar(@sub_files) );
+            }
+        }
+    } else {
+        warn("Cannot open $dir: $! ... skipping");
+    }
+
+    return @files;
+}
index d8a4423..11399e1 100644 (file)
@@ -7,6 +7,9 @@
 <!-- TMPL_IF name="opaccolorstylesheet" -->
     <link rel="stylesheet" type="text/css" href="<!-- TMPL_VAR NAME="themelang" -->/css/<!-- TMPL_VAR NAME="opaccolorstylesheet" -->" />
 <!-- /TMPL_IF -->
+<!-- TMPL_IF name="opacexternalsheet" -->
+    <link rel="stylesheet" type="text/css" href="<!-- TMPL_VAR NAME="opacexternalsheet" -->" />
+<!-- /TMPL_IF -->
 <!-- TMPL_IF name="opac_css_override" -->
     <link rel="stylesheet" type="text/css" href="<!-- TMPL_VAR NAME="themelang" -->/css/<!-- TMPL_VAR NAME="opac_css_override" -->" />
 <!-- /TMPL_IF -->