586 lines
23 KiB
Perl
586 lines
23 KiB
Perl
# ==================================================================
|
|
# 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 = '<ul>';
|
|
my @editors;
|
|
my %seen;
|
|
while (my $user = $sth->fetchrow_hashref) {
|
|
next if ($seen{$user->{Username}}++);
|
|
$output .= qq|<li>$user->{Username}</li>|;
|
|
push @editors, $user;
|
|
}
|
|
$output .= "</ul>";
|
|
return { editors => $output, editors_loop => \@editors };
|
|
}
|
|
|
|
sub load_user {
|
|
# -------------------------------------------------------------------
|
|
# You call this tag in your link.html or detailed.html template. It will
|
|
# provide all the information about the user who owns the link, and also
|
|
# create a Contact_Name and Contact_Email tag for backwards compatibility.
|
|
# So you would put:
|
|
# <%Links::Utils::load_user%>
|
|
# This link is owned by <%Username%>, whose email is <%Email%>
|
|
# and password is <%Password%>. They are a <%Status%> user.
|
|
#
|
|
my $vars = GT::Template->vars;
|
|
my $username = $vars->{LinkOwner} or return "No LinkOwner tag found! This tag can only be used on link.html or detailed.html templates.";
|
|
require Links::Authenticate;
|
|
my $user_r = Links::Authenticate->auth('get_user', { Username => $username } );
|
|
return $user_r;
|
|
}
|
|
|
|
sub load_reviews {
|
|
# -------------------------------------------------------------------
|
|
# You call this tag in link.html or detailed.html template. It will
|
|
# load all the reviews associated with this link.
|
|
# So you would put:
|
|
# <%Links::Utils::load_reviews($ID, $max_reviews)%>
|
|
# This link has <%Review_Total%> reviews.
|
|
# <%loop Reviews_Loop%><%Review_Subject%> - <%Review_ByLine%><%endloop%>
|
|
# Review_Count is a deprecated backwards compatible variable
|
|
#
|
|
my ($id, $max) = @_;
|
|
unless ($id) {
|
|
my $vars = GT::Template->vars;
|
|
$id = $vars->{ID};
|
|
}
|
|
my $reviews = $DB->table('Reviews');
|
|
if ($CFG->{review_sort_by}) {
|
|
my $order = $CFG->{review_sort_order} || 'DESC';
|
|
$reviews->select_options("ORDER BY $CFG->{review_sort_by} $order");
|
|
}
|
|
if ($max and $max =~ /^\d+$/) {
|
|
$reviews->select_options("LIMIT $max");
|
|
}
|
|
my $review_total = $reviews->count({ Review_LinkID => $id, Review_Validated => 'Yes' });
|
|
my $sth = $reviews->select({ Review_LinkID => $id, Review_Validated => 'Yes' });
|
|
my @reviews;
|
|
Links::init_date();
|
|
require Links::User::Review;
|
|
my $today = GT::Date::date_get();
|
|
while (my $rev = $sth->fetchrow_hashref) {
|
|
$rev->{Review_IsNew} = (GT::Date::date_diff($today, $rev->{Review_Date}) < $CFG->{review_days_old});
|
|
$rev->{Review_CanModify} = 0;
|
|
if ($CFG->{review_allow_modify} and $USER->{Username} eq $rev->{Review_Owner}) {
|
|
if ($CFG->{review_modify_timeout}) {
|
|
my $oldfmt = GT::Date::date_get_format();
|
|
GT::Date::date_set_format(GT::Date::FORMAT_DATETIME);
|
|
my $timeout = GT::Date::date_get(time - $CFG->{review_modify_timeout} * 60);
|
|
my $date = $rev->{Review_ModifyDate} =~ /^0000-00-00 00:00:00/ ? $rev->{Review_Date} : $rev->{Review_ModifyDate};
|
|
if (GT::Date::date_is_greater($date, $timeout)) {
|
|
$rev->{Review_CanModify} = 1;
|
|
}
|
|
GT::Date::date_set_format($oldfmt);
|
|
}
|
|
else {
|
|
$rev->{Review_CanModify} = 1;
|
|
}
|
|
}
|
|
if ($rev->{Review_ModifyDate} ne $rev->{Review_Date} and $rev->{Review_ModifyDate} !~ /^0000-00-00 00:00:00/) {
|
|
$rev->{Review_ModifyDate} = GT::Date::date_transform($rev->{Review_ModifyDate}, GT::Date::FORMAT_DATETIME, $CFG->{date_review_format});
|
|
}
|
|
else {
|
|
delete $rev->{Review_ModifyDate};
|
|
}
|
|
$rev->{Review_Date} = GT::Date::date_transform($rev->{Review_Date}, GT::Date::FORMAT_DATETIME, $CFG->{date_review_format});
|
|
$rev->{Num} = $rev->{Review_WasHelpful} + $rev->{Review_WasNotHelpful};
|
|
$CFG->{review_convert_br_tags} and $rev->{Review_Contents} = Links::User::Review::_translate_html($rev->{Review_Contents});
|
|
push @reviews, $rev;
|
|
}
|
|
|
|
return { Review_Total => $review_total, Review_Count => scalar @reviews, Review_Loop => \@reviews };
|
|
}
|
|
|
|
sub load_link {
|
|
# -------------------------------------------------------------------
|
|
# This will return a fully formatted link. Deprecated in favour of
|
|
# using load_link_info() + <%include link.html%>
|
|
#
|
|
my %vars = %{GT::Template->vars};
|
|
if ($Links::GLOBALS) {
|
|
delete @vars{keys %$Links::GLOBALS};
|
|
}
|
|
return Links::SiteHTML::display('link', \%vars);
|
|
}
|
|
|
|
sub load_link_info {
|
|
# -------------------------------------------------------------------
|
|
# This will return the vars needed to display a fully formatted link (i.e. by
|
|
# including link.html)
|
|
#
|
|
return Links::SiteHTML::tags(link => GT::Template->vars);
|
|
}
|
|
|
|
sub paging {
|
|
# -------------------------------------------------------------------
|
|
# Generate the html needed for a paging toolbar
|
|
#
|
|
# The paging hash (retrieved from vars) should contain:
|
|
# url
|
|
# page
|
|
# Only one of url or page should be included.
|
|
# url is used when the generated url will be <%url%>;nh=<%page_number%>
|
|
# page is used when the generated url will be <%build_root_url%>/<%page%>...
|
|
# page_format
|
|
# 1: <%build_root_url%>/<%page%>{index,more<%current_page%>}.html
|
|
# Used in category, cool, new pages
|
|
# 2: <%build_root_url%>/<%page%>{,_<%current_page%>}.html
|
|
# Used in new page
|
|
# num_hits
|
|
# max_hits
|
|
# current_page
|
|
#
|
|
# Options:
|
|
# max_pages
|
|
# The maximum number of pages to display (excluding boundary pages)
|
|
# boundary_pages
|
|
# When there are more pages than max_pages, this number of boundary
|
|
# pages are added to the paging toolbar
|
|
# style
|
|
# 1: |< < [1 of 20] > >|
|
|
# 2: [1 of 20] < >
|
|
# 3: |< < 1 2 3 4 5 6 7 8 9 ... 20 > >|
|
|
# style_next
|
|
# style_prev
|
|
# style_first
|
|
# style_last
|
|
# style_nonext
|
|
# style_noprev
|
|
# style_nofirst
|
|
# style_nolast
|
|
# These options allow you to change what's shown for the next/prev/etc
|
|
# actions
|
|
# lang_of
|
|
# For styles 1 and 2, they use the format of "<page> <lang_of> <page>".
|
|
# This option allows you to change the english text of "of".
|
|
# lang_button
|
|
# For styles 1 and 2, a "Go" button is used for users which do not have
|
|
# javascript support. This option allows you to change the button's
|
|
# label.
|
|
# button_id
|
|
# If you've got two paging toolbars on a page, then you will need to
|
|
# change the button_id so that the javascript can remove the button.
|
|
# paging_pre
|
|
# paging_post
|
|
# This text or html is added before and after the paging html.
|
|
#
|
|
# There are two ways of setting the above options:
|
|
# 1) Pass them in as arguments
|
|
# 2) Create a global code ref named 'paging_options' and return the options
|
|
# as a hash reference
|
|
# Options passed as arguments override all options passed in via other methods,
|
|
# followed by the global options and lastly the defaults contained in this
|
|
# function.
|
|
#
|
|
# Note 1: You can override this function by creating a paging_override global
|
|
# Note 2: The arguments to paging_override are slightly different. To keep
|
|
# duplicated code to a minimum, %paging with the paging calculations done
|
|
# is passed as the first argument (it also contains a few helper code
|
|
# refs), and the second argument contains the options with defaults set.
|
|
# The left over arguments are the passed in options (shouldn't be needed
|
|
# since they have been merged into the options already).
|
|
#
|
|
my $vars = GT::Template->vars;
|
|
|
|
return unless ref $vars->{paging} eq 'HASH';
|
|
my %paging = %{$vars->{paging}};
|
|
return if not $paging{num_hits} or $paging{num_hits} < $paging{max_hits};
|
|
|
|
%paging = (
|
|
page_format => 1,
|
|
current_page => 1,
|
|
form_hidden => '',
|
|
%paging
|
|
);
|
|
|
|
# Setup the default options
|
|
my %paging_options;
|
|
%paging_options = %{$vars->{paging_options}->()} if ref $vars->{paging_options} eq 'CODE';
|
|
my %options = (
|
|
max_pages => 10,
|
|
boundary_pages => 1,
|
|
style => 1,
|
|
style_next => '<img src="' . image_url('paging-next.gif') . '" alt=">" title="Next Page" />',
|
|
style_prev => '<img src="' . image_url('paging-prev.gif') . '" alt="<" title="Previous Page" />',
|
|
style_first => '<img src="' . image_url('paging-first.gif') . '" alt="|<" title="First Page" />',
|
|
style_last => '<img src="' . image_url('paging-last.gif') . '" alt=">|" title="Last Page" />',
|
|
style_nonext => '<img src="' . image_url('paging-nonext.gif') . '" alt="" />',
|
|
style_noprev => '<img src="' . image_url('paging-noprev.gif') . '" alt="" />',
|
|
style_nofirst => '<img src="' . image_url('paging-nofirst.gif') . '" alt="" />',
|
|
style_nolast => '<img src="' . image_url('paging-nolast.gif') . '" alt="" />',
|
|
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|<a href="|;
|
|
|
|
if ($paging{url}) {
|
|
(my $url = $paging{url}) =~ s/([;&?]?)nh=(\d+)/($1 and $1 eq '?') ? '?' : ''/eg;
|
|
$ret .= $url;
|
|
$ret .= index($url, '?') != -1 ? ';' : '?';
|
|
$ret .= "nh=$page";
|
|
}
|
|
else {
|
|
$ret .= "$CFG->{build_root_url}/$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};
|
|
}
|
|
}
|
|
$ret .= qq|">$disp</a>|;
|
|
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|<input type="hidden" name="| . $IN->html_escape($name) . qq|" value="| . $IN->html_escape($val) . 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|<form action="$paging{form_action}">$paging{form_hidden}$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} ";
|
|
}
|
|
|
|
$html .= qq|<select name="$paging{select_name}" onchange="if (this.options[this.selectedIndex].innerHTML != '...' && !this.options[this.selectedIndex].defaultSelected) |;
|
|
$html .= $IN->param('d') || $paging{url} ? qq|this.form.submit()| : qq|window.location = '$CFG->{build_root_url}/' + this.value|;
|
|
$html .= qq|">|;
|
|
for (@{$paging{pages}}) {
|
|
if ($_ eq '...') {
|
|
$html .= qq|<option value="" disabled="disabled">...</option>|;
|
|
}
|
|
else {
|
|
$html .= qq|<option value="| . $paging{select_value}->($_) . '"';
|
|
$html .= qq| selected="selected"| if $_ == $paging{current_page};
|
|
$html .= qq|>$_ $options{lang_of} $paging{num_pages}</option>|;
|
|
}
|
|
}
|
|
$html .= qq|</select><noscript><input type="submit" id="$options{button_id}" value="$options{lang_button}" class="submit" /></noscript> |;
|
|
|
|
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 .= qq|$options{paging_post}</form>|;
|
|
}
|
|
elsif ($options{style} == 2) {
|
|
# [1 of 20] < >
|
|
$html .= qq|<form action="$paging{form_action}">$paging{form_hidden}$options{paging_pre}<select name="$paging{select_name}" onchange="if (this.options[this.selectedIndex].innerHTML != '...' && !this.options[this.selectedIndex].defaultSelected) |;
|
|
$html .= $IN->param('d') || $paging{url} ? qq|this.form.submit()| : qq|window.location = '$CFG->{build_root_url}/' + this.value|;
|
|
$html .= qq|">|;
|
|
for (@{$paging{pages}}) {
|
|
if ($_ eq '...') {
|
|
$html .= qq|<option value="" disabled="disabled">...</option>|;
|
|
}
|
|
else {
|
|
$html .= qq|<option value="| . $paging{select_value}->($_) . '"';
|
|
$html .= qq| selected="selected"| if $_ == $paging{current_page};
|
|
$html .= qq|>$_ $options{lang_of} $paging{num_pages}</option>|;
|
|
}
|
|
}
|
|
$html .= qq|</select><noscript><input type="submit" id="$options{button_id}" value="$options{lang_button}" class="submit" /></noscript> |;
|
|
|
|
if ($paging{current_page} != 1) {
|
|
$html .= $paging{create_link}->($paging{current_page} - 1, $options{style_prev}) . ' ';
|
|
}
|
|
else {
|
|
$html .= "$options{style_noprev} ";
|
|
}
|
|
|
|
if ($paging{current_page} != $paging{num_pages}) {
|
|
$html .= $paging{create_link}->($paging{current_page} + 1, $options{style_next});
|
|
}
|
|
else {
|
|
$html .= $options{style_nonext};
|
|
}
|
|
$html .= qq|$options{paging_post}</form>|;
|
|
}
|
|
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 .= "<span>$_</span> ";
|
|
}
|
|
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 .= '<span class="lasttitle">' 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|<a href="| . $IN->html_escape($title_loop->[$_]->{URL}) . qq|">$title_loop->[$_]->{Name}</a>|;
|
|
}
|
|
else {
|
|
$ret .= $title_loop->[$_]->{Name};
|
|
}
|
|
$ret .= $options{separator} unless $_ == $#$title_loop;
|
|
$ret .= '</span>' if $_ == $#$title_loop and not $options{no_span} and $options{include_last};
|
|
}
|
|
if ($options{link_type} == 3) {
|
|
$ret = qq|<a href="| . $IN->html_escape($title_loop->[-1]->{URL}) . qq|">$ret</a>|;
|
|
}
|
|
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;
|