Difference between revisions of "Extension:Treeview4.php"
(4.0.3 - fix entire tree indentation, and add $wgTreeViewIndent) |
(4.0.4 - restructure main render code ready for adding line images) |
||
Line 5: | Line 5: | ||
# - Author: http://www.organicdesign.co.nz/nad | # - Author: http://www.organicdesign.co.nz/nad | ||
# - Started: (Version4) 2007-09-06 | # - Started: (Version4) 2007-09-06 | ||
− | + | ||
if (!defined('MEDIAWIKI')) die('Not an entry point.'); | if (!defined('MEDIAWIKI')) die('Not an entry point.'); | ||
− | + | ||
− | define('TREEVIEW4_VERSION','4.0. | + | define('TREEVIEW4_VERSION','4.0.4, 2007-09-10'); |
− | + | ||
# Set any unset images to default titles | # Set any unset images to default titles | ||
if (!is_array($wgTreeViewImages)) $wgTreeViewImages = array(); | if (!is_array($wgTreeViewImages)) $wgTreeViewImages = array(); | ||
Line 18: | Line 18: | ||
if (!isset($wgTreeViewImages['doc'])) $wgTreeViewImages['doc'] = 'Doc-icon.gif'; | if (!isset($wgTreeViewImages['doc'])) $wgTreeViewImages['doc'] = 'Doc-icon.gif'; | ||
if (!isset($wgTreeViewImages['spacer'])) $wgTreeViewImages['spacer'] = 'Blank.gif'; | if (!isset($wgTreeViewImages['spacer'])) $wgTreeViewImages['spacer'] = 'Blank.gif'; | ||
− | + | ||
+ | # These images are needed if you have $wgTreeViewShowLines set | ||
+ | if (!isset($wgTreeViewImages['vert'])) $wgTreeViewImages['vert'] = 'Vertline.gif'; | ||
+ | if (!isset($wgTreeViewImages['node'])) $wgTreeViewImages['node'] = 'Node.gif'; | ||
+ | if (!isset($wgTreeViewImages['last'])) $wgTreeViewImages['last'] = 'Lastnode.gif'; | ||
+ | |||
# Keep track of JavaScript added to page to avoid doubleups | # Keep track of JavaScript added to page to avoid doubleups | ||
if (!isset($wgJS)) $wgJS = array(); | if (!isset($wgJS)) $wgJS = array(); | ||
− | + | ||
$wgTreeView4Magic = "tree"; # the parser-function name for trees | $wgTreeView4Magic = "tree"; # the parser-function name for trees | ||
$wgTreeViewIndent = 0; # the number of pixels each level indents by (0 means doc-icon width) | $wgTreeViewIndent = 0; # the number of pixels each level indents by (0 means doc-icon width) | ||
+ | $wgTreeViewShowLines = false; # whether to render the dotted lines joining nodes | ||
$wgExtensionFunctions[] = 'wfSetupTreeView4'; | $wgExtensionFunctions[] = 'wfSetupTreeView4'; | ||
$wgHooks['LanguageGetMagic'][] = 'wfTreeView4LanguageGetMagic'; | $wgHooks['LanguageGetMagic'][] = 'wfTreeView4LanguageGetMagic'; | ||
− | + | ||
$wgExtensionCredits['parserhook'][] = array( | $wgExtensionCredits['parserhook'][] = array( | ||
'name' => 'Treeview4', | 'name' => 'Treeview4', | ||
Line 34: | Line 40: | ||
'version' => TREEVIEW4_VERSION | 'version' => TREEVIEW4_VERSION | ||
); | ); | ||
− | + | ||
class TreeView4 { | class TreeView4 { | ||
− | + | ||
var $version = TREEVIEW4_VERSION; | var $version = TREEVIEW4_VERSION; | ||
var $width = 16; | var $width = 16; | ||
var $uniq = array(); | var $uniq = array(); | ||
+ | var $uid = ''; | ||
var $js = 0; | var $js = 0; | ||
− | + | ||
# Constructor | # Constructor | ||
function TreeView4($magic) { | function TreeView4($magic) { | ||
Line 59: | Line 66: | ||
} | } | ||
} | } | ||
+ | |||
+ | $this->uid = uniqid('TVUNIQ'); | ||
} | } | ||
− | + | ||
# Restructure recursive trees into a single bullet list surrounded by internal treeview4 tags | # Restructure recursive trees into a single bullet list surrounded by internal treeview4 tags | ||
function Tree(&$parser) { | function Tree(&$parser) { | ||
Line 85: | Line 94: | ||
function treeview($text,$argv,&$parser) { | function treeview($text,$argv,&$parser) { | ||
global $wgTreeViewImages; | global $wgTreeViewImages; | ||
− | + | ||
$id = $argv['id']; | $id = $argv['id']; | ||
$ver = $this->version; | $ver = $this->version; | ||
Line 95: | Line 104: | ||
$spacer = $wgTreeViewImages['spacer']; | $spacer = $wgTreeViewImages['spacer']; | ||
$doc = $wgTreeViewImages['doc']; | $doc = $wgTreeViewImages['doc']; | ||
+ | $vert = $wgTreeViewImages['vert']; | ||
+ | $node = $wgTreeViewImages['node']; | ||
+ | $last = $wgTreeViewImages['last']; | ||
$default = isset($argv['openlevels']) ? $argv['openlevels']+1 : 1; | $default = isset($argv['openlevels']) ? $argv['openlevels']+1 : 1; | ||
$rows = array(); | $rows = array(); | ||
+ | $cols = 0; | ||
$tree = ''; | $tree = ''; | ||
− | + | ||
# Protect the asterisk structure and wiki-parse the bullet tree | # Protect the asterisk structure and wiki-parse the bullet tree | ||
− | $text = preg_replace_callback( | + | $text = preg_replace_callback("/^(\\*+)(.*?)$/m",array($this,'protectTree'),$text); |
− | |||
− | |||
− | |||
− | |||
$out = $parser->parse($text,$parser->mTitle,$parser->mOptions,false,false); | $out = $parser->parse($text,$parser->mTitle,$parser->mOptions,false,false); | ||
$text = $out->getText(); | $text = $out->getText(); | ||
− | # | + | # Extract the valid rows and process if any |
− | if (preg_match_all( | + | if (preg_match_all("/1{$this->uid}([0-9]+)-(.+?){$this->uid}2/",$text,$matches,PREG_SET_ORDER)) { |
+ | |||
+ | # Parse 1 | ||
+ | foreach ($matches as $row) { | ||
+ | list(,$depth,$item) = $row; | ||
+ | if ($depth > $cols) $cols = $depth; | ||
+ | $rows[] = array($depth,$item); | ||
+ | } | ||
+ | $cols += 2; | ||
+ | |||
+ | # Parse 2 | ||
foreach ($rows as $i => $row) { | foreach ($rows as $i => $row) { | ||
− | list( | + | list($depth,$item) = $row; |
− | $next = $i < count($rows)-1 ? $rows[$i+1][ | + | $next = $i < count($rows)-1 ? $rows[$i+1][0] : 0; |
$show = $depth > $default ? ' style="display:none"' : ''; | $show = $depth > $default ? ' style="display:none"' : ''; | ||
if ($depth >= $default) { $open = $plus; $icon = $closed; } else { $open = $minus; $icon = $opened; } | if ($depth >= $default) { $open = $plus; $icon = $closed; } else { $open = $minus; $icon = $opened; } | ||
Line 126: | Line 145: | ||
return $tree; | return $tree; | ||
} | } | ||
− | + | ||
+ | # Protect asterisk bullet structure from wiki parser | ||
+ | function protectTree($m) { | ||
+ | return "1{$this->uid}".strlen($m[1])."-$m[2]{$this->uid}2\n"; | ||
+ | } | ||
+ | |||
# Add the javascript to the output object if not added yet and there is at least one tree | # Add the javascript to the output object if not added yet and there is at least one tree | ||
function addJS() { | function addJS() { | ||
Line 165: | Line 189: | ||
} | } | ||
} | } | ||
− | + | ||
# Called from $wgExtensionFunctions array when initialising extensions | # Called from $wgExtensionFunctions array when initialising extensions | ||
function wfSetupTreeView4() { | function wfSetupTreeView4() { | ||
Line 172: | Line 196: | ||
$wgTreeView4->addJS(); # Make code unconditional for now due to parser caching | $wgTreeView4->addJS(); # Make code unconditional for now due to parser caching | ||
} | } | ||
− | + | ||
# Needed in MediaWiki >1.8.0 for magic word hooks to work properly | # Needed in MediaWiki >1.8.0 for magic word hooks to work properly | ||
function wfTreeView4LanguageGetMagic(&$magicWords,$langCode = 0) { | function wfTreeView4LanguageGetMagic(&$magicWords,$langCode = 0) { |
Revision as of 13:04, 10 September 2007
<?php
- MediaWiki Treeview ExtensionTemplate:Php
- - See http://www.mediawiki.org/wiki/Extension:Tree_view for installation and usage details
- - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
- - Author: http://www.organicdesign.co.nz/nad
- - Started: (Version4) 2007-09-06
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('TREEVIEW4_VERSION','4.0.4, 2007-09-10');
- Set any unset images to default titles
if (!is_array($wgTreeViewImages)) $wgTreeViewImages = array(); if (!isset($wgTreeViewImages['plus'])) $wgTreeViewImages['plus'] = 'Plus.gif'; if (!isset($wgTreeViewImages['minus'])) $wgTreeViewImages['minus'] = 'Minus.gif'; if (!isset($wgTreeViewImages['opened'])) $wgTreeViewImages['opened'] = 'Folder_opn_sml_yel.gif'; if (!isset($wgTreeViewImages['closed'])) $wgTreeViewImages['closed'] = 'Folder_sml_yel.gif'; if (!isset($wgTreeViewImages['doc'])) $wgTreeViewImages['doc'] = 'Doc-icon.gif'; if (!isset($wgTreeViewImages['spacer'])) $wgTreeViewImages['spacer'] = 'Blank.gif';
- These images are needed if you have $wgTreeViewShowLines set
if (!isset($wgTreeViewImages['vert'])) $wgTreeViewImages['vert'] = 'Vertline.gif'; if (!isset($wgTreeViewImages['node'])) $wgTreeViewImages['node'] = 'Node.gif'; if (!isset($wgTreeViewImages['last'])) $wgTreeViewImages['last'] = 'Lastnode.gif';
- Keep track of JavaScript added to page to avoid doubleups
if (!isset($wgJS)) $wgJS = array();
$wgTreeView4Magic = "tree"; # the parser-function name for trees $wgTreeViewIndent = 0; # the number of pixels each level indents by (0 means doc-icon width) $wgTreeViewShowLines = false; # whether to render the dotted lines joining nodes $wgExtensionFunctions[] = 'wfSetupTreeView4'; $wgHooks['LanguageGetMagic'][] = 'wfTreeView4LanguageGetMagic';
$wgExtensionCredits['parserhook'][] = array( 'name' => 'Treeview4', 'author' => 'User:Nad', 'url' => 'http://www.mediawiki.org/wiki/Extension:Treeview', 'description' => 'Allows dynamic tree-views to be made with bullet-list syntax', 'version' => TREEVIEW4_VERSION );
class TreeView4 {
var $version = TREEVIEW4_VERSION; var $width = 16; var $uniq = array(); var $uid = ; var $js = 0;
# Constructor function TreeView4($magic) { global $wgParser,$wgHooks,$wgTreeViewImages,$wgTreeViewIndent;
# Set hooks $wgParser->setFunctionHook($magic,array($this,'Tree'));
# Convert image titles to file paths and obtain pixel width of items if ($wgTreeViewIndent) $this->width = $wgTreeViewIndent; foreach ($wgTreeViewImages as $k => $v) { $title = Title::newFromText($v,NS_IMAGE); $image = Image::newFromTitle($title); if ($image && $image->exists()) { $wgTreeViewImages[$k] = $image->getURL(); if ($wgTreeViewIndent < 1 && $k == 'doc') $this->width = $image->getWidth(); } }
$this->uid = uniqid('TVUNIQ'); }
# Restructure recursive trees into a single bullet list surrounded by internal treeview4 tags function Tree(&$parser) { global $wgParser; $id = uniqid(); $args = "id='$id'"; foreach (func_get_args() as $arg) if (!is_object($arg)) { if (preg_match('/^(.+?=.+)$/',$arg,$m)) $args .= " $arg"; else $text = $arg; }
# Back magic $text = $this->uniq[$id] = preg_replace( '/^\\*(\\**)\\s*(.UNIQ.+?-treeview4(.+?)-.+?-QINU)/me', '$this->uniq["$3"] ? preg_replace("/^(\\*+)/m","$1\$1",$this->uniq["$3"]) : "$1$2"', $text );
# And a little more voodoo here $wgParser->setHook("treeview4$id",array($this,'treeview')); return "<treeview4$id $args>$text</treeview4$id>"; }
# Convert a bullet list into a treeview function treeview($text,$argv,&$parser) { global $wgTreeViewImages;
$id = $argv['id']; $ver = $this->version; $width = $this->width; $plus = $wgTreeViewImages['plus']; $minus = $wgTreeViewImages['minus']; $opened = $wgTreeViewImages['opened']; $closed = $wgTreeViewImages['closed']; $spacer = $wgTreeViewImages['spacer']; $doc = $wgTreeViewImages['doc']; $vert = $wgTreeViewImages['vert']; $node = $wgTreeViewImages['node']; $last = $wgTreeViewImages['last']; $default = isset($argv['openlevels']) ? $argv['openlevels']+1 : 1; $rows = array(); $cols = 0;
$tree = ;
# Protect the asterisk structure and wiki-parse the bullet tree $text = preg_replace_callback("/^(\\*+)(.*?)$/m",array($this,'protectTree'),$text); $out = $parser->parse($text,$parser->mTitle,$parser->mOptions,false,false); $text = $out->getText();
# Extract the valid rows and process if any if (preg_match_all("/1{$this->uid}([0-9]+)-(.+?){$this->uid}2/",$text,$matches,PREG_SET_ORDER)) {
# Parse 1 foreach ($matches as $row) { list(,$depth,$item) = $row; if ($depth > $cols) $cols = $depth; $rows[] = array($depth,$item); } $cols += 2;
# Parse 2 foreach ($rows as $i => $row) { list($depth,$item) = $row; $next = $i < count($rows)-1 ? $rows[$i+1][0] : 0; $show = $depth > $default ? ' style="display:none"' : ; if ($depth >= $default) { $open = $plus; $icon = $closed; } else { $open = $minus; $icon = $opened; } if ($depth >= $next) { $open = "<img src='$spacer' width='$width'/>"; $icon = $doc; } else $open = "<a href='javascript:toggleTreeviewItem(\"$id\",$i)'><img id='tvi$id$i' src='$open'/></a>"; $tree .= "<tr$show class='tree-row' depth='$depth' id='tvr$id$i'>"
. "<img src='$spacer' width='".(($depth-1)*$width)."' height='1'/>$open" . " <img id='tvf$id$i' src='$icon'/> $item\n"; } } $tree = "
\n$tree";
return $tree; }
# Protect asterisk bullet structure from wiki parser function protectTree($m) { return "1{$this->uid}".strlen($m[1])."-$m[2]{$this->uid}2\n"; }
# Add the javascript to the output object if not added yet and there is at least one tree function addJS() { global $wgOut,$wgTreeViewImages,$wgJS,$wgJsMimeType; if (isset($wgJS['TreeView4'])) return; $wgJS['TreeView4'] = true; $plus = $wgTreeViewImages['plus']; $minus = $wgTreeViewImages['minus']; $opened = $wgTreeViewImages['opened']; $closed = $wgTreeViewImages['closed']; $spacer = $wgTreeViewImages['spacer']; $doc = $wgTreeViewImages['doc']; $wgOut->addScript('<script type="'.$wgJsMimeType.'"> function toggleTreeviewItem(id,row) { var plus = "'.$plus.'"; var minus = "'.$minus.'"; var opened = "'.$opened.'"; var closed = "'.$closed.'"; var doc = "'.$doc.'"; var item = document.getElementById("tvr"+id+row); var next = document.getElementById("tvr"+id+(row+1)); var depth = 0+item.getAttribute("depth"); var close = next.style.display != "none"; var img = document.getElementById("tvi"+id+row); var fld = document.getElementById("tvf"+id+row); fld.setAttribute("src",close ? closed : opened); img.setAttribute("src",close ? plus : minus); while ((item = document.getElementById("tvr"+id+(++row))) && (0+item.getAttribute("depth") > depth)) { if (close) item.style.display = "none"; else if (depth == item.getAttribute("depth")-1) { item.style.display = ""; if (img = document.getElementById("tvi"+id+row)) img.setAttribute("src",plus); if (fld = document.getElementById("tvf"+id+row)) if (fld.getAttribute("src") == opened) fld.setAttribute("src",closed); } } }</script>'); } }
- Called from $wgExtensionFunctions array when initialising extensions
function wfSetupTreeView4() { global $wgTreeView4,$wgTreeView4Magic; $wgTreeView4 = new TreeView4($wgTreeView4Magic); $wgTreeView4->addJS(); # Make code unconditional for now due to parser caching }
- Needed in MediaWiki >1.8.0 for magic word hooks to work properly
function wfTreeView4LanguageGetMagic(&$magicWords,$langCode = 0) { global $wgTreeView4Magic; $magicWords[$wgTreeView4Magic] = array(0,$wgTreeView4Magic); return true; } ?>