Bug 14586 - Update about page with new 3.18 release team
[koha.git] / C4 / Output.pm
blobb16914074081d4af5ef1698fb598ec10bd78cf9c
1 package C4::Output;
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
7 # Copyright 2000-2002 Katipo Communications
9 # This file is part of Koha.
11 # Koha is free software; you can redistribute it and/or modify it
12 # under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 3 of the License, or
14 # (at your option) any later version.
16 # Koha is distributed in the hope that it will be useful, but
17 # WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with Koha; if not, see <http://www.gnu.org/licenses>.
25 # NOTE: I'm pretty sure this module is deprecated in favor of
26 # templates.
28 use strict;
29 #use warnings; FIXME - Bug 2505
31 use URI::Escape;
33 use C4::Context;
34 use C4::Dates qw(format_date);
35 use C4::Budgets qw(GetCurrency);
36 use C4::Templates;
38 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
40 BEGIN {
41 # set the version for version checking
42 $VERSION = 3.07.00.049;
43 require Exporter;
45 @ISA = qw(Exporter);
46 @EXPORT_OK = qw(&is_ajax ajax_fail); # More stuff should go here instead
47 %EXPORT_TAGS = ( all =>[qw(setlanguagecookie pagination_bar parametrized_url
48 &output_with_http_headers &output_ajax_with_http_headers &output_html_with_http_headers)],
49 ajax =>[qw(&output_with_http_headers &output_ajax_with_http_headers is_ajax)],
50 html =>[qw(&output_with_http_headers &output_html_with_http_headers)]
52 push @EXPORT, qw(
53 setlanguagecookie getlanguagecookie pagination_bar parametrized_url
55 push @EXPORT, qw(
56 &output_html_with_http_headers &output_ajax_with_http_headers &output_with_http_headers FormatData
61 =head1 NAME
63 C4::Output - Functions for managing output, is slowly being deprecated
65 =head1 FUNCTIONS
67 =over 2
68 =cut
70 =item FormatData
72 FormatData($data_hashref)
73 C<$data_hashref> is a ref to data to format
75 Format dates of data those dates are assumed to contain date in their noun
76 Could be used in order to centralize all the formatting for HTML output
77 =cut
79 sub FormatData{
80 my $data_hashref=shift;
81 $$data_hashref{$_} = format_date( $$data_hashref{$_} ) for grep{/date/} keys (%$data_hashref);
84 =item pagination_bar
86 pagination_bar($base_url, $nb_pages, $current_page, $startfrom_name)
88 Build an HTML pagination bar based on the number of page to display, the
89 current page and the url to give to each page link.
91 C<$base_url> is the URL for each page link. The
92 C<$startfrom_name>=page_number is added at the end of the each URL.
94 C<$nb_pages> is the total number of pages available.
96 C<$current_page> is the current page number. This page number won't become a
97 link.
99 This function returns HTML, without any language dependency.
101 =cut
103 sub pagination_bar {
104 my $base_url = (@_ ? shift : $ENV{SCRIPT_NAME} . $ENV{QUERY_STRING}) or return;
105 my $nb_pages = (@_) ? shift : 1;
106 my $current_page = (@_) ? shift : undef; # delay default until later
107 my $startfrom_name = (@_) ? shift : 'page';
109 # how many pages to show before and after the current page?
110 my $pages_around = 2;
112 my $delim = qr/\&(?:amp;)?|;/; # "non memory" cluster: no backreference
113 $base_url =~ s/$delim*\b$startfrom_name=(\d+)//g; # remove previous pagination var
114 unless (defined $current_page and $current_page > 0 and $current_page <= $nb_pages) {
115 $current_page = ($1) ? $1 : 1; # pull current page from param in URL, else default to 1
116 # $debug and # FIXME: use C4::Debug;
117 # warn "with QUERY_STRING:" .$ENV{QUERY_STRING}. "\ncurrent_page:$current_page\n1:$1 2:$2 3:$3";
119 $base_url =~ s/($delim)+/$1/g; # compress duplicate delims
120 $base_url =~ s/$delim;//g; # remove empties
121 $base_url =~ s/$delim$//; # remove trailing delim
123 my $url = $base_url . (($base_url =~ m/$delim/ or $base_url =~ m/\?/) ? '&amp;' : '?' ) . $startfrom_name . '=';
124 my $pagination_bar = '';
126 # navigation bar useful only if more than one page to display !
127 if ( $nb_pages > 1 ) {
129 # link to first page?
130 if ( $current_page > 1 ) {
131 $pagination_bar .=
132 "\n" . '&nbsp;'
133 . '<a href="'
134 . $url
135 . '1" rel="start">'
136 . '&lt;&lt;' . '</a>';
138 else {
139 $pagination_bar .=
140 "\n" . '&nbsp;<span class="inactive">&lt;&lt;</span>';
143 # link on previous page ?
144 if ( $current_page > 1 ) {
145 my $previous = $current_page - 1;
147 $pagination_bar .=
148 "\n" . '&nbsp;'
149 . '<a href="'
150 . $url
151 . $previous
152 . '" rel="prev">' . '&lt;' . '</a>';
154 else {
155 $pagination_bar .=
156 "\n" . '&nbsp;<span class="inactive">&lt;</span>';
159 my $min_to_display = $current_page - $pages_around;
160 my $max_to_display = $current_page + $pages_around;
161 my $last_displayed_page = undef;
163 for my $page_number ( 1 .. $nb_pages ) {
164 if (
165 $page_number == 1
166 or $page_number == $nb_pages
167 or ( $page_number >= $min_to_display
168 and $page_number <= $max_to_display )
171 if ( defined $last_displayed_page
172 and $last_displayed_page != $page_number - 1 )
174 $pagination_bar .=
175 "\n" . '&nbsp;<span class="inactive">...</span>';
178 if ( $page_number == $current_page ) {
179 $pagination_bar .=
180 "\n" . '&nbsp;'
181 . '<span class="currentPage">'
182 . $page_number
183 . '</span>';
185 else {
186 $pagination_bar .=
187 "\n" . '&nbsp;'
188 . '<a href="'
189 . $url
190 . $page_number . '">'
191 . $page_number . '</a>';
193 $last_displayed_page = $page_number;
197 # link on next page?
198 if ( $current_page < $nb_pages ) {
199 my $next = $current_page + 1;
201 $pagination_bar .= "\n"
202 . '&nbsp;<a href="'
203 . $url
204 . $next
205 . '" rel="next">' . '&gt;' . '</a>';
207 else {
208 $pagination_bar .=
209 "\n" . '&nbsp;<span class="inactive">&gt;</span>';
212 # link to last page?
213 if ( $current_page != $nb_pages ) {
214 $pagination_bar .= "\n"
215 . '&nbsp;<a href="'
216 . $url
217 . $nb_pages
218 . '" rel="last">'
219 . '&gt;&gt;' . '</a>';
221 else {
222 $pagination_bar .=
223 "\n" . '&nbsp;<span class="inactive">&gt;&gt;</span>';
227 return $pagination_bar;
230 =item output_with_http_headers
232 &output_with_http_headers($query, $cookie, $data, $content_type[, $status[, $extra_options]])
234 Outputs $data with the appropriate HTTP headers,
235 the authentication cookie $cookie and a Content-Type specified in
236 $content_type.
238 If applicable, $cookie can be undef, and it will not be sent.
240 $content_type is one of the following: 'html', 'js', 'json', 'xml', 'rss', or 'atom'.
242 $status is an HTTP status message, like '403 Authentication Required'. It defaults to '200 OK'.
244 $extra_options is hashref. If the key 'force_no_caching' is present and has
245 a true value, the HTTP headers include directives to force there to be no
246 caching whatsoever.
248 =cut
250 sub output_with_http_headers {
251 my ( $query, $cookie, $data, $content_type, $status, $extra_options ) = @_;
252 $status ||= '200 OK';
254 $extra_options //= {};
256 my %content_type_map = (
257 'html' => 'text/html',
258 'js' => 'text/javascript',
259 'json' => 'application/json',
260 'xml' => 'text/xml',
261 # NOTE: not using application/atom+xml or application/rss+xml because of
262 # Internet Explorer 6; see bug 2078.
263 'rss' => 'text/xml',
264 'atom' => 'text/xml'
267 die "Unknown content type '$content_type'" if ( !defined( $content_type_map{$content_type} ) );
268 my $cache_policy = 'no-cache';
269 $cache_policy .= ', no-store, max-age=0' if $extra_options->{force_no_caching};
270 my $options = {
271 type => $content_type_map{$content_type},
272 status => $status,
273 charset => 'UTF-8',
274 Pragma => 'no-cache',
275 'Cache-Control' => $cache_policy,
277 $options->{expires} = 'now' if $extra_options->{force_no_caching};
279 $options->{cookie} = $cookie if $cookie;
280 if ($content_type eq 'html') { # guaranteed to be one of the content_type_map keys, else we'd have died
281 $options->{'Content-Style-Type' } = 'text/css';
282 $options->{'Content-Script-Type'} = 'text/javascript';
285 # We can't encode here, that will double encode our templates, and xslt
286 # We need to fix the encoding as it comes out of the database, or when we pass the variables to templates
288 # utf8::encode($data) if utf8::is_utf8($data);
290 $data =~ s/\&amp\;amp\; /\&amp\; /g;
291 print $query->header($options), $data;
294 sub output_html_with_http_headers {
295 my ( $query, $cookie, $data, $status, $extra_options ) = @_;
296 output_with_http_headers( $query, $cookie, $data, 'html', $status, $extra_options );
300 sub output_ajax_with_http_headers {
301 my ( $query, $js ) = @_;
302 print $query->header(
303 -type => 'text/javascript',
304 -charset => 'UTF-8',
305 -Pragma => 'no-cache',
306 -'Cache-Control' => 'no-cache',
307 -expires => '-1d',
308 ), $js;
311 sub is_ajax {
312 my $x_req = $ENV{HTTP_X_REQUESTED_WITH};
313 return ( $x_req and $x_req =~ /XMLHttpRequest/i ) ? 1 : 0;
316 sub parametrized_url {
317 my $url = shift || ''; # ie page.pl?ln={LANG}
318 my $vars = shift || {}; # ie { LANG => en }
319 my $ret = $url;
320 while ( my ($key,$val) = each %$vars) {
321 my $val_url = URI::Escape::uri_escape_utf8($val);
322 $ret =~ s/\{$key\}/$val_url/g;
324 $ret =~ s/\{[^\{]*\}//g; # remove not defined vars
325 return $ret;
328 END { } # module clean-up code here (global destructor)
331 __END__
333 =back
335 =head1 AUTHOR
337 Koha Development Team <http://koha-community.org/>
339 =cut