Extension:TimelineTable

From MediaWiki.org

Jump to: navigation, search

       

Manual on MediaWiki Extensions
List of MediaWiki Extensions
Crystal Clear action run.png
TimelineTable

Release status: beta

Implementation  Tag
Description Generate a timeline contained in html table from a list of events
Author(s)  Thibault Marin
License GNU Lesser General Public License
Download no link

check usage (experimental)

Contents

[edit] What can this extension do?

This extension is a simple tag extension that generates timelines contained in html tables. From a list of events in the correct format, the extension will generate an html table (with a line for each event) spanning the columns over the event time range. Table formatting uses CSS defined in mediawiki:common.css file.

[edit] Usage

In your Mediawiki code, enter the following:

<timeline title="This is the title" footer="This is a timeline">
2008-01|2009-06|event1|some comment
2008-12|2009-07|event2|something else
2009-02|2010-12|event3
</timeline>

This will generate a html table with three rows (one per event), and a column for each month between the first month of the earliest event to the last month of the last event.

To modify the table format, define CSS classes in mediawiki:common.css. Here is a sample CSS code.

/* Timeline */
table.tl_table{
	border-width: thin;
	border-spacing: 4px;
	border-style: outset;
	border-color: black;
	border-collapse: separate;
	background-color: white;
	-moz-border-radius: 9px;
}
 
th.tl_title{
	text-transform: uppercase
	text-align: center;
	border-width: 1px;
	padding: 4px;
	border-style: outset;
	border-color: blue;
	background-color: rgb(243, 248, 252);
	-moz-border-radius: 9px;
}
 
th.tl_years{
	text-align: center;
	font-style: italic;
	border-width: 1px;
	padding: 4px;
	border-style: outset;
	border-color: blue;
	background-color: rgb(243, 248, 252);
	-moz-border-radius: 9px;
}
 
th.tl_months{
	text-align: center;
	border-width: 1px;
	padding: 4px;
	border-style: outset;
	border-color: blue;
	background-color: rgb(243, 248, 252);
	-moz-border-radius: 9px;
}
 
td.tl_freetime{
	background-color: rgb(187, 210, 236);
	border-width: 1px;
	border-color: black;
	border-style: inset;
	-moz-border-radius: 9px;
}
 
td.tl_event{
	text-align: center;
	padding: 4px;
	background-color: rgb(61, 114, 194);
	border-width: 1px;
	border-color: white;
	border-style: inset;
	color: white;
	-moz-border-radius: 9px;
}
 
td.tl_foot{
	text-align: center;
	padding: 4px;
	background-color: rgb(243, 248, 252);
	border-width: 1px;
	border-color: blue;
	border-style: ridge;
	color: gray;
	-moz-border-radius: 9px;
}
 
thead.tl_header{}
tbody.tl_body{}
tfoot.tl_footer{}

[edit] Download instructions

Please cut and paste the code found below and place it in $IP/extensions/TimelineTable/timeline.php. Note: $IP stands for the root directory of your MediaWiki installation, the same directory that holds LocalSettings.php.

[edit] Installation

To install this extension, add the following to LocalSettings.php:

require_once("$IP/extensions/TimelineTable/timeline.php");

[edit] Configuration parameters

Extension contains two parameters when creating a table:

  • title - Defines the title that will be put at the top of the table.
  • footer - Defines the table footer text.

[edit] User rights

[edit] Code

<?php
 
/**
 * ExampleExtension - this extension is an example that does nothing
 *
 * To activate this extension, add the following into your LocalSettings.php file:
 * require_once('$IP/extensions/Example.php');
 *
 * @ingroup Extensions
 * @author Thibault Marin
 * @version 1.0
 * @link http://www.mediawiki.org/wiki/Extension:TimelineTable Documentation
 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
 */
 
/**
 * Protect against register_globals vulnerabilities.
 * This line must be present before any global variable is referenced.
 */
if( !defined( 'MEDIAWIKI' ) ) {
	echo( "This is an extension to the MediaWiki package and cannot be run standalone.\n" );
	die( -1 );
}
 
// Extension credits that will show up on Special:Version    
$wgExtensionCredits['validextensionclass'][] = array(
	'name'         => 'TimelineTable',
	'version'      => '1.0',
	'author'       => 'Thibault Marin', 
	'url'          => 'http://www.mediawiki.org/wiki/TimelineTable',
	'description'  => 'Create a table containing a timeline'
);
 
// Parameters
$wgTimelineLineSeparator="\n"; // Separator for parsing lines of the input.
$wgTimelineFieldSeparator="\|"; // Separator for parsing a single event (lcontained in a line).
$wgTimelineDateSeparator="-"; // Separator for parsing the date of an event.
 
