history-scan — generate link to (or just display name of) a previously visited page


Attribute Pos. Req. Default Description
find Yes Yes   Regular expression that a candidate page must match. First match wins.
exclude Yes   Regular expression specifying a pattern which, if matched, causes individual history entries to be removed from the list of possible candidates.
default Yes   Value of the SpecialPage catalog directive (which is usually index.html). Default link. Displayed if nothing else matched your criteria, or the user's history is empty.
include     Regular expression specifying a pattern which pages in user's history must match to be included as candidates.
form       Additional form data.
pageonly     0 Only display page name instead of generating an HTML link around it.
count       How many most-recently-visited pages to leave out from the list of candidates.
var_exclude     mv_credit_card_number 1
mv_pc 1
mv_session_id 1
expand 1
collapse 1
expandall 1
collapseall 1
Hash of variables to exclude from the form if form is used in the generated link. The default value shows a meaningful example. Note that since this is a hash, the number 1 (or any true value for that matter) after each entry is necessary, but redundant.
sizelimit     1024 maximum limit for resulting URL


This tag produces an HTML link to some previously visited page. Optionally, just the page name (without the link) can be displayed.

Pages in history which are marked "expired" (for any reason) are automatically discarded from the link candidates list.


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


Example: "Continue Shopping" button

  text="Continue shopping"
  [bounce href='[history-scan exclude="^/ord|^/multi/|^/process|^/login"

This example was provided by Jeff Dafoe.

Here's a simple login form that returns the user to the previous page after successful login:

<form action="[process secure=1]" method="post">
<input type="hidden"   name="mv_todo"        value="return>
<input type="hidden"   name="mv_click"       value="Login">
<input type="hidden"   name="mv_failpage"    value="login">
<input type="hidden"   name="mv_successpage" value="[history-scan
      exclude="^/ord|^/multi/|^/process|^/login|^/logout" pageonly=1]">
<input type="hidden"   name="mv_nextpage"    value="index">
<input type="hidden"   name="mv_session_id"  value="[data session id]">
<input type="text"     name="mv_username"    value="[read-cookie MV_USERNAME]">
<input type="password" name="mv_password"    value="">
<input type="submit"   name="submit"         value="Log In">



history-scan is available in Interchange versions:

4.6.0-5.9.0 (git-head)


Interchange 5.9.0:

Source: code/UserTag/history_scan.tag
Lines: 93

# Copyright 2002-2007 Interchange Development Group and others
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.  See the LICENSE file for details.
# $Id: history_scan.tag,v 1.20 2007-03-30 23:40:57 pajamian Exp $

UserTag history-scan Order   find exclude default
UserTag history-scan addAttr
UserTag history-scan Version $Revision: 1.20 $
UserTag history-scan Routine <<EOR
my %var_exclude = ( qw/
  mv_credit_card_number 1
  mv_pc                 1
  mv_session_id         1
  expand                1
  collapse              1
  expandall             1
  collapseall           1

sub {
my ($find, $exclude, $default, $opt) = @_;
$default ||= $Vend::Cfg->{SpecialPage}{catalog};
my $ref = $Vend::Session->{History};

use vars qw/$CGI $Tag/;

$opt->{size_limit} ||= '1024';
unless ($ref) {
  return $default if $opt->{pageonly};
  return $Tag->area($default);
my ($hist, $href, $cgi);
$exclude = qr/$exclude/ if $exclude;
my $include;
$include = qr/$opt->{include}/ if $opt->{include};
for (my $i = $#$ref - abs($opt->{count}); $i >= 0; $i--) {
  next if $ref->[$i][0] eq 'expired';
  if ($exclude and $ref->[$i][0] =~ $exclude) {
  if ($include and $ref->[$i][0] !~ $include) {
  if($find) {
    next unless $ref->[$i][0] =~ /$find/;
  ($href, $cgi) = @{$ref->[$i]};
unless ($href) {
  return $default if $opt->{pageonly};
  return $Tag->area($default);
$href =~ s|/+|/|g;
$href =~ s|^/||;
if ($opt->{pageonly}) {
  return $href;
my $form = '';
if($opt->{var_exclude}) {
  for(split /[\s,\0]+/, $opt->{var_exclude}) {
    $var_exclude{$_} = 1;
for(grep !$var_exclude{$_}, keys %$cgi) {
  $form .= "\n$_=";
  $form .= join("\n$_=", split /\0/, $cgi->{$_});
$form .= "\n$opt->{form}" if $opt->{form};
my $string = $Tag->area( {
              href => $href,
              form => $form,
              no_session => $opt->{no_session},
            } );
my $len = length($string);
if($len > $opt->{size_limit}) {
  $len = $Tag->filter('commify.0', $len);
  my $m = errmsg(
        'Huge URL (%s bytes) exceeds %s byte limit, returning blank.',
  $Tag->error({ name => 'history-scan', set => $m })
    if $opt->{debug};
  return undef;
return $string;


Interchange Development Group


DocBook! Interchange!