Revision [10491]

This is an old revision of ParentAction made by DennyShimkoski on 2005-08-07 02:41:34.

 

Go Ahead... Choose Your Parent!


Although wikis tend to have a flat web-like structure, it would still be nice if we could specify an "official parent" on a per-page basis. However, rather than building from the bottom up, which would require parents to choose their "most favorite" child, we'll build from the top down and let children choose their parent instead.

Since we want this to run on versions of MySQL that don't support subqueries, we'll have to figure out a way to cache each page's "family tree," rebuilding only when it becomes necessary. I think the current solution works well enough, but it hasn't been tested much and I don't know how well it will hold up on a busy wiki.

The Data Model


CREATE TABLE `wikka_parents` (
  `page_tag` varchar(75) NOT NULL default '',
  `parents` mediumtext NOT NULL,
  `time` datetime NOT NULL default '0000-00-00 00:00:00',
  KEY `page_tag` (`page_tag`)
) TYPE=MyISAM;


The Code


Save as "parent.php" in the actions directory...

<?php

// Examples
// {{parent page="HomePage"}} - set HomePage as the parent
// {{parent page="HomePage" label="<b>Current Location:</b>"}} -- add a prefix to the output
// Return a div with the id set to parent

global $table_pages, $table_parents;
$table_pages = $this->config['table_prefix'] . 'pages';
$table_parents = $this->config['table_prefix'] . 'parents';

function update_parents(&$wikka, $tag)
{
    static $children = array();
    global $table_pages, $table_parents;

    if ($row = $wikka->LoadSingle("SELECT parents, time FROM $table_parents WHERE page_tag = '$tag'"))
    {
        $parents = $row['parents'];
        $last_updated = $row['time'];
    }
    else
    {
        $parents = $last_updated = false;
    }

    // check to see if pages have changed since the last time we updated the parent info
    // if so, we'll have to update any parent tags we encounter
    // including this page's parent's parents and so on
    if ($last_updated) $updated_pages = $wikka->LoadAll("SELECT tag FROM $table_pages WHERE time > '$last_updated'");
    if ($updated_pages || !$last_updated)
    {
        // fetch the body of this page and check it for a parent action
        // ignore the action if it specifies a child item as its parent
        $row = $wikka->LoadSingle("SELECT body FROM $table_pages WHERE tag = '$tag' AND latest = 'Y'");
        $wikka_body = $row['body'];
        $parent_tag = preg_match('/{{.*parent[^}]+page="(.+)"/iU', $wikka_body, $match) ? $match[1] : false;
        array_unshift($children, $tag);
        if ($parent_tag && !in_array($parent_tag, $children))
        {
            // remove circular references from the tree
            $parents = preg_replace("/.*$tag:/", '', update_parents($wikka, $parent_tag));
            $retval = "$parents:$tag";
            $wikka->Query("UPDATE $table_parents SET parents = '$retval', time = NOW() WHERE page_tag = '$tag'");
            if (!mysql_affected_rows()) $wikka->Query("INSERT INTO $table_parents (page_tag, parents, time) VALUES ('$tag', '$retval', NOW())");
        }
        else
        {
            $retval = $tag;
        }
        array_shift($children);
    }
    elseif ($last_updated && !$updated_pages)
    {
        $retval = ($row = $wikka->LoadSingle("SELECT parents FROM $table_parents WHERE page_tag = '$tag'")) ? $row['parents'] : '';
    }
    else
    {
        $retval = '';
    }
    return $retval;
}

$label = isset($vars['label']) ? $vars['label'] : '';
$parents = update_parents($this, $this->tag);
$parents = split(':', $parents);
foreach ($parents as $tag)
{
    $url = $this->Href('', $tag);
    $links[] = $tag == $this->tag ? $tag : "<a href=\"$url\">$tag</a>";
}
echo '<div id="parent">' . $label . join(' &#187; ', $links) . '</div>';

?>


The Examples


{{parent page="HomePage"}} - set HomePage as the parent
{{parent page="HomePage" label="<b>Current Location:</b>"}} -- add a prefix to the output


The Screenshot


Screenshot of the Parent action's output

Authors


DennyShimkoski


CategoryUserContributions
There are no comments on this page.
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki