Bugfix for Bug 1790: Theme defaults to prog if other themes fail.
[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
30 use C4::Context;
31 use C4::Languages qw(getTranslatedLanguages get_bidi regex_lang_subtags language_get_description accept_language );
32
33 use HTML::Template::Pro;
34 use vars qw($VERSION @ISA @EXPORT);
35
36 BEGIN {
37     # set the version for version checking
38     $VERSION = 3.01;
39     require Exporter;
40     @ISA    = qw(Exporter);
41     push @EXPORT, qw(
42         &themelanguage &gettemplate setlanguagecookie pagination_bar
43     );
44     push @EXPORT, qw(
45         &output_html_with_http_headers
46     );
47 }
48
49 =head1 NAME
50
51 C4::Output - Functions for managing templates
52
53 =head1 FUNCTIONS
54
55 =over 2
56
57 =cut
58
59 #FIXME: this is a quick fix to stop rc1 installing broken
60 #Still trying to figure out the correct fix.
61 my $path = C4::Context->config('intrahtdocs') . "/prog/en/includes/";
62
63 #---------------------------------------------------------------------------------------------------------
64 # FIXME - POD
65 sub gettemplate {
66     my ( $tmplbase, $interface, $query ) = @_;
67     ($query) or warn "no query in gettemplate";
68         warn "Template base is $tmplbase";
69     my $htdocs;
70     if ( $interface ne "intranet" ) {
71         $htdocs = C4::Context->config('opachtdocs');
72     }
73     else {
74         $htdocs = C4::Context->config('intrahtdocs');
75     }
76     my $path = C4::Context->preference('intranet_includes') || 'includes';
77
78     my ( $theme, $lang ) = themelanguage( $htdocs, $tmplbase, $interface, $query );
79     my $opacstylesheet = C4::Context->preference('opacstylesheet');
80
81     # if the template doesn't exist, load the English one as a last resort
82     my $filename = "$htdocs/$theme/$lang/modules/$tmplbase";
83     unless (-f $filename) {
84         $lang = 'en';
85         $filename = "$htdocs/$theme/$lang/modules/$tmplbase";
86     }
87     my $template       = HTML::Template::Pro->new(
88         filename          => $filename,
89         die_on_bad_params => 1,
90         global_vars       => 1,
91         case_sensitive    => 1,
92         path              => ["$htdocs/$theme/$lang/$path"]
93     );
94
95     $template->param(
96         themelang => ( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' )
97           . "/$theme/$lang",
98         interface => ( $interface ne 'intranet' ? '/opac-tmpl' : '/intranet-tmpl' ),
99         theme => $theme,
100         opacstylesheet      => $opacstylesheet,
101         opaccolorstylesheet => C4::Context->preference('opaccolorstylesheet'),
102         opacsmallimage      => C4::Context->preference('opacsmallimage'),
103         lang                => $lang
104     );
105
106     # Bidirectionality
107     my $current_lang = regex_lang_subtags($lang);
108     my $bidi;
109     $bidi = get_bidi($current_lang->{script}) if $current_lang->{script};
110     # Languages
111     my $languages_loop = getTranslatedLanguages($interface,$theme,$lang);
112     $template->param(
113             languages_loop => $languages_loop,
114             bidi => $bidi
115     ) unless @$languages_loop<2;
116
117     return $template;
118 }
119
120 #---------------------------------------------------------------------------------------------------------
121 # FIXME - POD
122 sub themelanguage {
123     my ( $htdocs, $tmpl, $interface, $query ) = @_;
124     ($query) or warn "no query in themelanguage";
125
126     # Set some defaults for language and theme
127     # First, check the user's preferences
128     my $lang;
129     my $http_accept_language = regex_lang_subtags($ENV{HTTP_ACCEPT_LANGUAGE})->{language};
130     if ($http_accept_language) {
131         $lang = accept_language($http_accept_language,getTranslatedLanguages($interface,'prog'));
132     } 
133     # But, if there's a cookie set, obey it
134     $lang = $query->cookie('KohaOpacLanguage') if $query->cookie('KohaOpacLanguage');
135     # Fall back to English
136     my @languages = split " ", C4::Context->preference("opaclanguages");
137     if ($lang){  
138         @languages=($lang,@languages);
139     } else {
140         $lang = $languages[0];
141     }      
142     my $theme = 'prog'; # in the event of theme failure default to 'prog' -fbcit
143     my $dbh = C4::Context->dbh;
144     my @themes;
145     if ( $interface eq "intranet" ) {
146         @themes    = split " ", C4::Context->preference("template");
147     }
148     else {
149       # we are in the opac here, what im trying to do is let the individual user
150       # set the theme they want to use.
151       # and perhaps the them as well.
152         #my $lang = $query->cookie('KohaOpacLanguage');
153         @themes = split " ", C4::Context->preference("opacthemes");
154     }
155
156  # searches through the themes and languages. First template it find it returns.
157  # Priority is for getting the theme right.
158     THEME:
159     foreach my $th (@themes) {
160         foreach my $la (@languages) {
161             #for ( my $pass = 1 ; $pass <= 2 ; $pass += 1 ) {
162                 # warn "$htdocs/$th/$la/modules/$interface-"."tmpl";
163                 #$la =~ s/([-_])/ $1 eq '-'? '_': '-' /eg if $pass == 2;
164                                 if ( -e "$htdocs/$th/$la/modules/$tmpl") {
165                 #".($interface eq 'intranet'?"modules":"")."/$tmpl" ) {
166                     $theme = $th;
167                     $lang  = $la;
168                     last THEME;
169                 }
170                 last unless $la =~ /[-_]/;
171             #}
172         }
173     }
174     return ( $theme, $lang );
175 }
176
177 sub setlanguagecookie {
178     my ( $query, $language, $uri ) = @_;
179     my $cookie = $query->cookie(
180         -name    => 'KohaOpacLanguage',
181         -value   => $language,
182         -expires => ''
183     );
184     print $query->redirect(
185         -uri    => $uri,
186         -cookie => $cookie
187     );
188 }
189
190 =item pagination_bar
191
192    pagination_bar($base_url, $nb_pages, $current_page, $startfrom_name)
193
194 Build an HTML pagination bar based on the number of page to display, the
195 current page and the url to give to each page link.
196
197 C<$base_url> is the URL for each page link. The
198 C<$startfrom_name>=page_number is added at the end of the each URL.
199
200 C<$nb_pages> is the total number of pages available.
201
202 C<$current_page> is the current page number. This page number won't become a
203 link.
204
205 This function returns HTML, without any language dependency.
206
207 =cut
208
209 sub pagination_bar {
210     my ( $base_url, $nb_pages, $current_page, $startfrom_name ) = @_;
211
212     # how many pages to show before and after the current page?
213     my $pages_around = 2;
214
215     my $url =
216       $base_url . ( $base_url =~ m/&/ ? '&amp;' : '?' ) . $startfrom_name . '=';
217
218     my $pagination_bar = '';
219
220     # current page detection
221     if ( not defined $current_page ) {
222         $current_page = 1;
223     }
224
225     # navigation bar useful only if more than one page to display !
226     if ( $nb_pages > 1 ) {
227
228         # link to first page?
229         if ( $current_page > 1 ) {
230             $pagination_bar .=
231                 "\n" . '&nbsp;'
232               . '<a href="'
233               . $url
234               . '1" rel="start">'
235               . '&lt;&lt;' . '</a>';
236         }
237         else {
238             $pagination_bar .=
239               "\n" . '&nbsp;<span class="inactive">&lt;&lt;</span>';
240         }
241
242         # link on previous page ?
243         if ( $current_page > 1 ) {
244             my $previous = $current_page - 1;
245
246             $pagination_bar .=
247                 "\n" . '&nbsp;'
248               . '<a href="'
249               . $url
250               . $previous
251               . '" rel="prev">' . '&lt;' . '</a>';
252         }
253         else {
254             $pagination_bar .=
255               "\n" . '&nbsp;<span class="inactive">&lt;</span>';
256         }
257
258         my $min_to_display      = $current_page - $pages_around;
259         my $max_to_display      = $current_page + $pages_around;
260         my $last_displayed_page = undef;
261
262         for my $page_number ( 1 .. $nb_pages ) {
263             if (
264                    $page_number == 1
265                 or $page_number == $nb_pages
266                 or (    $page_number >= $min_to_display
267                     and $page_number <= $max_to_display )
268               )
269             {
270                 if ( defined $last_displayed_page
271                     and $last_displayed_page != $page_number - 1 )
272                 {
273                     $pagination_bar .=
274                       "\n" . '&nbsp;<span class="inactive">...</span>';
275                 }
276
277                 if ( $page_number == $current_page ) {
278                     $pagination_bar .=
279                         "\n" . '&nbsp;'
280                       . '<span class="currentPage">'
281                       . $page_number
282                       . '</span>';
283                 }
284                 else {
285                     $pagination_bar .=
286                         "\n" . '&nbsp;'
287                       . '<a href="'
288                       . $url
289                       . $page_number . '">'
290                       . $page_number . '</a>';
291                 }
292                 $last_displayed_page = $page_number;
293             }
294         }
295
296         # link on next page?
297         if ( $current_page < $nb_pages ) {
298             my $next = $current_page + 1;
299
300             $pagination_bar .= "\n"
301               . '&nbsp;<a href="'
302               . $url
303               . $next
304               . '" rel="next">' . '&gt;' . '</a>';
305         }
306         else {
307             $pagination_bar .=
308               "\n" . '&nbsp;<span class="inactive">&gt;</span>';
309         }
310
311         # link to last page?
312         if ( $current_page != $nb_pages ) {
313             $pagination_bar .= "\n"
314               . '&nbsp;<a href="'
315               . $url
316               . $nb_pages
317               . '" rel="last">'
318               . '&gt;&gt;' . '</a>';
319         }
320         else {
321             $pagination_bar .=
322               "\n" . '&nbsp;<span class="inactive">&gt;&gt;</span>';
323         }
324     }
325
326     return $pagination_bar;
327 }
328
329 =item output_html_with_http_headers
330
331    &output_html_with_http_headers($query, $cookie, $html)
332
333 Outputs the HTML page $html with the appropriate HTTP headers,
334 with the authentication cookie $cookie and a Content-Type that
335 corresponds to the HTML page $html.
336
337 =cut
338
339 sub output_html_with_http_headers ($$$) {
340     my($query, $cookie, $html) = @_;
341     print $query->header(
342         -type    => 'text/html',
343         -charset => 'UTF-8',
344         -cookie  => $cookie,
345         -Pragma => 'no-cache',
346         -'Cache-Control' => 'no-cache',
347     ), $html;
348 }
349
350 END { }    # module clean-up code here (global destructor)
351
352 1;
353 __END__
354
355 =back
356
357 =head1 AUTHOR
358
359 Koha Developement team <info@koha.org>
360
361 =cut