charset: fixed bug that prevented ISO-5426 conversion
[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'; # in the event of theme failure default to 'prog' -fbcit
142     my $dbh = C4::Context->dbh;
143     my @themes;
144     if ( $interface eq "intranet" ) {
145         @themes    = split " ", C4::Context->preference("template");
146     }
147     else {
148       # we are in the opac here, what im trying to do is let the individual user
149       # set the theme they want to use.
150       # and perhaps the them as well.
151         #my $lang = $query->cookie('KohaOpacLanguage');
152         @themes = split " ", C4::Context->preference("opacthemes");
153     }
154
155  # searches through the themes and languages. First template it find it returns.
156  # Priority is for getting the theme right.
157     THEME:
158     foreach my $th (@themes) {
159         foreach my $la (@languages) {
160             #for ( my $pass = 1 ; $pass <= 2 ; $pass += 1 ) {
161                 # warn "$htdocs/$th/$la/modules/$interface-"."tmpl";
162                 #$la =~ s/([-_])/ $1 eq '-'? '_': '-' /eg if $pass == 2;
163                                 if ( -e "$htdocs/$th/$la/modules/$tmpl") {
164                 #".($interface eq 'intranet'?"modules":"")."/$tmpl" ) {
165                     $theme = $th;
166                     $lang  = $la;
167                     last THEME;
168                 }
169                 last unless $la =~ /[-_]/;
170             #}
171         }
172     }
173     return ( $theme, $lang );
174 }
175
176 sub setlanguagecookie {
177     my ( $query, $language, $uri ) = @_;
178     my $cookie = $query->cookie(
179         -name    => 'KohaOpacLanguage',
180         -value   => $language,
181         -expires => ''
182     );
183     print $query->redirect(
184         -uri    => $uri,
185         -cookie => $cookie
186     );
187 }
188
189 =item pagination_bar
190
191    pagination_bar($base_url, $nb_pages, $current_page, $startfrom_name)
192
193 Build an HTML pagination bar based on the number of page to display, the
194 current page and the url to give to each page link.
195
196 C<$base_url> is the URL for each page link. The
197 C<$startfrom_name>=page_number is added at the end of the each URL.
198
199 C<$nb_pages> is the total number of pages available.
200
201 C<$current_page> is the current page number. This page number won't become a
202 link.
203
204 This function returns HTML, without any language dependency.
205
206 =cut
207
208 sub pagination_bar {
209     my ( $base_url, $nb_pages, $current_page, $startfrom_name ) = @_;
210
211     # how many pages to show before and after the current page?
212     my $pages_around = 2;
213
214     my $url =
215       $base_url . ( $base_url =~ m/&/ ? '&amp;' : '?' ) . $startfrom_name . '=';
216
217     my $pagination_bar = '';
218
219     # current page detection
220     if ( not defined $current_page ) {
221         $current_page = 1;
222     }
223
224     # navigation bar useful only if more than one page to display !
225     if ( $nb_pages > 1 ) {
226
227         # link to first page?
228         if ( $current_page > 1 ) {
229             $pagination_bar .=
230                 "\n" . '&nbsp;'
231               . '<a href="'
232               . $url
233               . '1" rel="start">'
234               . '&lt;&lt;' . '</a>';
235         }
236         else {
237             $pagination_bar .=
238               "\n" . '&nbsp;<span class="inactive">&lt;&lt;</span>';
239         }
240
241         # link on previous page ?
242         if ( $current_page > 1 ) {
243             my $previous = $current_page - 1;
244
245             $pagination_bar .=
246                 "\n" . '&nbsp;'
247               . '<a href="'
248               . $url
249               . $previous
250               . '" rel="prev">' . '&lt;' . '</a>';
251         }
252         else {
253             $pagination_bar .=
254               "\n" . '&nbsp;<span class="inactive">&lt;</span>';
255         }
256
257         my $min_to_display      = $current_page - $pages_around;
258         my $max_to_display      = $current_page + $pages_around;
259         my $last_displayed_page = undef;
260
261         for my $page_number ( 1 .. $nb_pages ) {
262             if (
263                    $page_number == 1
264                 or $page_number == $nb_pages
265                 or (    $page_number >= $min_to_display
266                     and $page_number <= $max_to_display )
267               )
268             {
269                 if ( defined $last_displayed_page
270                     and $last_displayed_page != $page_number - 1 )
271                 {
272                     $pagination_bar .=
273                       "\n" . '&nbsp;<span class="inactive">...</span>';
274                 }
275
276                 if ( $page_number == $current_page ) {
277                     $pagination_bar .=
278                         "\n" . '&nbsp;'
279                       . '<span class="currentPage">'
280                       . $page_number
281                       . '</span>';
282                 }
283                 else {
284                     $pagination_bar .=
285                         "\n" . '&nbsp;'
286                       . '<a href="'
287                       . $url
288                       . $page_number . '">'
289                       . $page_number . '</a>';
290                 }
291                 $last_displayed_page = $page_number;
292             }
293         }
294
295         # link on next page?
296         if ( $current_page < $nb_pages ) {
297             my $next = $current_page + 1;
298
299             $pagination_bar .= "\n"
300               . '&nbsp;<a href="'
301               . $url
302               . $next
303               . '" rel="next">' . '&gt;' . '</a>';
304         }
305         else {
306             $pagination_bar .=
307               "\n" . '&nbsp;<span class="inactive">&gt;</span>';
308         }
309
310         # link to last page?
311         if ( $current_page != $nb_pages ) {
312             $pagination_bar .= "\n"
313               . '&nbsp;<a href="'
314               . $url
315               . $nb_pages
316               . '" rel="last">'
317               . '&gt;&gt;' . '</a>';
318         }
319         else {
320             $pagination_bar .=
321               "\n" . '&nbsp;<span class="inactive">&gt;&gt;</span>';
322         }
323     }
324
325     return $pagination_bar;
326 }
327
328 =item output_html_with_http_headers
329
330    &output_html_with_http_headers($query, $cookie, $html)
331
332 Outputs the HTML page $html with the appropriate HTTP headers,
333 with the authentication cookie $cookie and a Content-Type that
334 corresponds to the HTML page $html.
335
336 =cut
337
338 sub output_html_with_http_headers ($$$) {
339     my($query, $cookie, $html) = @_;
340     print $query->header(
341         -type    => 'text/html',
342         -charset => 'UTF-8',
343         -cookie  => $cookie,
344         -Pragma => 'no-cache',
345         -'Cache-Control' => 'no-cache',
346     ), $html;
347 }
348
349 END { }    # module clean-up code here (global destructor)
350
351 1;
352 __END__
353
354 =back
355
356 =head1 AUTHOR
357
358 Koha Developement team <info@koha.org>
359
360 =cut