Bug 6755 Problems with switching languages

This patch solves the situation that news is in another language than
the Koha interface AND makes that themelanguage routine is always called
the same way in order to prevent mixed display.

It fixes also a bug related to language preselection based on web
browser prefered language.

September 9: Adjusted with input of Frederic Demians.

Septembre 10: Avoid circular dependency, as pointed by Chris Cormack.
Templates related functions are moved from C4::Output to C4::Templates

Signed-off-by: Alex Arnaud <alex.arnaud@biblibre.com>
Signed-off-by: Ian Walls <ian.walls@bywatersolutions.com>
Signed-off-by: Chris Cormack <chrisc@catalyst.net.nz>
This commit is contained in:
Frédéric Demians 2011-08-25 15:01:19 +02:00 committed by Chris Cormack
parent 4029e8ed75
commit 6b8be20497
16 changed files with 195 additions and 230 deletions

View File

@ -26,7 +26,7 @@ use CGI::Session;
require Exporter;
use C4::Context;
use C4::Output; # to get the template
use C4::Templates; # to get the template
use C4::Members;
use C4::Koha;
use C4::Branch; # GetBranches
@ -136,7 +136,7 @@ EOQ
sub get_template_and_user {
my $in = shift;
my $template =
gettemplate( $in->{'template_name'}, $in->{'type'}, $in->{'query'} );
C4::Templates::gettemplate( $in->{'template_name'}, $in->{'type'}, $in->{'query'} );
my ( $user, $cookie, $sessionID, $flags );
if ( $in->{'template_name'} !~m/maintenance/ ) {
( $user, $cookie, $sessionID, $flags ) = checkauth(
@ -936,7 +936,7 @@ sub checkauth {
}
my $template_name = ( $type eq 'opac' ) ? 'opac-auth.tmpl' : 'auth.tmpl';
my $template = gettemplate( $template_name, $type, $query );
my $template = C4::Templates::gettemplate( $template_name, $type, $query );
$template->param(branchloop => \@branch_loop,);
my $checkstyle = C4::Context->preference("opaccolorstylesheet");
if ($checkstyle =~ /\//)

View File

@ -29,7 +29,6 @@ use strict;
#use warnings; FIXME - Bug 2505
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;
@ -43,192 +42,16 @@ BEGIN {
require Exporter;
@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
&output_with_http_headers &output_html_with_http_headers)],
%EXPORT_TAGS = ( all =>[qw(&pagination_bar
&output_with_http_headers &output_html_with_http_headers)],
ajax =>[qw(&output_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
);
push @EXPORT, qw(
&output_html_with_http_headers &output_with_http_headers FormatData FormatNumber
&output_html_with_http_headers &output_with_http_headers FormatData FormatNumber pagination_bar
);
}
=head1 NAME
C4::Output - Functions for managing templates
=head1 FUNCTIONS
=over 2
=cut
#FIXME: this is a quick fix to stop rc1 installing broken
#Still trying to figure out the correct fix.
my $path = C4::Context->config('intrahtdocs') . "/prog/en/includes/";
#---------------------------------------------------------------------------------------------------------
# FIXME - POD
sub _get_template_file {
my ( $tmplbase, $interface, $query ) = @_;
my $htdocs = C4::Context->config( $interface ne 'intranet' ? 'opachtdocs' : 'intrahtdocs' );
my ( $theme, $lang ) = themelanguage( $htdocs, $tmplbase, $interface, $query );
my $opacstylesheet = C4::Context->preference('opacstylesheet');
# if the template doesn't exist, load the English one as a last resort
my $filename = "$htdocs/$theme/$lang/modules/$tmplbase";
unless (-f $filename) {
$lang = 'en';
$filename = "$htdocs/$theme/$lang/modules/$tmplbase";
}
return ( $htdocs, $theme, $lang, $filename );
}
sub gettemplate {
my ( $tmplbase, $interface, $query ) = @_;
($query) or warn "no query in gettemplate";
my $path = C4::Context->preference('intranet_includes') || 'includes';
my $opacstylesheet = C4::Context->preference('opacstylesheet');
$tmplbase =~ s/\.tmpl$/.tt/;
my ( $htdocs, $theme, $lang, $filename ) = _get_template_file( $tmplbase, $interface, $query );
my $template = C4::Templates->new( $interface, $filename, $tmplbase);
my $themelang=( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' )
. "/$theme/$lang";
$template->param(
themelang => $themelang,
yuipath => (C4::Context->preference("yuipath") eq "local"?"$themelang/lib/yui":C4::Context->preference("yuipath")),
interface => ( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' ),
theme => $theme,
lang => $lang
);
# Bidirectionality
my $current_lang = regex_lang_subtags($lang);
my $bidi;
$bidi = get_bidi($current_lang->{script}) if $current_lang->{script};
# Languages
my $languages_loop = getTranslatedLanguages($interface,$theme,$lang);
my $num_languages_enabled = 0;
foreach my $lang (@$languages_loop) {
foreach my $sublang (@{ $lang->{'sublanguages_loop'} }) {
$num_languages_enabled++ if $sublang->{enabled};
}
}
$template->param(
languages_loop => $languages_loop,
bidi => $bidi,
one_language_enabled => ($num_languages_enabled <= 1) ? 1 : 0, # deal with zero enabled langs as well
) unless @$languages_loop<2;
return $template;
}
# FIXME - this is a horrible hack to cache
# the current known-good language, temporarily
# put in place to resolve bug 4403. It is
# used only by C4::XSLT::XSLTParse4Display;
# the language is set via the usual call
# to themelanguage.
my $_current_language = 'en';
sub _current_language {
return $_current_language;
}
#---------------------------------------------------------------------------------------------------------
# FIXME - POD
sub themelanguage {
my ( $htdocs, $tmpl, $interface, $query ) = @_;
($query) or warn "no query in themelanguage";
# Set some defaults for language and theme
# First, check the user's preferences
my $lang;
my $http_accept_language = $ENV{ HTTP_ACCEPT_LANGUAGE };
$lang = accept_language( $http_accept_language,
getTranslatedLanguages($interface,'prog') )
if $http_accept_language;
# But, if there's a cookie set, obey it
$lang = $query->cookie('KohaOpacLanguage') if (defined $query and $query->cookie('KohaOpacLanguage'));
# Fall back to English
my @languages;
if ($interface eq 'intranet') {
@languages = split ",", C4::Context->preference("language");
} else {
@languages = split ",", C4::Context->preference("opaclanguages");
}
if ($lang){
@languages=($lang,@languages);
} else {
$lang = $languages[0];
}
my $theme = 'prog'; # in the event of theme failure default to 'prog' -fbcit
my $dbh = C4::Context->dbh;
my @themes;
if ( $interface eq "intranet" ) {
@themes = split " ", C4::Context->preference("template");
}
else {
# we are in the opac here, what im trying to do is let the individual user
# set the theme they want to use.
# and perhaps the them as well.
#my $lang = $query->cookie('KohaOpacLanguage');
@themes = split " ", C4::Context->preference("opacthemes");
}
# searches through the themes and languages. First template it find it returns.
# Priority is for getting the theme right.
THEME:
foreach my $th (@themes) {
foreach my $la (@languages) {
#for ( my $pass = 1 ; $pass <= 2 ; $pass += 1 ) {
# warn "$htdocs/$th/$la/modules/$interface-"."tmpl";
#$la =~ s/([-_])/ $1 eq '-'? '_': '-' /eg if $pass == 2;
if ( -e "$htdocs/$th/$la/modules/$tmpl") {
#".($interface eq 'intranet'?"modules":"")."/$tmpl" ) {
$theme = $th;
$lang = $la;
last THEME;
}
last unless $la =~ /[-_]/;
#}
}
}
$_current_language = $lang; # FIXME part of bad hack to paper over bug 4403
return ( $theme, $lang );
}
sub setlanguagecookie {
my ( $query, $language, $uri ) = @_;
my $cookie = $query->cookie(
-name => 'KohaOpacLanguage',
-value => $language,
-expires => ''
);
print $query->redirect(
-uri => $uri,
-cookie => $cookie
);
}
sub getlanguagecookie {
my ($query) = @_;
my $lang;
if ($query->cookie('KohaOpacLanguage')){
$lang = $query->cookie('KohaOpacLanguage') ;
}else{
$lang = $ENV{HTTP_ACCEPT_LANGUAGE};
}
$lang = substr($lang, 0, 2);
return $lang;
}
=item FormatNumber
=cut

View File

@ -31,16 +31,20 @@ use CGI;
use base qw(Class::Accessor);
use Template;
use Template::Constants qw( :debug );
use C4::Languages qw(getTranslatedLanguages get_bidi regex_lang_subtags language_get_description accept_language );
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 $tmplbase = shift;
my $query = @_? shift: undef;
my $htdocs;
if ( $interface ne "intranet" ) {
$htdocs = C4::Context->config('opachtdocs');
@ -49,7 +53,7 @@ sub new {
$htdocs = C4::Context->config('intrahtdocs');
}
my ( $theme, $lang ) = themelanguage( $htdocs, $tmplbase, $interface );
my ($theme, $lang)= themelanguage( $htdocs, $tmplbase, $interface, $query);
my $template = Template->new(
{
EVAL_PERL => 1,
@ -164,7 +168,7 @@ sub _current_language {
return $_current_language;
}
sub themelanguage {
sub themelanguage_lite {
my ( $htdocs, $tmpl, $interface ) = @_;
my $query = new CGI;
@ -228,5 +232,170 @@ sub param {
}
}
=head1 NAME
C4::Templates - Functions for managing templates
=head1 FUNCTIONS
=over 2
=cut
#FIXME: this is a quick fix to stop rc1 installing broken
#Still trying to figure out the correct fix.
my $path = C4::Context->config('intrahtdocs') . "/prog/en/includes/";
#---------------------------------------------------------------------------------------------------------
# FIXME - POD
sub _get_template_file {
my ( $tmplbase, $interface, $query ) = @_;
my $htdocs = C4::Context->config( $interface ne 'intranet' ? 'opachtdocs' : 'intrahtdocs' );
my ( $theme, $lang ) = themelanguage( $htdocs, $tmplbase, $interface, $query );
my $opacstylesheet = C4::Context->preference('opacstylesheet');
# if the template doesn't exist, load the English one as a last resort
my $filename = "$htdocs/$theme/$lang/modules/$tmplbase";
unless (-f $filename) {
$lang = 'en';
$filename = "$htdocs/$theme/$lang/modules/$tmplbase";
}
return ( $htdocs, $theme, $lang, $filename );
}
sub gettemplate {
my ( $tmplbase, $interface, $query ) = @_;
($query) or warn "no query in gettemplate";
my $path = C4::Context->preference('intranet_includes') || 'includes';
my $opacstylesheet = C4::Context->preference('opacstylesheet');
$tmplbase =~ s/\.tmpl$/.tt/;
my ( $htdocs, $theme, $lang, $filename ) = _get_template_file( $tmplbase, $interface, $query );
my $template = C4::Templates->new($interface, $filename, $tmplbase, $query);
my $themelang=( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' )
. "/$theme/$lang";
$template->param(
themelang => $themelang,
yuipath => (C4::Context->preference("yuipath") eq "local"?"$themelang/lib/yui":C4::Context->preference("yuipath")),
interface => ( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' ),
theme => $theme,
lang => $lang
);
# Bidirectionality
my $current_lang = regex_lang_subtags($lang);
my $bidi;
$bidi = get_bidi($current_lang->{script}) if $current_lang->{script};
# Languages
my $languages_loop = getTranslatedLanguages($interface,$theme,$lang);
my $num_languages_enabled = 0;
foreach my $lang (@$languages_loop) {
foreach my $sublang (@{ $lang->{'sublanguages_loop'} }) {
$num_languages_enabled++ if $sublang->{enabled};
}
}
$template->param(
languages_loop => $languages_loop,
bidi => $bidi,
one_language_enabled => ($num_languages_enabled <= 1) ? 1 : 0, # deal with zero enabled langs as well
) unless @$languages_loop<2;
return $template;
}
#---------------------------------------------------------------------------------------------------------
# FIXME - POD
sub themelanguage {
my ( $htdocs, $tmpl, $interface, $query ) = @_;
($query) or warn "no query in themelanguage";
# Set some defaults for language and theme
# First, check the user's preferences
my $lang;
my $http_accept_language = $ENV{ HTTP_ACCEPT_LANGUAGE };
$lang = accept_language( $http_accept_language,
getTranslatedLanguages($interface,'prog') )
if $http_accept_language;
# But, if there's a cookie set, obey it
$lang = $query->cookie('KohaOpacLanguage') if (defined $query and $query->cookie('KohaOpacLanguage'));
# Fall back to English
my @languages;
if ($interface eq 'intranet') {
@languages = split ",", C4::Context->preference("language");
} else {
@languages = split ",", C4::Context->preference("opaclanguages");
}
if ($lang){
@languages=($lang,@languages);
} else {
$lang = $languages[0];
}
my $theme = 'prog'; # in the event of theme failure default to 'prog' -fbcit
my $dbh = C4::Context->dbh;
my @themes;
if ( $interface eq "intranet" ) {
@themes = split " ", C4::Context->preference("template");
}
else {
# we are in the opac here, what im trying to do is let the individual user
# set the theme they want to use.
# and perhaps the them as well.
#my $lang = $query->cookie('KohaOpacLanguage');
@themes = split " ", C4::Context->preference("opacthemes");
}
# searches through the themes and languages. First template it find it returns.
# Priority is for getting the theme right.
THEME:
foreach my $th (@themes) {
foreach my $la (@languages) {
#for ( my $pass = 1 ; $pass <= 2 ; $pass += 1 ) {
# warn "$htdocs/$th/$la/modules/$interface-"."tmpl";
#$la =~ s/([-_])/ $1 eq '-'? '_': '-' /eg if $pass == 2;
if ( -e "$htdocs/$th/$la/modules/$tmpl") {
#".($interface eq 'intranet'?"modules":"")."/$tmpl" ) {
$theme = $th;
$lang = $la;
last THEME;
}
last unless $la =~ /[-_]/;
#}
}
}
$_current_language = $lang; # FIXME part of bad hack to paper over bug 4403
return ( $theme, $lang );
}
sub setlanguagecookie {
my ( $query, $language, $uri ) = @_;
my $cookie = $query->cookie(
-name => 'KohaOpacLanguage',
-value => $language,
-expires => ''
);
print $query->redirect(
-uri => $uri,
-cookie => $cookie
);
}
sub getlanguagecookie {
my ($query) = @_;
my $lang;
if ($query->cookie('KohaOpacLanguage')){
$lang = $query->cookie('KohaOpacLanguage') ;
}else{
$lang = $ENV{HTTP_ACCEPT_LANGUAGE};
}
$lang = substr($lang, 0, 2);
return $lang;
}
1;

View File

@ -29,7 +29,6 @@ use C4::Koha;
use C4::Biblio;
use C4::Circulation;
use C4::Reserves;
use C4::Output qw//;
use Encode;
use XML::LibXML;
use XML::LibXSLT;
@ -160,14 +159,14 @@ sub XSLTParse4Display {
if ($interface eq 'intranet') {
$xslfile = C4::Context->config('intrahtdocs') .
'/' . C4::Context->preference("template") .
'/' . C4::Output::_current_language() .
'/' . C4::Templates::_current_language() .
'/xslt/' .
C4::Context->preference('marcflavour') .
"slim2intranet$xsl_suffix.xsl";
} else {
$xslfile = C4::Context->config('opachtdocs') .
'/' . C4::Context->preference("opacthemes") .
'/' . C4::Output::_current_language() .
'/' . C4::Templates::_current_language() .
'/xslt/' .
C4::Context->preference('marcflavour') .
"slim2OPAC$xsl_suffix.xsl";

View File

@ -28,7 +28,7 @@ use LWP::Simple;
use XML::Simple;
use Config;
use C4::Output; # contains gettemplate
use C4::Output;
use C4::Auth;
use C4::Context;
use C4::Installer;

View File

@ -28,6 +28,7 @@ use C4::Languages qw(getTranslatedLanguages);
use C4::ClassSource;
use C4::Log;
use C4::Output;
use C4::Templates;
use C4::Budgets qw(GetCurrency);
use File::Spec;
use IO::File;
@ -41,7 +42,7 @@ our $lang;
sub GetTab {
my ( $input, $tab ) = @_;
my $tab_template = C4::Output::gettemplate( 'admin/preferences/' . $tab . '.pref', 'intranet', $input );
my $tab_template = C4::Templates::gettemplate( 'admin/preferences/' . $tab . '.pref', 'intranet', $input );
my $active_currency = GetCurrency();
my $local_currency;

View File

@ -27,7 +27,7 @@ use C4::Biblio;
use C4::Items;
use C4::Branch;
use C4::Acquisition;
use C4::Output; # contains gettemplate
use C4::Output;
use C4::Auth;
use C4::Serials;
use C4::Dates qw/format_date/;

View File

@ -471,7 +471,7 @@ my ( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit
my @results;
## I. BUILD THE QUERY
my $lang = C4::Output::getlanguagecookie($cgi);
my $lang = C4::Templates::getlanguagecookie($cgi);
( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$stopwords_removed,$query_type) = buildQuery(\@operators,\@operands,\@indexes,\@limits,\@sort_by,$scan,$lang);
## parse the query_cgi string and put it into a form suitable for <input>s

View File

@ -18,7 +18,7 @@
use strict;
use warnings;
use C4::Output qw(setlanguagecookie);
use C4::Templates;
use CGI;
my $query = new CGI;
@ -26,4 +26,4 @@ my $language = $query->param('language');
my $url = $query->referer();
#warn "Language : $query // $language // $url";
setlanguagecookie( $query, $language, $url );
C4::Templates::setlanguagecookie( $query, $language, $url );

View File

@ -103,7 +103,7 @@ InstallAuth - Authenticates Koha users for Install process
authenticated page.
More information on the C<gettemplate> sub can be found in the
Output.pm module.
Templates.pm module.
=cut

View File

@ -28,12 +28,12 @@ BEGIN {
eval { require "$FindBin::Bin/../kohalib.pl" };
}
use CGI; # NOT a CGI script, this is just to keep C4::Output::gettemplate happy
use CGI; # NOT a CGI script, this is just to keep C4::Templates::gettemplate happy
use C4::Context;
use C4::Dates;
use C4::Debug;
use C4::Letters;
use C4::Output;
use C4::Templates;
use File::Spec;
use Getopt::Long;
@ -70,7 +70,7 @@ exit unless( @messages );
open OUTPUT, '>', File::Spec->catdir( $output_directory, "holdnotices-" . $today->output( 'iso' ) . ".html" );
my $template = C4::Output::gettemplate( 'batch/print-notices.tmpl', 'intranet', new CGI );
my $template = C4::Templates::gettemplate( 'batch/print-notices.tmpl', 'intranet', new CGI );
my $stylesheet_contents = '';
if ($stylesheet) {

View File

@ -13,7 +13,6 @@ BEGIN {
}
use C4::Context;
use C4::Output; # contains gettemplate
use C4::Biblio;
use C4::Auth;
my $outfile = $ARGV[0];

View File

@ -17,7 +17,7 @@
use strict;
use warnings;
use C4::Output qw(setlanguagecookie);
use C4::Templates;
use CGI;
my $query = new CGI;
@ -25,4 +25,4 @@ my $language = $query->param('language');
my $url = $query->referer();
# warn "Language : $query // $language // $url";
setlanguagecookie( $query, $language, $url );
C4::Templates::setlanguagecookie( $query, $language, $url );

View File

@ -54,33 +54,7 @@ $template->param(
# display news
# use cookie setting for language, bug default to syspref if it's not set
(my $theme) = themelanguage(C4::Context->config('opachtdocs'),'opac-main.tmpl','opac',$input);
my $translations = getTranslatedLanguages('opac',$theme);
my @languages = ();
foreach my $trans (@$translations)
{
push(@languages, $trans->{rfc4646_subtag});
}
my $news_lang;
if($input->cookie('KohaOpacLanguage')){
$news_lang = $input->cookie('KohaOpacLanguage');
}else{
if ($ENV{HTTP_ACCEPT_LANGUAGE}) {
while( !$news_lang && ( $ENV{HTTP_ACCEPT_LANGUAGE} =~ m/([a-zA-Z]{2,}-?[a-zA-Z]*)(;|,)?/g ) ){
if( my @lang = grep { /^$1$/i } @languages ) {
$news_lang = $lang[0];
}
}
}
if (not $news_lang) {
my @languages = split ",", C4::Context->preference("opaclanguages");
$news_lang = $languages[0];
}
}
$news_lang = $news_lang ? $news_lang : 'en' ;
my ($theme, $news_lang) = 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;

View File

@ -373,7 +373,7 @@ my ($error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_
my @results;
## I. BUILD THE QUERY
my $lang = C4::Output::getlanguagecookie($cgi);
my $lang = C4::Templates::getlanguagecookie($cgi);
( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$stopwords_removed,$query_type) = buildQuery(\@operators,\@operands,\@indexes,\@limits,\@sort_by, 0, $lang);
sub _input_cgi_parse ($) {

View File

@ -20,7 +20,7 @@
use strict;
use warnings;
use C4::Auth;
use C4::Output; # contains gettemplate
use C4::Output;
use C4::Biblio; # GetMarcBiblio GetXmlBiblio
use CGI;
use C4::Koha; # GetItemTypes