Extension:TimelineTable
From MediaWiki.org
|
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.) */ ?>