more_list — pagination for Interchange lists
| Attribute | Pos. | Req. | Default | Description |
|---|---|---|---|---|
| more_routine |
custom routine for [more_list]
|
|||
| interpolate | 0 | interpolate input? | ||
| reparse | 1 | interpolate output? | ||
| hide | 0 | Hide the tag return value? |
[more_list] can be used in lists produced by the [query],
[search_region] ... tags.
The default template for more lists looks like that:
{FIRST_LINK?}{FIRST_LINK} {/FIRST_LINK?}
{PREV_LINK?}{PREV_LINK} {/PREV_LINK?}
{DECADE_PREV?}{DECADE_PREV} {/DECADE_PREV?}
{MORE_LIST}
{DECADE_NEXT?} {DECADE_NEXT}{/DECADE_NEXT?}
{NEXT_LINK?} {NEXT_LINK}{/NEXT_LINK?}
{LAST_LINK?} {LAST_LINK}{/LAST_LINK?}
The following values will be recognized in the template:
| Value | Description |
|---|---|
MATCH_COUNT
|
Same as [match-count], number of matches |
MATCHES
|
Same as [matches] |
LAST_PAGE
|
Last page number |
CURRENT_PAGE
|
Current page number |
DECADE_FIRST
|
First page of decade |
DECADE_LAST
|
Last page of decade |
FIRST_MATCH
|
First match displayed on this page |
LAST_MATCH
|
Last match displayed on this page |
FIRST_LINK
|
Link to first page |
PREV_LINK
|
Link to previous page |
DECADE_PREV
|
Link to previous decade |
MORE_LIST
|
The page list |
DECADE_NEXT
|
Link to next decade |
NEXT_LINK
|
Link to next page |
LAST_LINK
|
Link to last page |
Interchange 5.7.0:
Source: lib/Vend/Interpolate.pm
Lines: 3477
sub tag_more_list {
(
$next_anchor,
$prev_anchor,
$page_anchor,
$border,
$border_selected,
$opt,
$r,
) = @_;
if(my $name = $opt->{more_routine}) {
my $sub = $Vend::Cfg->{Sub}{$name} || $Global::GlobalSub->{$name};
return $sub->(@_) if $sub;
}
#::logDebug("more_list: opt=$opt label=$opt->{label}");
return undef if ! $opt;
$q = $opt->{object} || $::Instance->{SearchObject}{$opt->{label}};
return '' unless $q->{matches} > $q->{mv_matchlimit}
and $q->{mv_matchlimit} > 0;
my($arg,$inc,$last,$m);
my($adder,$pages);
my($first_anchor,$last_anchor);
my %hash;
$session = $q->{mv_cache_key};
my $first = $q->{mv_first_match} || 0;
$chunk = $q->{mv_matchlimit};
$perm = $q->{mv_more_permanent} ? ':1' : '';
$total = $q->{matches};
my $next = defined $q->{mv_next_pointer}
? $q->{mv_next_pointer}
: $first + $chunk;
$page = $q->{mv_search_page} || $Global::Variable->{MV_PAGE};
$prefix = $q->{prefix} || '';
my $form_arg = "mv_more_ip=1\nmv_nextpage=$page";
$form_arg .= "\npf=$q->{prefix}" if $q->{prefix};
$form_arg .= "\n$opt->{form}" if $opt->{form};
if($q->{mv_more_id}) {
$more_id = $q->{mv_more_id};
$form_arg .= "\nmi=$more_id";
}
else {
$more_id = undef;
}
my $more_joiner = $opt->{more_link_joiner} || ' ';
if($r =~ s:\[border\]($All)\[/border\]::i) {
$border = $1;
$border =~ s/\D//g;
}
if($r =~ s:\[border[-_]selected\]($All)\[/border[-_]selected\]::i) {
$border = $1;
$border =~ s/\D//g;
}
undef $link_template;
$r =~ s:\[link[-_]template\]($All)\[/link[-_]template\]::i
and $link_template = $1;
$link_template ||= q{<a href="$URL$">$ANCHOR$</a>};
if(! $chunk or $chunk >= $total) {
return '';
}
$border = qq{ border="$border"} if defined $border;
$border_selected = qq{ border="$border_selected"}
if defined $border_selected;
$adder = ($total % $chunk) ? 1 : 0;
$pages = int($total / $chunk) + $adder;
$current = int($next / $chunk) || $pages;
if($first) {
$first = 0 if $first < 0;
# First link may appear when prev link is valid
if($r =~ s:\[first[-_]anchor\]($All)\[/first[-_]anchor\]::i) {
$first_anchor = $1;
}
else {
$first_anchor = errmsg('First');
}
unless ($first_anchor eq 'none') {
$arg = $session;
$arg .= ':0:';
$arg .= $chunk - 1;
$arg .= ":$chunk$perm";
$hash{first_link} = more_link_template($first_anchor, $arg, $form_arg);
}
unless ($prev_anchor) {
if($r =~ s:\[prev[-_]anchor\]($All)\[/prev[-_]anchor\]::i) {
$prev_anchor = $1;
}
else {
$prev_anchor = errmsg('Previous');
}
}
elsif ($prev_anchor ne 'none') {
$prev_anchor = qq%<img src="$prev_anchor"$border>%;
}
unless ($prev_anchor eq 'none') {
$arg = $session;
$arg .= ':';
$arg .= $first - $chunk;
$arg .= ':';
$arg .= $first - 1;
$arg .= ":$chunk$perm";
$hash{prev_link} = more_link_template($prev_anchor, $arg, $form_arg);
}
}
else {
$r =~ s:\[(prev|first)[-_]anchor\]$All\[/\1[-_]anchor\]::ig;
}
if($next) {
unless ($next_anchor) {
if($r =~ s:\[next[-_]anchor\]($All)\[/next[-_]anchor\]::i) {
$next_anchor = $1;
}
else {
$next_anchor = errmsg('Next');
}
}
else {
$next_anchor = qq%<img src="$next_anchor"$border>%;
}
$last = $next + $chunk - 1;
$last = $last > ($total - 1) ? $total - 1 : $last;
$arg = "$session:$next:$last:$chunk$perm";
$hash{next_link} = more_link_template($next_anchor, $arg, $form_arg);
# Last link can appear when next link is valid
if($r =~ s:\[last[-_]anchor\]($All)\[/last[-_]anchor\]::i) {
$last_anchor = $1;
}
else {
$last_anchor = errmsg('Last');
}
unless ($last_anchor eq 'none') {
$last = $total - 1;
my $last_beg_idx = $total - ($total % $chunk || $chunk);
$arg = "$session:$last_beg_idx:$last:$chunk$perm";
$hash{last_link} = more_link_template($last_anchor, $arg, $form_arg);
}
}
else {
$r =~ s:\[(last|next)[-_]anchor\]$All\[/\1[-_]anchor\]::gi;
}
unless ($page_anchor) {
if($r =~ s:\[page[-_]anchor\]($All)\[/page[-_]anchor\]::i) {
$page_anchor = $1;
}
else {
$page_anchor = '__PAGE__';
}
}
elsif ($page_anchor ne 'none') {
$page_anchor = qq%<img src="$page_anchor?__PAGE__"__BORDER__>%;
}
$page_anchor =~ s/\$(MIN|MAX)?PAGE\$/__${1}PAGE__/g;
my $more_string = errmsg('more');
my ($decade_next, $decade_prev, $decade_div);
if( $q->{mv_more_decade} or $r =~ m:\[decade[-_]next\]:) {
$r =~ s:\[decade[-_]next\]($All)\[/decade[-_]next\]::i
and $decade_next = $1;
$decade_next = "<small>[$more_string>>]</small>"
if ! $decade_next;
$r =~ s:\[decade[-_]prev\]($All)\[/decade[-_]prev\]::i
and $decade_prev = $1;
$decade_prev = "<small>[<<$more_string]</small>"
if ! $decade_prev;
$decade_div = $q->{mv_more_decade} > 1 ? $q->{mv_more_decade} : 10;
}
my ($begin, $end);
if(defined $decade_div and $pages > $decade_div) {
if($current > $decade_div) {
$begin = ( int ($current / $decade_div) * $decade_div ) + 1;
$hash{decade_prev} = more_link($begin - $decade_div, $decade_prev);
}
else {
$begin = 1;
}
if($begin + $decade_div <= $pages) {
$end = $begin + $decade_div;
$hash{decade_next} = more_link($end, $decade_next);
$end--;
}
else {
$end = $pages;
delete $hash{$decade_next};
}
#::logDebug("more_list: decade found pages=$pages current=$current begin=$begin \
end=$end next=$next last=$last decade_div=$decade_div");
}
else {
($begin, $end) = (1, $pages);
delete $hash{$decade_next};
}
#::logDebug("more_list: pages=$pages current=$current begin=$begin end=$end \
next=$next last=$last decade_div=$decade_div page_anchor=$page_anchor");
my @more_links;
if ($q->{mv_alpha_list}) {
for my $record (@{$q->{mv_alpha_list}}) {
$arg = "$session:$record->[2]:$record->[3]:" . ($record->[3] - $record->[2] + 1);
my $letters = substr($record->[0], 0, $record->[1]);
push @more_links, more_link_template($letters, $arg, $form_arg);
}
$hash{more_alpha} = join $more_joiner, @more_links;
}
else {
foreach $inc ($begin .. $end) {
last if $page_anchor eq 'none';
push @more_links, more_link($inc, $page_anchor);
}
$hash{more_numeric} = join $more_joiner, @more_links;
}
$hash{more_list} = join $more_joiner, @more_links;
$first = $first + 1;
$last = $first + $chunk - 1;
$last = $last > $total ? $total : $last;
$m = $first . '-' . $last;
$hash{matches} = $m;
$hash{first_match} = $first;
$hash{last_match} = $last;
$hash{decade_first} = $begin;
$hash{decade_last} = $end;
$hash{last_page} = $hash{total_pages} = $pages;
$hash{current_page} = $current;
$hash{match_count} = $q->{matches};
if($r =~ /{[A-Z][A-Z_]+[A-Z]}/ and $r !~ $QR{more}) {
return tag_attr_list($r, \%hash, 1);
}
else {
my $tpl = qq({FIRST_LINK?}{FIRST_LINK} {/FIRST_LINK?}{PREV_LINK?}{PREV_LINK} \
{/PREV_LINK?}{DECADE_PREV?}{DECADE_PREV} {/DECADE_PREV?}{MORE_LIST}{DECADE_NEXT \
?} {DECADE_NEXT}{/DECADE_NEXT?}{NEXT_LINK?} {NEXT_LINK}{/NEXT_LINK \
?}{LAST_LINK?} {LAST_LINK}{/LAST_LINK?});
$tpl =~ s/\s+$//;
my $list = tag_attr_list($opt->{more_template} || $tpl, \%hash, 1);
$r =~ s,$QR{more},$list,g;
$r =~ s,$QR{matches},$m,g;
$r =~ s,$QR{match_count},$q->{matches},g;
return $r;
}
}