<< | Cookbook-V1 | >>

Note: The recipes here are for PmWiki versions 0.6 and 1.0 only. For PmWiki 2.0 recipes, see Cookbook.

I'd suggest using session variables instead of cookies for this. Anyway, I'm planning a script for this feature soon. However, can we call it something besides "Bread Crumb Trail", since the common definition of "bread crumb trail" is the path to the page in the site's hierarchy, and not the path a user took to arrive at the current page. (See [(approve links) edit diff] and Nielsen's alertbox.) Perhaps "Navigation Trail" or "Navigated Trail"? How about "Recently Visited"? --Pm

I would say that bread crumb trail is a good naming for this purpose, and rename what you would like to be called bread crumb trail. To indeed sth like hierarchical trail. It is what "Hans and Grietje" from the fairy tail did when they were in the forest, to be able to exactly find their way back, dropping their bread crumbs. Might include some detours, indeed.

Anyway, what is the current status for this? And what does your script actually does and don't rigth now? Maybe it will serve my needs. I will eventually try it, but I can't get my head around PHP yet. Too little time ;-)


This would be good when it gets here. My attempt, that doesn't work right :( is as follows:


$visitedTrail =& BreadCrumbTrail();

function BreadCrumbTrail(){

global $HTTP_COOKIE_VARS,$pagename;

$breadCrumbHTML =  "<div align='right'>";  ## 
$breadCrumbHTML .= "<b>Recently Viewed:</b>";
$title = FmtPageName('$Title',$pagename);    # spaces wikiwords if
                                            # SpaceWikiWords set
$path = FmtPageName('$PageUrl',$pagename);
$path = "<a href=$path>$title</a>";

// Code begins here....
$old_value = $HTTP_COOKIE_VARS["my_trail"];
TruncateArrayInPlace($old_value, 5);

    if (strstr($old_value,$path)) {
        $new_value = $old_value;
    } else {
            $new_value = "$old_value > $path"; 
            $new_value = "$path";

    $trail = "$new_value";
    $splitter = explode($path, $trail);
    $trail = "$splitter[0] $title";
    TruncateArrayInPlace($trail , 5);

    $breadCrumbHTML .= "$trail";
    $breadCrumbHTML .= "</div>";

return $breadCrumbHTML; 

// TruncateArrayInPlace
function TruncateArrayInPlace( &$trail, $maxSize )
    // Trim off anything greater than $maxSize;
    if( isset( $trail ) && is_array( $trail ) && count( $trail ) > $maxSize )
        // Update the reference
        $trail = array_slice( $trail, 0, $maxSize );
// UnduplicateArray
function UnduplicateArray( &$in )
    // Loop across and remove consecutive duplicates
    // Loop across and create a new array containing non-unique values
    if( isset( $in ) && is_array( $in ) )
        foreach( $in as $element )
            if( !isset( $out ) || ($element != end($out)) )            
                $out[] = $element;
    // Done
    return $out;


All the elements are there, <strike>pinched</strike> borrowed from a variety of sources. I can't get my head around PHP array handling yet. It's too sophisticated :)

How about storing the version # for each pages visited (it looks like you are storing the time)? This would eventually allow differences form the last time they visited the page to automatically be highlighted when they return to a page. fick?

For what it's worth, here's a different way to do it. I haven't prepared this for public consumption, but it works in my environment (with messy urls), and the concept is simple enough that it should be easy to adopt.

All this does is generate an html fragment, consisting of links separated by $glue, and place it in $history for use in the active template. Then it adds the current page to a session array variable.

To use this, just save the following in cookbook/historytrails.php, include the same from local/config.php, and then stick '$history' into your template somewhere. You may also want to change the $glue and $max_chars variables.


$glue = ' > ';
$max_chars = 60;

function get_history_html() {
  global $glue;
  $result = '';
  for ($i = 0; $i < count($_SESSION['history']['linktitles']); $i++) {
    $linktitle = $_SESSION['history']['linktitles'][$i];
  $href = "$ScriptUrl?n={$_SESSION['history']['fulltitles'][$i]}";
    $result .= "<a href=$href >$linktitle</a>$glue";
  $result = substr_replace($result, '', -3, 3);
  return $result;

function add_to_history() {
  global $glue, $max_chars;

  $fulltitle = $_GET['n'];
  if (!$fulltitle || $fulltitle == $DefaultPage) {
  $fulltitle = $DefaultPage;
  $linktitle = 'Home';
  } else {
  $pieces = explode('.', $fulltitle);
  $group = $pieces[0]; $linktitle = $pieces[1];
  if ($linktitle == 'HomePage')
    $linktitle = $group;

  if ('Site' != $group) {
  if ($_SESSION['history']['fulltitles'][count($_SESSION['history']['fulltitles'])-1] != $fulltitle) {
    $_SESSION['history']['fulltitles'][] = $fulltitle;
    $_SESSION['history']['linktitles'][] = $linktitle;
  if (strlen(join($glue, $_SESSION['history']['linktitles'])) > $max_chars) {

//Set up $history html snippet.
if ($_SESSION['history']) {
  $history = get_history_html();
} else {
  $history = '';
  $_SESSION['history'] = array(
    'linktitles' => array(),
    'fulltitles' => array()

//Add current page to history.
if (!$_GET['action'])


Jonathan Camenisch pmwiki-2.3.34 -- Last modified by {{Jonathan Camenisch}}

from IP: ip should be disabled by default for security reasons