Bug 8622: Fix theme fallback
authorJared Camins-Esakov <jcamins@cpbibliography.com>
Sun, 12 Aug 2012 23:32:18 +0000 (19:32 -0400)
committerPaul Poulain <paul.poulain@biblibre.com>
Wed, 5 Sep 2012 09:39:14 +0000 (11:39 +0200)
This patch does the following:
1) Enables fallback for includes between different themes and different
   languages (with the exact same precedence as for .tt files)
2) Enable fallback for XSLT files between different themes and different
   languages (again, same precedence)
3) Change the semantics of the TT [% themelang %] variable so that it always
   refers to the preferred theme and language, rather than the fallback
   theme/language. As a result, all themes must include all javascript,
   css and image resources they use.

Note that these changes actually have no impact whatsoever on an
installation where the default (prog) themes are in use.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Mason James <mtj@kohaaloha.com>
Signed-off-by: Paul Poulain <paul.poulain@biblibre.com>
C4/Output.pm
C4/Reports/Guided.pm
C4/Templates.pm
C4/XSLT.pm
catalogue/moredetail.pl
edithelp.pl
opac/opac-main.pl

index 8cfa351..57faa00 100644 (file)
@@ -42,13 +42,13 @@ BEGIN {
 
  @ISA    = qw(Exporter);
     @EXPORT_OK = qw(&is_ajax ajax_fail); # More stuff should go here instead
-    %EXPORT_TAGS = ( all =>[qw(&themelanguage &gettemplate setlanguagecookie pagination_bar &gettemplate
+    %EXPORT_TAGS = ( all =>[qw(setlanguagecookie pagination_bar
                                 &output_with_http_headers &output_ajax_with_http_headers &output_html_with_http_headers)],
                     ajax =>[qw(&output_with_http_headers &output_ajax_with_http_headers is_ajax)],
                     html =>[qw(&output_with_http_headers &output_html_with_http_headers)]
                 );
     push @EXPORT, qw(
-        &themelanguage &gettemplate setlanguagecookie getlanguagecookie pagination_bar &gettemplate
+        setlanguagecookie getlanguagecookie pagination_bar
     );
     push @EXPORT, qw(
         &output_html_with_http_headers &output_ajax_with_http_headers &output_with_http_headers FormatData FormatNumber
index f682fe8..e5c28f3 100644 (file)
@@ -802,7 +802,7 @@ sub _get_column_defs {
        my $columns_def_file = "columns.def";
        my $htdocs = C4::Context->config('intrahtdocs');                       
        my $section='intranet';
-       my ($theme, $lang) = C4::Templates::themelanguage($htdocs, $columns_def_file, $section,$cgi);
+    my ($theme, $lang, $availablethemes) = C4::Templates::themelanguage($htdocs, $columns_def_file, $section,$cgi);
 
        my $full_path_to_columns_def_file="$htdocs/$theme/$lang/$columns_def_file";    
        open (COLUMNS,$full_path_to_columns_def_file);
index e0baf2f..46e0c09 100644 (file)
@@ -36,7 +36,7 @@ use C4::Languages qw(getTranslatedLanguages get_bidi regex_lang_subtags language
 
 use C4::Context;
 
-__PACKAGE__->mk_accessors(qw( theme lang filename htdocs interface vars));
+__PACKAGE__->mk_accessors(qw( theme activethemes preferredtheme lang filename htdocs interface vars));
 
 
 
@@ -53,17 +53,19 @@ sub new {
     else {
         $htdocs = C4::Context->config('intrahtdocs');
     }
-    my ($theme, $lang)= themelanguage( $htdocs, $tmplbase, $interface, $query);
+    my ($theme, $lang, $activethemes)= themelanguage( $htdocs, $tmplbase, $interface, $query);
+    my @includes;
+    foreach (@$activethemes) {
+        push @includes, "$htdocs/$_/$lang/includes";
+        push @includes, "$htdocs/$_/en/includes" unless $lang eq 'en';
+    }
     my $template = Template->new(
         {   EVAL_PERL    => 1,
             ABSOLUTE     => 1,
             PLUGIN_BASE => 'Koha::Template::Plugin',
             COMPILE_EXT => C4::Context->config('template_cache_dir')?'.ttc':'',
             COMPILE_DIR => C4::Context->config('template_cache_dir')?C4::Context->config('template_cache_dir'):'',,
-            INCLUDE_PATH => [
-                "$htdocs/$theme/$lang/includes",
-                "$htdocs/$theme/en/includes"
-            ],
+            INCLUDE_PATH => \@includes,
             FILTERS => {},
         }
     ) or die Template->error();
@@ -74,6 +76,8 @@ sub new {
     bless $self, $class;
     $self->theme($theme);
     $self->lang($lang);
+    $self->activethemes($activethemes);
+    $self->preferredtheme($activethemes->[0]);
     $self->filename($filename);
     $self->htdocs($htdocs);
     $self->interface($interface);
@@ -95,7 +99,7 @@ sub output {
         $vars->{themelang} = '/opac-tmpl';
     }
     $vars->{lang} = $self->lang;
-    $vars->{themelang} .= '/' . $self->theme . '/' . $self->lang;
+    $vars->{themelang} .= '/' . $self->preferredtheme . '/' . $self->lang;
     $vars->{yuipath} =
       ( C4::Context->preference("yuipath") eq "local"
         ? $vars->{themelang} . "/lib/yui"
@@ -211,7 +215,7 @@ sub _get_template_file {
 
     my $is_intranet = $interface eq 'intranet';
     my $htdocs = C4::Context->config($is_intranet ? 'intrahtdocs' : 'opachtdocs');
-    my ($theme, $lang) = themelanguage($htdocs, $tmplbase, $interface, $query);
+    my ($theme, $lang, $availablethemes) = themelanguage($htdocs, $tmplbase, $interface, $query);
 
     # if the template doesn't exist, load the English one as a last resort
     my $filename = "$htdocs/$theme/$lang/modules/$tmplbase";
@@ -231,19 +235,21 @@ sub gettemplate {
     my ($htdocs, $theme, $lang, $filename)
        =  _get_template_file($tmplbase, $interface, $query);
     my $template = C4::Templates->new($interface, $filename, $tmplbase, $query);
-    my $is_intranet = $interface eq 'intranet';
-    my $themelang =
-        ($is_intranet ? '/intranet-tmpl' : '/opac-tmpl') .
-        "/$theme/$lang";
-    $template->param(
-        themelang => $themelang,
-        yuipath   => C4::Context->preference("yuipath") eq "local"
-                     ? "$themelang/lib/yui"
-                     : C4::Context->preference("yuipath"),
-        interface => $is_intranet ? '/intranet-tmpl' : '/opac-tmpl',
-        theme     => $theme,
-        lang      => $lang
-    );
+# NOTE: Commenting these out rather than deleting them so that those who need
+# to know how we previously shimmed these directories will be able to understand.
+#    my $is_intranet = $interface eq 'intranet';
+#    my $themelang =
+#        ($is_intranet ? '/intranet-tmpl' : '/opac-tmpl') .
+#        "/$theme/$lang";
+#    $template->param(
+#        themelang => $themelang,
+#        yuipath   => C4::Context->preference("yuipath") eq "local"
+#                     ? "$themelang/lib/yui"
+#                     : C4::Context->preference("yuipath"),
+#        interface => $is_intranet ? '/intranet-tmpl' : '/opac-tmpl',
+#        theme     => $theme,
+#        lang      => $lang
+#    );
 
     # Bidirectionality
     my $current_lang = regex_lang_subtags($lang);
@@ -286,11 +292,11 @@ sub themelanguage {
     for my $theme (@themes) {
         if ( -e "$htdocs/$theme/$lang/modules/$tmpl" ) {
             $_current_language = $lang;
-            return ($theme, $lang)
+            return ($theme, $lang, \@themes)
         }
     }
     # Otherwise, return prog theme in English 'en'
-    return ('prog', 'en');
+    return ('prog', 'en', \@themes);
 }
 
 
index 36a3bfc..d17b828 100644 (file)
@@ -140,35 +140,35 @@ sub XSLTParse4Display {
     my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_;
     my $xslfilename = C4::Context->preference($xslsyspref);
     if ( $xslfilename =~ /^\s*"?default"?\s*$/i ) {
+        my $htdocs;
+        my $theme;
+        my $lang = C4::Templates::_current_language();
+        my $xslfile;
         if ($xslsyspref eq "XSLTDetailsDisplay") {
-            $xslfilename = C4::Context->config('intrahtdocs') .
-                        '/' . C4::Context->preference("template") .
-                        '/' . C4::Templates::_current_language() .
-                        '/xslt/' .
-                        C4::Context->preference('marcflavour') .
-                        "slim2intranetDetail.xsl";
+            $htdocs  = C4::Context->config('intrahtdocs');
+            $theme   = C4::Context->preference("template");
+            $xslfile = C4::Context->preference('marcflavour') .
+                       "slim2intranetDetail.xsl";
         } elsif ($xslsyspref eq "XSLTResultsDisplay") {
-            $xslfilename = C4::Context->config('intrahtdocs') .
-                        '/' . C4::Context->preference("template") .
-                        '/' . C4::Templates::_current_language() .
-                        '/xslt/' .
-                        C4::Context->preference('marcflavour') .
+            $htdocs  = C4::Context->config('intrahtdocs');
+            $theme   = C4::Context->preference("template");
+            $xslfile = C4::Context->preference('marcflavour') .
                         "slim2intranetResults.xsl";
         } elsif ($xslsyspref eq "OPACXSLTDetailsDisplay") {
-            $xslfilename = C4::Context->config('opachtdocs') .
-                        '/' . C4::Context->preference("opacthemes") .
-                        '/' . C4::Templates::_current_language() .
-                        '/xslt/' .
-                        C4::Context->preference('marcflavour') .
-                        "slim2OPACDetail.xsl";
+            $htdocs  = C4::Context->config('opachtdocs');
+            $theme   = C4::Context->preference("opacthemes");
+            $xslfile = C4::Context->preference('marcflavour') .
+                       "slim2OPACDetail.xsl";
         } elsif ($xslsyspref eq "OPACXSLTResultsDisplay") {
-            $xslfilename = C4::Context->config('opachtdocs') .
-                        '/' . C4::Context->preference("opacthemes") .
-                        '/' . C4::Templates::_current_language() .
-                        '/xslt/' .
-                        C4::Context->preference('marcflavour') .
-                        "slim2OPACResults.xsl";
+            $htdocs  = C4::Context->config('opachtdocs');
+            $theme   = C4::Context->preference("opacthemes");
+            $xslfile = C4::Context->preference('marcflavour') .
+                       "slim2OPACResults.xsl";
         }
+        $xslfilename = "$htdocs/$theme/$lang/xslt/$xslfile";
+        $xslfilename = "$htdocs/$theme/en/xslt/$xslfile" unless ( $lang ne 'en' && !-f $xslfilename );
+        $xslfilename = "$htdocs/prog/$lang/xslt/$xslfile" unless ( !-f $xslfilename );
+        $xslfilename = "$htdocs/prog/en/xslt/$xslfile" unless ( $lang ne 'en' && !-f $xslfilename );
     }
 
     if ( $xslfilename =~ m/\{langcode\}/ ) {
index 809430c..3eee676 100755 (executable)
@@ -28,7 +28,7 @@ use C4::Items;
 use C4::Branch;
 use C4::Acquisition;
 use C4::Bookseller qw(GetBookSellerFromId);
-use C4::Output;             # contains gettemplate
+use C4::Output;
 use C4::Auth;
 use C4::Serials;
 use C4::Circulation;  # to use itemissues
index 5cde314..28586b3 100755 (executable)
@@ -67,7 +67,7 @@ sub _get_filepath ($;$) {
     $referer =~ /koha\/(.*)\.pl/;
     my $from = "help/$1.tt";
     my $htdocs = C4::Context->config('intrahtdocs');
-    my ($theme, $lang) = C4::Templates::themelanguage( $htdocs, $from, "intranet", $input );
+    my ($theme, $lang, $availablethemes) = C4::Templates::themelanguage( $htdocs, $from, "intranet", $input );
        $debug and print STDERR "help filepath: $htdocs/$theme/$lang/modules/$from";
        return "$htdocs/$theme/$lang/modules/$from";
 }
index 0d5bb9e..c716c60 100755 (executable)
@@ -46,7 +46,7 @@ $template->param(
 
 # display news
 # use cookie setting for language, bug default to syspref if it's not set
-my ($theme, $news_lang) = C4::Templates::themelanguage(C4::Context->config('opachtdocs'),'opac-main.tt','opac',$input);
+my ($theme, $news_lang, $availablethemes) = C4::Templates::themelanguage(C4::Context->config('opachtdocs'),'opac-main.tt','opac',$input);
 
 my $all_koha_news   = &GetNewsToDisplay($news_lang);
 my $koha_news_count = scalar @$all_koha_news;