# ================================================================== # Gossamer Links - enhanced directory management system # # Website : http://gossamer-threads.com/ # Support : http://gossamer-threads.com/scripts/support/ # CVS Info : 087,071,086,086,085 # Revision : $Id: Utils.pm,v 1.61 2008/07/15 19:50:11 brewt Exp $ # # Copyright (c) 2001 Gossamer Threads Inc. All Rights Reserved. # Redistribution in part or in whole strictly prohibited. Please # see LICENSE file for full details. # ================================================================== package Links::Utils; # ================================================================== # This package contains some builtin functions useful in your templates. # use strict; use Links qw/$IN $DB $CFG $USER/; sub is_editor { # ------------------------------------------------------------------- # Returns true if the current user is an editor. # return unless $USER and $USER->{Status} ne 'Not Validated'; return $DB->table('Editors')->count({ Username => $USER->{Username} }); } sub load_editors { # ------------------------------------------------------------------- # You call this tag by placing <%Links::Utils::load_editors%> in your # category.html template. It will then make available an <%editors%> # tag that you can use in your template. For example: # <%Links::Utils::load_editors%> # <%if editors%> # The following users are editors in this category: <%editors%> # <%endif%> # my $vars = GT::Template->vars; my $cat_id = $vars->{category_id} or return "No category_id tag found! This tag can only be used on category.html template"; my $cat_db = $DB->table('Category'); my @parents = @{$cat_db->parents($cat_id)}; push @parents, $cat_id; my $ed_db = $DB->table('Editors', 'Users'); my $sth = $ed_db->select(GT::SQL::Condition->new('CategoryID', 'IN', \@parents)); return {} unless ($sth->rows); # Make any formatting changes you need here. my $output = '
',
style_prev => '
',
style_first => '
',
style_last => '
',
style_nonext => '
',
style_noprev => '
',
style_nofirst => '
',
style_nolast => '
',
lang_of => 'of',
lang_button => 'Go',
button_id => 'paging_button',
paging_pre => '',
paging_post => '',
%paging_options,
@_
);
# Make all the page calculations
$paging{num_pages} = int($paging{num_hits} / $paging{max_hits});
$paging{num_pages}++ if $paging{num_hits} % $paging{max_hits};
my ($start, $end);
if ($paging{num_pages} <= $options{max_pages}) {
$start = 1;
$end = $paging{num_pages};
}
elsif ($paging{current_page} >= $paging{num_pages} - $options{max_pages} / 2) {
$end = $paging{num_pages};
$start = $end - $options{max_pages} + 1;
}
elsif ($paging{current_page} <= $options{max_pages} / 2) {
$start = 1;
$end = $options{max_pages};
}
else {
$start = $paging{current_page} - int($options{max_pages} / 2) + 1;
$start-- if $options{max_pages} % 2;
$end = $paging{current_page} + int($options{max_pages} / 2);
}
my ($left_boundary, $right_boundary);
if ($end >= $paging{num_pages} - $options{boundary_pages} - 1) {
$end = $paging{num_pages};
}
else {
$right_boundary = 1;
}
if ($start <= $options{boundary_pages} + 2) {
$start = 1;
}
else {
$left_boundary = 1;
}
my @pages;
push @pages, 1 .. $options{boundary_pages}, '...' if $left_boundary;
push @pages, $start .. $end;
push @pages, '...', $paging{num_pages} - $options{boundary_pages} + 1 .. $paging{num_pages} if $right_boundary;
$paging{pages} = \@pages;
$paging{create_link} = sub {
my ($page, $disp) = @_;
my $ret = '';
$ret .= qq|{build_index_include} ? $CFG->{build_index} : '') : "$CFG->{build_more}$page$CFG->{build_extension}";
}
elsif ($paging{page_format} == 2) {
$ret .= "_$page" if $page > 1;
$ret .= $CFG->{build_extension};
}
}
$ret .= qq|">$disp|;
return $ret;
};
$paging{select_value} = sub {
my $page = shift;
if ($paging{url}) {
return $page;
}
else {
my $ret = $paging{page};
if ($paging{page_format} == 1) {
$ret .= $page == 1 ? ($CFG->{build_index_include} ? $CFG->{build_index} : '') : "$CFG->{build_more}$page$CFG->{build_extension}";
}
elsif ($paging{page_format} == 2) {
$ret .= "_$page" if $page > 1;
$ret .= $CFG->{build_extension};
}
return $ret;
}
};
if ($paging{url}) {
# Figure out what needs to be submitted with the form (it *should* have ? in it
# since with these queries, it *will* have other arguments)
($paging{form_action}, my $args) = $paging{url} =~ /^(.*?)\?(.*)$/;
NV: for (split /[;&]/, $args) {
my ($name, $val) = /([^=]+)=(.*)/ or next;
$name = $IN->unescape($name);
$val = $IN->unescape($val);
# Skip these since Links::clean_output will put them in automatically
for (@{$CFG->{dynamic_preserve}}, 'nh') {
next NV if $name eq $_;
}
$paging{form_hidden} .= qq||;
}
$paging{select_name} = 'nh';
}
else {
$paging{form_action} = "$CFG->{db_cgi_url}/page.cgi";
$paging{select_name} = 'g';
}
# Override this function. Pass in the updated %paging and %options hashes so
# the calculations don't have to be duplicated in the override.
if (ref $vars->{paging_override} eq 'CODE') {
return $vars->{paging_override}->(\%paging, \%options, @_);
}
my $html;
if ($options{style} == 1) {
# |< < [1 of 20] > >|
$html .= qq||;
}
elsif ($options{style} == 2) {
# [1 of 20] < >
$html .= qq||;
}
elsif ($options{style} == 3) {
# |< < 1 2 3 4 5 6 7 8 9 ... 20 > >|
$html .= $options{paging_pre};
if ($paging{current_page} != 1) {
$html .= $paging{create_link}->(1, $options{style_first}) . ' ' . $paging{create_link}->($paging{current_page} - 1, $options{style_prev}) . ' ';
}
else {
$html .= "$options{style_nofirst} $options{style_noprev} ";
}
for (@{$paging{pages}}) {
if ($_ eq '...') {
$html .= "$_ ";
}
elsif ($_ == $paging{current_page}) {
$html .= "$_ ";
}
else {
$html .= $paging{create_link}->($_, $_) . ' ';
}
}
if ($paging{current_page} != $paging{num_pages}) {
$html .= $paging{create_link}->($paging{current_page} + 1, $options{style_next}) . ' ' . $paging{create_link}->($paging{num_pages}, $options{style_last});
}
else {
$html .= "$options{style_nonext} $options{style_nolast}";
}
$html .= $options{paging_post};
}
return \$html;
}
sub format_title {
# -------------------------------------------------------------------
# Format a title
#
# Options:
# separator (required)
# The separator used to join the items.
# no_escape_separator
# Set this to a true value if you do not wish to HTML escape the separator.
# include_home
# Whether or not to include Home as the first entry. Default is no.
# include_last
# Whether or not to include the last entry. Default is yes.
# link_type
# How the items should be linked:
# 0: No items linked
# 1: All items linked separately
# 2: All except the last item linked separately
# 3: All items linked as one single link (using the last item's URL)
# no_span
# Don't add the span tags around the last portion of the title. Default is to include the span tags.
#
# Note: You can override this function by creating a format_title_override global
#
my ($title_loop, %options) = @_;
return unless ref $title_loop eq 'ARRAY';
my $vars = GT::Template->vars;
if (exists $vars->{format_title_override}) {
return $vars->{format_title_override}->(@_);
}
if (!exists $options{include_last}) {
$options{include_last} = 1;
}
if (!$options{include_last}) {
pop @$title_loop;
}
my $ret;
$options{separator} = GT::CGI::html_escape($options{separator}) unless $options{no_escape_separator};
for (0 .. $#$title_loop) {
next unless $_ or $options{include_home};
$ret .= '' if $_ == $#$title_loop and not $options{no_span} and $options{include_last};
if ($options{link_type} == 1 or
($options{link_type} == 2 and $_ != $#$title_loop)) {
$ret .= qq|$title_loop->[$_]->{Name}|;
}
else {
$ret .= $title_loop->[$_]->{Name};
}
$ret .= $options{separator} unless $_ == $#$title_loop;
$ret .= '' if $_ == $#$title_loop and not $options{no_span} and $options{include_last};
}
if ($options{link_type} == 3) {
$ret = qq|$ret|;
}
return \$ret;
}
sub column_split {
# -------------------------------------------------------------------
# Calculate where the columns should be
#
my ($items, $columns) = @_;
if ($items % $columns > 0) {
$items += ($columns - $items % $columns);
}
return $items / $columns;
}
sub image_url {
# -------------------------------------------------------------------
# Takes an filename and using the current template set and theme, returns
# the url of the image. It first checks if the file exists in the theme's
# image directory, checks the template's image directory, and then tries
# to check the template inheritance tree for more image directories.
#
my $image = shift;
my ($template, $theme) = Links::template_set();
if (-e "$CFG->{build_static_path}/$template/images/$theme/$image") {
return "$CFG->{build_static_url}/$template/images/$theme/$image";
}
# Grab the inheritance tree of the template set and grab the basename of
# each template set path (making an assumption that they won't do anything
# crazy with their inheritance).
require GT::File::Tools;
require GT::Template::Inheritance;
my @paths = GT::Template::Inheritance->tree(path => "$CFG->{admin_root_path}/templates/$template", local => 0);
for (@paths) {
my $tpl = GT::File::Tools::basename($_);
next if $tpl eq 'browser';
if (-e "$CFG->{build_static_path}/$tpl/images/$image") {
return "$CFG->{build_static_url}/$tpl/images/$image";
}
}
# The image doesn't exist here, but return it anyway
return "$CFG->{build_static_url}/$template/images/$image";
}
1;