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