Difference between revisions of "Extension talk:Treeview5.php"

From Organic Design wiki
m (Explanation of guids)
m (Explanation of guids)
Line 207: Line 207:
 
$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();
 +
 +
function protectTree($m) { return "1{$this->uid}".strlen($m[1])."-$m[2]{$this->uid}2\n"; }
 
</php>}}
 
</php>}}
  

Revision as of 05:24, 22 February 2008

Info.svg This talk page pertains specifically to the development of this extension. For more general discussion about bugs and usage etc, please refer to the mediawiki.org talk page at MW:Extension talk:Tree view

A more logical way of approaching a treeview in MediaWiki is for the PHP extension part to concentrate on allowing bullet lists (and maybe numbered lists too) to work recusively with transclusion, and for the tree rendering to be handled by existing JavaScript components such as dTree which are very good and packed with features such as persistence between pages.


Note.svg Note: Extension:DTree.php has been created in the mean time to test dtree, the code will be integrated into Extension:Treeview5.php.


Treeview4 already handles the recursion aspect well and has been written in a much more modular way than Treeview3 allowing it to be independent of the tree rendering. But in this version I'd like to make the list-recursion work without any parser-function syntax at all - i.e. essentially to fix the MediaWiki parser's limitation of not allowing transclusion to work properly with lists as in the following example.

*Foo
**Bar
**{{:Baz}}
**Fodda

The new version would allow the Baz article (if it were a bullet list) to be properly nested at the correct level in the parent tree. This would simply be based on the fact that the transclusion is directly after an asterisk. The following example would not be indented, the indentation of Baz is determined by the article itself.

*Foo
**Bar
{{:Baz}}
**Fodda


The #tree parser-function would still be used to make bullet lists into trees, but would be optional and would provide an interface to convert the transcluded bullet lists into the javascript required in dTree (see Extension talk:Treeview5.php#Dtree API) to generate a tree.

Persistance

Persistance is auctomatically handled via cookies, see dtree.js, line 36.


Dtree API

See file api.html in the dTree directory.

Basically this extension need to provide an interface from a parser function which deals with nested bullet lists to creating the javascript output. At the bullet list stage the php function htmlspecialchars on the input to prevent cross site scripting. See HTML Code Injection and Cross-site scripting for details.

Open/Close parser function

Dedicated parser functions should be provided which inserts the open/close functionality of clades on the tree.

<p><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>

Note here that the javascript object is a tree called d. The functionality will not work for any other tree other than that named d.

Tree example

This example generates a tree similar to the example01.html provided with dTree

Wikisyntax
{{#tree:openlevels=4|root='My example tree'|
*Node 1
**Node 1.1
***Node 1.1.1
****Node 1.1.1.1
*Node 2
*Node 3
*Node 4
*My Pictures
**The trip to Iceland
**Mom's birthday
*Recycle bin
}}
Original javascript syntax;
	d = new dTree('d');

	d.add(0,-1,'My example tree');
	d.add(1,0,'Node 1','/wiki/index.php?title=Sandbox');
	d.add(2,0,'Node 2','example01.html');
	d.add(3,1,'Node 1.1','example01.html');
	d.add(4,0,'Node 3','example01.html');
	d.add(5,3,'Node 1.1.1','example01.html');
	d.add(6,5,'Node 1.1.1.1','example01.html');
	d.add(7,0,'Node 4','example01.html');
	d.add(8,1,'Node 1.2','example01.html');
	d.add(9,0,'My Pictures','example01.html','Pictures I\'ve taken over the years','','','img/imgfolder.gif');
	d.add(10,9,'The trip to Iceland','example01.html','Pictures of Gullfoss and Geysir');
	d.add(11,9,'Mom\'s birthday','example01.html');
	d.add(12,0,'Recycle Bin','example01.html','','','img/trash.gif');

	document.write(d);
Equivalent reordered javascript syntax;
	e = new dTree('e');

	e.add(0,-1,'My example tree');
	e.add(1,0,'Node 1','/wiki/index.php?title=Sandbox');
	e.add(2,1,'Node 1.1','example01.html');
	e.add(3,2,'Node 1.1.1','example01.html');
	e.add(4,3,'Node 1.1.1.1','example01.html');
	e.add(5,1,'Node 1.2','example01.html');
	e.add(6,0,'Node 2','example01.html');
	e.add(7,0,'Node 3','example01.html');
	e.add(8,0,'Node 4','example01.html');
	e.add(9,0,'My Pictures','example01.html','Pictures I\'ve taken over the years','','','img/imgfolder.gif');
	e.add(10,9,'The trip to Iceland','example01.html','Pictures of Gullfoss and Geysir');
	e.add(11,9,'Mom\'s birthday','example01.html');
	e.add(12,0,'Recycle Bin','example01.html','','','img/trash.gif');
	
	document.write(e);

The current treeview5.php can be configured to use images from dtree during development.

{{{1}}}

Defining the root of the tree

The root of the tree could be optionally specified with a parameter called root in the parser function options. It must be specified as either;

unnamed

	e.add(0,-1,'');

or named

	e.add(0,-1,'My example tree');

for the tree to be rendered.


{{{1}}}

How it works

There are basically two stages to the way the treeview is working the first stage is the parser-function (the Tree function) which is designed to allow bullet lists to work continue with proper depth when transcluded. The result of the parser-function is a single bullet list which is surrounded in <treeviewxxx> tags to be converted into the proper tree HTML. It was very difficult to get the transclusion to work properly and required some "voodoo".

Explanation of voodoo

The voodoo is required because the wiki parser works from deepest first to top level last, and protects tags inside GUID's which are not exposed to the parser which effectively puts them off-limits to any possible adjustment. The voodoo finds these protected GUID's and replaces them with normal bullet content which is not protected from further parsing and so becomes part of the higher level's content.

Explanation of guids

After the first stage of wiki-parsing (i.e. the processing of curly braces and protection of tag content) each tree will be a single wikitext bullet list to be processed by the tag hook (the treeview function). This function is essentially a two-stage process.

The first stage of this function converts the wikitext bullet list into list of items matchable by unique id's eg,

*[[foo]]
**[[bar]]

would become something like this:

UNIQxxxx1-<a href=.....</a>UNIQxxxx
UNIQxxxx2-<a href=.....</a>UNIQxxxx

The reason for this is that we need to protect the asterisks from being parsed otherwise they will be converted into UL's and LI's, but the rest of the content (i.e. the wikitext content in each bullet item) should be wiki-parsed as usual. We convert each row into a GUID-based structure so that the rows can be easily matched in the second stage without any possibility of any other content in the page or in a another tree being accidentally matched as well.

After this conversion all the rows of the current tree can be matched with a single preg_match_all. Each row contains the depth info and the parsed wikitext of the row (and also an icon if the first item of content in a row was an image link). The code which does this conversion is as follows:

{{{1}}}

The way to loop through the resulting matched rows and obtain their info to build the HTML or JS of a tree is as follows:

{{{1}}}

See also