Name

more_list — pagination for Interchange lists

ATTRIBUTES

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?

DESCRIPTION

[more_list] can be used in lists produced by the [query], [search_region] ... tags.

Template for More Lists

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

BEHAVIOR

This tag does not appear to be affected by, or affect, the rest of Interchange.

EXAMPLES

No examples are available at this time. We do consider this a problem and will try to supply some.

NOTES

AVAILABILITY

more_list is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0:

Source: lib/Vend/Interpolate.pm
Lines: 3521

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;

  ($pretty_url, $incl_pageno) = ();
  if ($r =~ m{\[more[-_]pretty[-_]url\]}i) {
#::logDebug('$r matched on more-pretty-url');
      $r =~ s{\[more[-_]pretty[-_]url\]($All)\[/more[-_]pretty[-_]url\]}{}i
          and $pretty_url = $q->{more_pretty_url} ||= ::interpolate_html($1);
      $r =~ s{\[more[-_]incl[-_]pageno\]($All)\[/more[-_]incl[-_]pageno\]}{}i
          and $incl_pageno = $q->{more_incl_pageno} ||= $1 || '1';
  }

$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, 1);
  }

  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, \
 $current && $current - 1);
  }

}
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, $current && $current + 1);

   # 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, \
 $chunk && ceil($total / $chunk));
  }
}
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>&#91;$more_string&gt;&gt;&#93;</small>"
    if ! $decade_next;
  $r =~ s:\[decade[-_]prev\]($All)\[/decade[-_]prev\]::i
    and $decade_prev = $1;
  $decade_prev = "<small>&#91;&lt;&lt;$more_string&#93;</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;
}

if ($r =~ s:\[all[-_]anchor\]($All)\[/all[-_]anchor\]::i and ($first or $next)) {
  my $all_anchor = $1;
  $arg = "$session:0:0:100000";
  push @more_links, more_link_template($all_anchor, $arg, $form_arg);
}

$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;
}

}

AUTHORS

Interchange Development Group

SEE ALSO

DocBook! Interchange!