From MediaWiki.org
CREATE TABLE datatable_data (
dtd_page INT(8) UNSIGNED NOT NULL DEFAULT 0,
dtd_table CHAR(255) NOT NULL,
c1 TEXT(1024) NOT NULL,
c2 TEXT(1024),
c3 TEXT(1024),
c4 TEXT(1024),
c5 TEXT(1024),
c6 TEXT(1024),
c7 TEXT(1024),
c8 TEXT(1024),
c9 TEXT(1024),
c10 TEXT(1024),
c11 TEXT(1024),
c12 TEXT(1024),
c13 TEXT(1024),
c14 TEXT(1024),
c15 TEXT(1024),
c16 TEXT(1024),
c17 TEXT(1024),
c18 TEXT(1024),
c19 TEXT(1024),
c20 TEXT(1024),
KEY datatable_data_page(dtd_page),
KEY datatable_data_table(dtd_table)
);
grant select on datatable_data to wikiuser;
grant insert on datatable_data to wikiuser;
grant delete on datatable_data to wikiuser;
[edit] Extension Source
<?php
$wgExtensionCredits['parserhook'][] = array(
'name' => 'DataTable',
'version' => ExtDataTable::$mVersion,
'author' => '[http://www.mediawiki.org/wiki/User:RV1971 RV1971]',
'url' => 'http://www.mediawiki.org/wiki/Extension:DataTable',
'description' => 'store data in a table and retrieve it on other pages'
);
// instance of this extension class
$wgExtDataTable = new ExtDataTable();
// register the extension
$wgExtensionFunctions[] = array( &$wgExtDataTable, "setup" );
$wgHooks['LanguageGetMagic'][] = array( &$wgExtDataTable,
"onLanguageGetMagic" );
$wgHooks['ArticleDeleteComplete'][] = array( &$wgExtDataTable,
"onArticleDeleteComplete" );
$wgHooks['ArticleSaveComplete'][] = array( &$wgExtDataTable,
"onArticleSaveComplete" );
class ExtDataTable
{
public static $mVersion = "0.3";
public $mDataBuffer = array();
public function setup() {
global $wgParser;
// parser functions
$wgParser->setFunctionHook( 'data', array( &$this, 'data' ) );
// tags
$wgParser->setHook( 'datatable', array( &$this, "datatable" ) );
}
public function onLanguageGetMagic( &$magicWords, $langCode ) {
$magicWords['data'] = array( 0, 'data' );
return true;
}
// hook to delete data when an article is deleted
public function onArticleDeleteComplete( $article )
{
$dtd_page = $article->getID();
$dbr =& wfGetDB( DB_MASTER );
// Delete all data for this page.
$dbr->delete( 'datatable_data', array( 'dtd_page' => $dtd_page ) );
return true;
}
// hook to save data when an article is saved
public function onArticleSaveComplete( $article )
{
$dtd_page = $article->getID();
$dbr =& wfGetDB( DB_MASTER );
// Delete all data for this page.
$dbr->delete( 'datatable_data', array( 'dtd_page' => $dtd_page ) );
// Re-insert all data that were created when parseing this page
foreach( $this->mDataBuffer as $record )
{
$record['dtd_page'] = $dtd_page;
$dbr->insert( 'datatable_data', $record );
}
return true;
}
// display and/or store data
public function datatable( $input, $args, &$parser)
{
extract( $args );
$output = "";
// parse head tag, if any
if( preg_match( '+<head>(.*)</head>+s', $input, $matches ) )
{
$head = $matches[1];
$input = str_replace( $matches[0], '', $input );
if( $class )
$class = "class='$class'";
$output .= "{| $class\n|-\n$head\n|-\n";
}
// parse template tag, if any
if( preg_match( '+<template>(.*)</template>+s', $input, $matches ) )
{
$inlinetemplate = $matches[1];
$input = str_replace( $matches[0], '', $input );
for( $i = 1; $i <= 20; $i++ )
$param_array[] = '{{{' . $i . '}}}';
}
$data = preg_split( "/[\n\r]+/", $input );
foreach( $data as $row ) {
if( $row > '' )
{
$record = array();
foreach($this->splitRowByPipe( $row ) as $key => $value)
$record["c" . ($key + 1)] = $value;
if( $template )
{
// explicitely name positional parameters
// in order to allow equal signs within parameters
$count = 0;
foreach( $record as $key => $arg )
$args[$key] = ++$count . "=" . $arg;
$output .= '{{' . $template . '|'
. $this->templateArgString( $record ) . "}}\n";
}
elseif( $inlinetemplate )
{
$output .= str_replace( $param_array, $record,
$inlinetemplate );
}
else
$output .= "| " . implode( "\n| ", $record ) . "\n|-\n";
if( $table )
{
$record["dtd_table"] = $table;
$this->mDataBuffer[] = $record;
}
}
}
if( $head )
$output .= "|-\n|}\n";
if( $display != "no" )
return $parser->recursiveTagParse( $output );
}
// explicitely name positional parameters
// in order to allow equal signs within parameters
function templateArgString( $args )
{
$count = 0;
foreach($args as $key => $arg)
$args[$key] = ++$count . "=" . $arg;
return implode( "|", $args );
}
// split a pipe-separated row into an array
// such that pipes within template calls are protected
function splitRowByPipe( $string )
{
foreach(preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY) as $c)
{
switch($c)
{
case '{' :
case '[' :
$substring .= $c;
$par++;
break;
case '}' :
case ']' :
$substring .= $c;
$par--;
break;
case '|' :
if( !$par )
{
$string_array[] = $substring;
$substring = "";
}
else
$substring .= $c;
break;
default :
$substring .= $c;
}
}
$string_array[] = $substring;
return $string_array;
}
// retrieve data
function data( &$parser, $table, $columns, $template, $condition, $sort,
$p1, $p2, $p3, $p4 )
{
$dbr =& wfGetDB( DB_SLAVE );
$result = "";
$resarray = array();
if( !$columns )
$columns = "*";
if( $condition )
$condition = "and " . $condition;
if( $sort )
$sort = "order by " . $sort;
$res = $dbr->query( "select distinct $columns from datatable_data where dtd_table = '$table' $condition $sort" , __METHOD__ );
while( $record = $dbr->fetchRow( $res ) )
{
// fetchRow returns an array with both numeric and text keys
// we keep only the numeric keys
foreach( $record as $key => $value )
if( !is_int( $key ) )
unset( $record[$key] );
if( $columns == "*" )
{
// all columns except page ID and table name
unset($record[0]);
unset($record[1]);
}
if( $template )
$result .= "{{{$template}|" . $this->templateArgString( $record )
. "|p1=$p1|p2=$p2|p3=$p3|p4=$p4}}";
else
$resarray[] = implode( ", ", $record );
}
if( !$template )
$result = implode( "; ", $resarray );
$dbr->freeResult($res);
return $result;
}
}