Extension talk:TemplateTable
From MediaWiki.org
Any user names refer to users of that site, who are not necessarily users of MediaWiki.org (even if they share the same username).
Contents |
[edit] Another useful feature
This would be a more useful extension (IMHO) if you could filter the table based on a parameter (or an expression of parameters), and also possibly have an option to only show include template usages on the current page. In the example, then, this could let you build a table of all restaurants in the $$$ price range, or make a page of Boston Restaurants that uses this template, and summarize them all in a table at the top.
Also note that for this to work the code should look for more than one template per page! It currently only finds the first one. Vash 16:15, 24 April 2007 (UTC)
[edit] re. Another useful feature
- Yes! I agree. This would be a more useful extension (IMHO) if you could filter the table based on a parameter (or an expression of parameters).
- Some examples belows here would be nice.
<ttable template='Restaurant' category=Chinese food and category=located America></ttable> <ttable template='Restaurant' category=Chinese food or category=America food></ttable>
- Other ideas which can be found it written in DynamicPageList2 0.9.
- --Roc michael 14:52, 25 April 2007 (UTC)
[edit] Two bugs
This is a great extension, but there are two pretty simple but significant bugs i've encountered.
- MediaWiki installations with a db table prefix will not work with this extension, as all three queries did not take this into account.
- The article links in the resulting table do not have their namespaces in them.
Both are pretty easily fixed.
Additional:
- It does not work if the template does not use named parameters
Suggested: (sorry lots of debug lines... I don't have any PHP background. took apart this ext slowly to try to understand it.)
<?php
/*******************************************************************
* MediaWiki Extension: Template Table
* by CS "Kainaw" Wagner <http://shaunwagner.com>
********************************************************************
********************************************************************
* DESCRIPTION
* This adds a ttable tag to MediaWiki to show template items from
* all pages in a single table. This is very useful for creating an
* automatically generated comparison between common articles.
********************************************************************
* USAGE
* Simplest usage is <ttable template='TemplateName'></ttable>.
*
* !!!IMPORTANT NOTE!!!
* For technical reasons, TemplateName is case-sensitive. That means
* that if you have Template:MyTemplate, you must use:
* <ttable template='MyTemplate'></ttable>
* However, it will find data in pages that use {{mytemplate ...}}
* You just have to make sure the value in the ttable tag matches
* the case of the actual template page.
*
* ADVANCED USAGE
* You can choose which headers to display with the headers option:
* <ttable template='MyTemplate' headers='Name|Address'></ttable>
* A | (vertical bar/pipe) separates each header. If you do not
* supply this option, all headers used will be shown.
*
* You may customize the table with the standard table tags:
* border, cellspacing, cellpadding, class, align, and style.
*
* Any text between <ttable> and </ttable> will appear ABOVE the
* table that is produced.
********************************************************************
* SPECIAL NOTE
* A side effect of how this script works is that you can have fields
* that display in this table and not in the actual template. If you
* have made a template, you know that you can ignore variables that
* are sent to it. If you do that and you do not ignore them in this
* table, they will show up here and not in the template.
********************************************************************
* INSTALLATION
* Put this in the extensions directory and include it in your
* LocalSettings.php file before the last ?> like:
* include("extensions/templatetable.php");
********************************************************************
* CUSTOMIZATION
* The only thing I think anyone would customize is the text of the
* "article" link. That is easy to change. Just search the script
* for "article" and you will see it. It looks like:
* $output.= "article";
* Change it to whatever you like (it can even be an image).
Added:
*prefixes
*check if mediawiki
*argument: styleclass (for table formatting)
Changed:
*to stop supporting named parameters and support only unnamed parameters
(commented out, can be restored easily)
********************************************************************/
//if not MediaWiki - abort (security feature)
if( !defined( 'MEDIAWIKI' ) ) {
die();
}
// Register the tag.
$wgExtensionFunctions[] = "wfTemplateTable";
$wgExtensionCredits['parserhook'][] = array(
'name' => 'TemplateTable',
'author' => 'CS Wagner (modified)',
'url' => 'http://meta.wikimedia.org/wiki/TemplateTable_extension',
'description' => 'Auto-generates a table derived from the template parameters of every instance of a template',
);
function wfTemplateTable()
{
global $wgParser;
$wgParser->setHook("ttable", "renderTemplateTable");
}
/**
* This function renders the TemplateTable.
* $input = text between <ttable> and </ttable>
* $argv = key/val array of options in the <ttable> tag.
*/
function renderTemplateTable($input, $argv)
{
global $wgScript;
// Print a nice error if template is not given.
if(!isset($argv["template"])) return "TemplateTable Error: No template given. Please use the format <tt><ttable template='Name Of Template'>...</ttable></tt>";
// Header type. If "headers" is given, use that.
// Otherwise, use dynamic headers (every variable used in the template)
$dynhead = true;
$headers = array();
if(isset($argv["headers"]))
{
$headers = explode("|", $argv["headers"]);
$dynhead = false;
}
// Preset output to the input (stuff between <ttable> and </ttable>
$output = $input;
//debug $output .= "Hello..." . mysql_escape_string($argv["template"]);
// Now the hard part: Hunt down the template data...
/***************************************************************
* Instead of commenting all through this, I will just describe
* it here:
* The goal is to have an array ($data) that looks like:
* $data[page name] = array(key1=>val1, key2=>val2...);
*
* Step 1:
* Get a list of all Page IDs that use the template.
* For every page found...
* Step 2:
* Get the last Revision ID for each Page ID.
* Step 3:
* Get the text for the last Revision.
* Step 4:
* Extract the template text from the Revision.
* Step 5:
* If there is template text, parse it and create an item for
* the $data array.
****************************************************************/
global $wgDBprefix;
$prefix = $wgDBprefix; // add this so because my wiki uses prefixes in front of table names
$data = array();
$query = "select * from " . $prefix . "templatelinks left join " . $prefix . "page on " . $prefix . "templatelinks.tl_from=" . $prefix . "page.page_id where tl_title='".$argv["template"]."' order by page_title";
//This unfortunately selects records irrespective of case: ABC, Abc, abc, etc
$result = mysql_query($query);
while($row = mysql_fetch_object($result))
{
//debug: $output .= "\n\n=". $row->page_title; //Page title is the title of the page
$q2 = "select rev_text_id from " . $prefix . "revision where rev_page=".$row->page_id." order by rev_timestamp desc limit 1";
if(($res2 = mysql_query($q2)) && ($row2 = mysql_fetch_object($res2)))
{
$q3 = "select * from " . $prefix . "text where old_id=".$row2->rev_text_id;
if(($res3 = mysql_query($q3)) && ($row3 = mysql_fetch_object($res3)))
{
//$row3->old_text is the whole text of the file
//debug(show whole file text): $output .= "\n"."\n"."===".$row2->rev_text_id."==="."\n"."\n". $row3->old_text ;
$row3->old_text = str_replace("\n", " ", $row3->old_text); //Unsure of function... works well without
//Works out starting postion of {{Template ... to its end ...}} so that can extract/copy this information
$start = stripos($row3->old_text, "{{".$argv["template"]);
//If you specifically only use your template at the beginning of your file:
//Only accepts this file if the header is at the beginning of the file, else ignore
// if($start == 0)
// {
if($start === false) continue;
$end = strpos($row3->old_text, "}}", $start);
if($end === false) continue;
//Debug (position)// $output .= "\n"."\n"."===xx2xx".$start. " to ".$end."==="."\n"."\n";
//The extracted wanted text in raw form
$tmp = substr($row3->old_text, $start+strlen("{{".$argv["template"]), $end-strlen("{{".$argv["template"]));
//Debug (raw extracted text)// $output .= "\n\n==".$tmp ;
$item = array();
$kvs = explode("|", $tmp); //separate out each of the parameters separated by "|"
//changed so that it will work with template unnamed parameters
$key = 0 ; //counter
foreach($kvs as $kv)
{
$kv = trim($kv);
if($kv == "") continue;
// $eq = strpos($kv, "=");
// $output .= "\n"."\n"."===xxEq5xx: ".$eq;
// if($eq === false) continue;
// $key = strtolower(trim(substr($kv, 0, $eq)));
$key = $key + 1;
// $val = trim(substr($kv, $eq+1));
$val = $kv;
$item[$key] = $val;
//debug (all items)// $output .= "\n\n*item(". $key. ")=" .$item[$key];
if($dynhead && !in_array($key, $headers)) array_push($headers, $key); //probably can delete this line too
}
if(sizeof($item) > 0)
$data[$row->page_title] = $item;
//enable this for: if (beginning of file):// }
}
}
}
// Skip this if there's no data to display.
// Otherwise, create our pretty little table!
if(sizeof($data) < 1)
{
// Print a nice (no data found) message:
$output.= "Template ".$argv["template"]." has no data.";
}
else
{
$output.= "<table class=\"".$argv["styleclass"]. "\"";
/*Not needed for unnamed parameters
foreach($argv as $key=>$val)
{
if($key == "template" || $key == "headers") continue;
$output.= " $key=\"$val\"";
}
$output.= ">\n";
$output.= "<tr><th> </th>\n";
foreach($headers as $header)
{
$output.= "<th>$header</th>\n";
}
$output.= "</tr>\n";
*/
foreach($data as $index=>$item) // FOREACH ( array AS key/index => Value of current item (in this case item[array] )
{
$output.= "<tr><td align='center'><a href='".$wgScript."?title=".urlencode($index)."'>";
$output.= $index;//"article"; // Changing this line will change the text that appears in the row heading
$output.= "</a></td>\n";
foreach($headers as $header)
{
$header = strtolower($header);
if(isset($item[$header]))
$output.= "<td>".$item[$header]."</td>\n";
else
$output.= "<td> </td>\n";
}
$output.= "</tr>\n";
}
$output.= "</table>\n";
//Display the output data
}
return $output;
}
?>
Note that the above conversation may have been edited or added to since the transfer. If in doubt, check the edit history.
[edit] Cache Problem
While the suggestions and bugs above are nice, there is a crippling problem with this extension - it suffers from the MediaWiki cache. When a template is changed, the ttable needs to change also. How can that be done? The templates do not know if they are part of a ttable, so there's no reasonable way to get them to flush the cache. Because the ttable is cached, it isn't processed - which means that the ttable can't force itself to flush the cache. It would be nice if there was some magical keyword that would tell MediaWiki to never cache a certain page, then that could be added to ttable pages. Kainaw 19:16, 25 July 2007 (UTC)

