template improvement: fall back on english if the template file doesn't exist
[koha.git] / C4 / Output.pm
1 package C4::Output;
2
3 #package to deal with marking up output
4 #You will need to edit parts of this pm
5 #set the value of path to be where your html lives
6
7 # Copyright 2000-2002 Katipo Communications
8 #
9 # This file is part of Koha.
10 #
11 # Koha is free software; you can redistribute it and/or modify it under the
12 # terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
14 # version.
15 #
16 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License along with
21 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
22 # Suite 330, Boston, MA  02111-1307 USA
23
24
25 # NOTE: I'm pretty sure this module is deprecated in favor of
26 # templates.
27
28 use strict;
29 require Exporter;
30
31 use C4::Context;
32 use C4::Languages qw(getTranslatedLanguages get_bidi regex_lang_subtags language_get_description);
33
34 use HTML::Template::Pro;
35 use vars qw($VERSION @ISA @EXPORT);
36
37 # set the version for version checking
38 $VERSION = 3.00;
39
40 =head1 NAME
41
42 C4::Output - Functions for managing templates
43
44 =head1 FUNCTIONS
45
46 =over 2
47
48 =cut
49
50 @ISA    = qw(Exporter);
51 push @EXPORT, qw(
52   &themelanguage &gettemplate setlanguagecookie pagination_bar
53 );
54
55 #Output
56 push @EXPORT, qw(
57     &output_html_with_http_headers
58 );
59
60
61 #FIXME: this is a quick fix to stop rc1 installing broken
62 #Still trying to figure out the correct fix.
63 my $path = C4::Context->config('intrahtdocs') . "/prog/en/includes/";
64
65 #---------------------------------------------------------------------------------------------------------
66 # FIXME - POD
67 sub gettemplate {
68     my ( $tmplbase, $interface, $query ) = @_;
69     if ( !$query ) {
70         warn "no query in gettemplate";
71     }
72     my $htdocs;
73     if ( $interface ne "intranet" ) {
74         $htdocs = C4::Context->config('opachtdocs');
75     }
76     else {
77         $htdocs = C4::Context->config('intrahtdocs');
78     }
79     my $path = C4::Context->preference('intranet_includes') || 'includes';
80
81     #    warn "PATH : $path";
82     my ( $theme, $lang ) = themelanguage( $htdocs, $tmplbase, $interface, $query );
83     my $opacstylesheet = C4::Context->preference('opacstylesheet');
84
85         # if the template doesn't exist, load the English one as a last resort
86         my $filename = "$htdocs/$theme/$lang/".($interface eq 'intranet'?"modules":"")."/$tmplbase";
87         unless (-f $filename) {
88                 $lang = 'en';
89                 $filename = "$htdocs/$theme/$lang/".($interface eq 'intranet'?"modules":"")."/$tmplbase";
90         }
91     my $template       = HTML::Template::Pro->new(
92                 filename          => $filename,
93         die_on_bad_params => 1,
94         global_vars       => 1,
95         case_sensitive    => 1,
96         path              => ["$htdocs/$theme/$lang/$path"]
97     );
98
99     $template->param(
100         themelang => ( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' )
101           . "/$theme/$lang",
102         interface => ( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' ),
103         theme => $theme,
104         opacstylesheet      => $opacstylesheet,
105         opaccolorstylesheet => C4::Context->preference('opaccolorstylesheet'),
106         opacsmallimage      => C4::Context->preference('opacsmallimage'),
107         lang                => $lang
108     );
109
110         # Language, Script, and Locale
111         my $language_subtags_hashref = regex_lang_subtags($lang);
112         my $bidi;
113         $bidi = get_bidi($language_subtags_hashref->{script}) if $language_subtags_hashref->{script};
114         my @template_languages;
115         my $languages_loop = getTranslatedLanguages($interface,$theme);
116         for my $language_hashref (@$languages_loop) {
117                         $language_hashref->{'language_script_description'} = language_get_description($language_hashref->{'language_script'},$lang);
118                         $language_hashref->{'language_region_description'} = language_get_description($language_hashref->{'language_region'},$lang);
119                         $language_hashref->{'language_variant_description'} = language_get_description($language_hashref->{'language_variant'},$lang);
120
121                 if ($language_hashref->{language_code} eq $language_subtags_hashref->{language}) {
122                         $language_hashref->{current}++;
123                 }
124                 push @template_languages, $language_hashref;
125         }
126         # load the languages ( for switching from one template to another )
127         $template->param(       languages_loop => \@template_languages,
128                                                 bidi => $bidi
129         );
130
131     return $template;
132 }
133
134 #---------------------------------------------------------------------------------------------------------
135 # FIXME - POD
136 sub themelanguage {
137     my ( $htdocs, $tmpl, $section, $query ) = @_;
138
139     #   if (!$query) {
140     #     warn "no query";
141     #   }
142
143         # set some defaults for language and theme
144         my $lang = $query->cookie('KohaOpacLanguage');
145         $lang = 'en' unless $lang;
146         my $theme = 'prog';
147
148     my $dbh = C4::Context->dbh;
149     my @languages;
150     my @themes;
151     if ( $section eq "intranet" ) {
152         @languages = split " ", C4::Context->preference("opaclanguages");
153         @themes    = split " ", C4::Context->preference("template");
154         pop @languages, $lang if $lang;
155     }
156     else {
157
158       # we are in the opac here, what im trying to do is let the individual user
159       # set the theme they want to use.
160       # and perhaps the them as well.
161         #my $lang = $query->cookie('KohaOpacLanguage');
162         if ($lang) {
163
164             push @languages, $lang;
165             @themes = split " ", C4::Context->preference("opacthemes");
166         }
167         else {
168             @languages = split " ", C4::Context->preference("opaclanguages");
169             @themes    = split " ", C4::Context->preference("opacthemes");
170         }
171     }
172
173  # searches through the themes and languages. First template it find it returns.
174  # Priority is for getting the theme right.
175   THEME:
176     foreach my $th (@themes) {
177         foreach my $la (@languages) {
178             for ( my $pass = 1 ; $pass <= 2 ; $pass += 1 ) {
179                 $la =~ s/([-_])/ $1 eq '-'? '_': '-' /eg if $pass == 2;
180                 if ( -e "$htdocs/$th/$la/modules/$tmpl" ) {
181                     $theme = $th;
182                     $lang  = $la;
183                     last THEME;
184                 }
185                 last unless $la =~ /[-_]/;
186             }
187         }
188     }
189     return ( $theme, $lang );
190 }
191
192 sub setlanguagecookie {
193     my ( $query, $language, $uri ) = @_;
194     my $cookie = $query->cookie(
195         -name    => 'KohaOpacLanguage',
196         -value   => $language,
197         -expires => ''
198     );
199     print $query->redirect(
200         -uri    => $uri,
201         -cookie => $cookie
202     );
203 }
204
205 =item pagination_bar
206
207    pagination_bar($base_url, $nb_pages, $current_page, $startfrom_name)
208
209 Build an HTML pagination bar based on the number of page to display, the
210 current page and the url to give to each page link.
211
212 C<$base_url> is the URL for each page link. The
213 C<$startfrom_name>=page_number is added at the end of the each URL.
214
215 C<$nb_pages> is the total number of pages available.
216
217 C<$current_page> is the current page number. This page number won't become a
218 link.
219
220 This function returns HTML, without any language dependency.
221
222 =cut
223
224 sub pagination_bar {
225     my ( $base_url, $nb_pages, $current_page, $startfrom_name ) = @_;
226
227     # how many pages to show before and after the current page?
228     my $pages_around = 2;
229
230     my $url =
231       $base_url . ( $base_url =~ m/&/ ? '&amp;' : '?' ) . $startfrom_name . '=';
232
233     my $pagination_bar = '';
234
235     # current page detection
236     if ( not defined $current_page ) {
237         $current_page = 1;
238     }
239
240     # navigation bar useful only if more than one page to display !
241     if ( $nb_pages > 1 ) {
242
243         # link to first page?
244         if ( $current_page > 1 ) {
245             $pagination_bar .=
246                 "\n" . '&nbsp;'
247               . '<a href="'
248               . $url
249               . '1" rel="start">'
250               . '&lt;&lt;' . '</a>';
251         }
252         else {
253             $pagination_bar .=
254               "\n" . '&nbsp;<span class="inactive">&lt;&lt;</span>';
255         }
256
257         # link on previous page ?
258         if ( $current_page > 1 ) {
259             my $previous = $current_page - 1;
260
261             $pagination_bar .=
262                 "\n" . '&nbsp;'
263               . '<a href="'
264               . $url
265               . $previous
266               . '" rel="prev">' . '&lt;' . '</a>';
267         }
268         else {
269             $pagination_bar .=
270               "\n" . '&nbsp;<span class="inactive">&lt;</span>';
271         }
272
273         my $min_to_display      = $current_page - $pages_around;
274         my $max_to_display      = $current_page + $pages_around;
275         my $last_displayed_page = undef;
276
277         for my $page_number ( 1 .. $nb_pages ) {
278             if (
279                    $page_number == 1
280                 or $page_number == $nb_pages
281                 or (    $page_number >= $min_to_display
282                     and $page_number <= $max_to_display )
283               )
284             {
285                 if ( defined $last_displayed_page
286                     and $last_displayed_page != $page_number - 1 )
287                 {
288                     $pagination_bar .=
289                       "\n" . '&nbsp;<span class="inactive">...</span>';
290                 }
291
292                 if ( $page_number == $current_page ) {
293                     $pagination_bar .=
294                         "\n" . '&nbsp;'
295                       . '<span class="currentPage">'
296                       . $page_number
297                       . '</span>';
298                 }
299                 else {
300                     $pagination_bar .=
301                         "\n" . '&nbsp;'
302                       . '<a href="'
303                       . $url
304                       . $page_number . '">'
305                       . $page_number . '</a>';
306                 }
307                 $last_displayed_page = $page_number;
308             }
309         }
310
311         # link on next page?
312         if ( $current_page < $nb_pages ) {
313             my $next = $current_page + 1;
314
315             $pagination_bar .= "\n"
316               . '&nbsp;<a href="'
317               . $url
318               . $next
319               . '" rel="next">' . '&gt;' . '</a>';
320         }
321         else {
322             $pagination_bar .=
323               "\n" . '&nbsp;<span class="inactive">&gt;</span>';
324         }
325
326         # link to last page?
327         if ( $current_page != $nb_pages ) {
328             $pagination_bar .= "\n"
329               . '&nbsp;<a href="'
330               . $url
331               . $nb_pages
332               . '" rel="last">'
333               . '&gt;&gt;' . '</a>';
334         }
335         else {
336             $pagination_bar .=
337               "\n" . '&nbsp;<span class="inactive">&gt;&gt;</span>';
338         }
339     }
340
341     return $pagination_bar;
342 }
343
344 =item output_html_with_http_headers
345
346    &output_html_with_http_headers($query, $cookie, $html)
347
348 Outputs the HTML page $html with the appropriate HTTP headers,
349 with the authentication cookie $cookie and a Content-Type that
350 corresponds to the HTML page $html.
351
352 =cut
353
354 sub output_html_with_http_headers ($$$) {
355     my($query, $cookie, $html) = @_;
356     print $query->header(
357         -type    => 'text/html',
358         -charset => 'UTF-8',
359         -cookie  => $cookie,
360                 -Pragma => 'no-cache',
361                 -'Cache-Control' => 'no-cache',
362     ), $html;
363 }
364
365 END { }    # module clean-up code here (global destructor)
366
367 1;
368 __END__
369
370 =back
371
372 =head1 AUTHOR
373
374 Koha Developement team <info@koha.org>
375
376 =cut