//Avoid unstubbing $wgParser on setHook() too early on modern (1.12+) MW versions, as per r35980
if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
	$wgHooks['ParserFirstCallInit'][] = 'efTimelineParserInit';
	$wgHooks['ParserAfterTidy'][]='efTimelineAfterTidy';
	$wgExtensionFunctions[] = 'efTimelineParserInit';
} else { // Otherwise do things the old fashioned way
	$wgHooks['ParserAfterTidy'][]='efTimelineAfterTidy';
	$wgExtensionFunctions[] = 'efTimelineParserInit';
}
 
function efTimelineParserInit() {
	global $wgParser;
	$wgParser->setHook( 'timeline', 'efTimelineRender' );
	return true;
}
 
function efTimelineRender( $input, $args, $parser ) {
 
	// Extract parameters from global veriables
	global $wgTimelineFieldSeparator;
	global $wgTimelineDateSeparator;
	global $wgTimelineLineSeparator;
 
	// Parse tag arguments
	$title=$args['title'];
	$footer=$args['footer'];
 
	// Caculate time range
	$lines=split($wgTimelineLineSeparator,trim($input));
	// Get the first and last years in the timeline
	$startYear=9999; // Should work for a while
	$endYear=-1;
	foreach ( $lines as $val )
	{
		$year=split($wgTimelineDateSeparator,trim($val),2);
		if ( (int)($year[0])<$startYear ){$startYear=(int)($year[0]);}
		$tmp=split($wgTimelineFieldSeparator,trim($val));
		$year=split($wgTimelineDateSeparator,trim($tmp[1]),2);
		if ( (int)($year[0])>$endYear ){$endYear=(int)($year[0]);}
	}
	// Find the number of months for each year
	$curStartMonth=13;
	$curEndMonth=0;
	foreach ( $lines as $val )
	{
		$tmp=split($wgTimelineFieldSeparator,trim($val));
		list($eventStartYear,$eventStartMonth)=split($wgTimelineDateSeparator,$tmp[0]);
		list($eventEndYear,$eventEndMonth)=split($wgTimelineDateSeparator,$tmp[1]);
		$eventStartYear=((int)$eventStartYear);
		$eventEndYear=((int)$eventEndYear);
		$eventStartMonth=(int)$eventStartMonth;
		$eventEndMonth=(int)$eventEndMonth;
		if ( $eventStartYear==$startYear )
		{
			if ( $eventStartMonth<$curStartMonth )
			{
				$curStartMonth=$eventStartMonth;
			}
		}
		if ( $eventEndYear==$endYear )
		{
			if ( $eventEndMonth>$curEndMonth )
			{
				$curEndMonth=$eventEndMonth;
			}
		}
	}
	$nMonths[]=12-$curStartMonth+1;
	for ( $year=$startYear+1 ; $year<$endYear ; $year++)
	{
		$nMonths[]=12;
	}
	$nMonths[]=$curEndMonth;
	// Number of years to display
	$nYears=$endYear-$startYear+1;
	// $nColumns contains the total number of months over the time reange
	$nColumns=array_sum($nMonths);
	for ( $year=$startYear ; $year<=$endYear ; $year++ )
	{
		if ( $year==$startYear )
		{
			$startMonth[]=12-$nMonths[$year-$startYear];
		}
		else
		{
			$startMonth[]=0;
		}
		if ( $year==$endYear )
		{
			$endMonth[]=$nMonths[$year-$startYear];
		}
		else
		{
			$endMonth[]=12;
		}
	}
 
	// Additional parameters
	// List of the months as they should be displayed in the timeline cell
	$monthList=array( "J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D");
	//$monthList=array( "January" => "J", "February" => "F", "March" => "M", "April" => "A", "May" => "M", "June" => "J", "July" => "J", "August" => "A", "September" => "S", "October" => "O", "November" => "N", "December" => "D");
	//$monthList=array( "January" , "February" , "March" , "April" , "May" , "June" , "July" , "August" , "September" , "October" , "November" , "December" );	
 
	// Create the timeline: $timeline_str will contain the html code for the table
 
	// Start the table
	$timeline_str='<table class=tl_table>';
 
	// Header: title line
	$timeline_str=$timeline_str . '<thead class=tl_header>';
	$timeline_str=$timeline_str . '<tr>';
	$timeline_str=$timeline_str . '<th colspan="' . $nColumns . '" class=tl_title>';
	$timeline_str=$timeline_str . htmlspecialchars($title);
	$timeline_str=$timeline_str . '</th>';
	$timeline_str=$timeline_str . '</tr>';
	// Header: Years timeline
	$timeline_str=$timeline_str . '<tr>';
	for ( $year=$startYear ; $year<=$endYear ; $year++ )
	{
		$timeline_str=$timeline_str . '<th colspan="' . $nMonths[$year-$startYear] . '" class=tl_years>';
		$timeline_str=$timeline_str . $year;
		$timeline_str=$timeline_str . '</th>';
	}
	$timeline_str=$timeline_str . '</tr>';
	$timeline_str=$timeline_str . '<tr>';
	// Header: Months
	for ( $year=$startYear ; $year<=$endYear ; $year++ )
	{
		for ( $month=$startMonth[$year-$startYear] ; $month<$endMonth[$year-$startYear] ; $month++ )
		{
			$timeline_str=$timeline_str . '<th class=tl_months>';
			$timeline_str=$timeline_str . $monthList[$month];
			$timeline_str=$timeline_str . '</th>';
		}
	}
	$timeline_str=$timeline_str . '</tr>';
	$timeline_str=$timeline_str . '</thead>';
 
	// Footer
	$timeline_str=$timeline_str . '<tfoot class=tl_footer><tr><td colspan="' . $nColumns . '" class=tl_foot>';
	$timeline_str=$timeline_str . htmlspecialchars($footer);
	$timeline_str=$timeline_str . '</td></tr></tfoot>';
 
	// Body: Events (display one event per row)
	$timeline_str=$timeline_str . '<tbody class=tl_body>';
	foreach ( $lines as $val )
	{
		// Parse the event dates and content
		list($eventStartDate,$eventEndDate,$text,$comment)=split($wgTimelineFieldSeparator,$val);
		list($eventStartYear,$eventStartMonth)=split($wgTimelineDateSeparator,$eventStartDate);
		list($eventEndYear,$eventEndMonth)=split($wgTimelineDateSeparator,$eventEndDate);
		$eventStartYear=(int)$eventStartYear;
		$eventStartMonth=(int)$eventStartMonth;
		$eventEndYear=(int)$eventEndYear;
		$eventEndMonth=(int)$eventEndMonth;
 
		// Find the number of months between the first month of the timeline and the first month of the event
		$nPreviousMonths=array_sum(array_slice($nMonths,0,$eventStartYear-$startYear));
		$nPreviousMonths=$nPreviousMonths+$eventStartMonth-$startMonth[$eventStartYear-$startYear]-1;
 
		// Find the length of the event (in months)
		$nEventMonths=12-$eventStartMonth+1;
		$nEventMonths=$nEventMonths+$eventEndMonth;
		$nEventMonths=$nEventMonths+12*($eventEndYear-$eventStartYear-1);
 
		// Define the number of months between the end of the event and the end of the timeline
		$nRemainingMonths=$nColumns-$nPreviousMonths-$nEventMonths;
 
		// Merge the month before the event into a 'freetime' cell
		$timeline_str=$timeline_str . '<tr>';
		if ( $nPreviousMonths > 0 )
		{
			$timeline_str=$timeline_str . '<td colspan="' . $nPreviousMonths . '" class=tl_freetime></td>';
		}
 
		// Create the event cell
		$timeline_str=$timeline_str . '<td colspan="' . $nEventMonths . '" class=tl_event>';
		$timeline_str=$timeline_str . htmlspecialchars($text). '<br>(' . htmlspecialchars($comment) . ')';
		$timeline_str=$timeline_str . '</td>';
 
		// Merge the month after the event into a 'freetime' cell
		if ( $nRemainingMonths > 0 )
		{
			$timeline_str=$timeline_str . '<td colspan="' . $nRemainingMonths . '" class=tl_freetime></td>';
		}
		$timeline_str=$timeline_str . '</tr>';		
	}
	$timeline_str=$timeline_str . '</tbody>';
 
	// Finish table
	$timeline_str=$timeline_str . '</table><br />';
 
	// Define the html code as a marker, then change it back to text in 'efTimelineAfterTidy'. This is done to prevent the html code from being modified afterwards.
	global $markerList;
	$makercount = count($markerList);
	$marker = "xx-marker".$makercount."-xx";
	$markerList[$makercount] = $timeline_str;
	return $marker;
}
 
function efTimelineAfterTidy(&$parser, &$text) {
	// find markers in $text
	// replace markers with actual output
	global $markerList;
	for ($i = 0; $i<count($markerList); $i++)
	$text = preg_replace('/xx-marker'.$i.'-xx/',$markerList[$i],$text);
	return true;
}
 
// TODO
/*
	/ CSS file for table and define classes for each type of cell -> common.css
	- Finish syntax YYYY-MM|YYYY-MM|text|color|bgcolor|comment
	- Options
	- Check execution time
	- Clear code
	- Check inputs (date order, etc.)
*/
?>

[edit] See also

Extension:EasyTimeline