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