Extension:TODOListProgressBar

From MediaWiki.org
Jump to navigation Jump to search
MediaWiki extensions manual
Crystal Clear action run.svg
TODO List Progress Bar
Release status: stable
Implementation Tag
Description Implements a TODO list progress bar that can be used for tracking the progress of the TODO list (or other list).
Author(s) Vadtectalk
Latest version 20100621.0 (2010-06-21)
MediaWiki 1.15.X, 1.16.X
PHP 5.2.X
License ISC License
Download Copy and Paste
Translate the TODOListProgressBar extension if it is available at translatewiki.net
Check usage and version matrix.

What can this extension do?[edit]

This extension is aimed at making the process of tracking the progress of a TODO list (or other list) easier. When creating your TODO list, you include the <todo /> tag along with each item. As you complete an item, you update its status accordingly and the rest of the extension takes care of displaying the nice progress bar for a visual indicator as to the progress of completing the TODO list. In addition, it places a status string where the tag is located so that your TODO list will tell you which items are complete and which arent.

Usage[edit]

If you do not want to keep referring to this page or the code, place a <todo type="help" /> tag somewhere on a page and it will display the help contents for you. Please note: The most current documentation will always be within the extension itself; it is highly recommended you use <todo type="help" /> so you are sure the information you are given matches the version of TODO List Progress Bar you are running.

Help for TODO List Progress Bar

The <todo /> tag has multiple modes of operation:

  • Defaults Mode (Not Implemented)
    • <todo type="defaults" ... />
    • Sets defaults for the following items and progress bars such as color, width, height, etc.
  • Graphic Mode
    • <todo type="graphic" ...>Caption</todo>
    • <todo type="graphic" ... /> (No caption given)
    • Used for displaying a progress bar for a list.
  • Help Mode
    • <todo type="help" />
    • Renders the help text you are reading at this moment.
  • Item Mode
    • <todo type="item" ...>Item</todo>
    • <todo type="item" ... />Item
    • Used for adding items to a list.
  • Progress Mode
    • <todo type="progress" ...>Caption</todo>
    • <todo type="progress" ... />
    • Simple progress bar that isn't dependent upon a list.
  • Values Mode
    • <todo type="values" ... />
    • Outputs list data in a table.

All <todo /> tags require the "type" parameter. It only has the following values:

  • "defaults" (Not Implemented)
  • "graphic"
  • "help"
  • "item"
  • "progress"
  • "values"


The type parameter tells the code what to do with the tag. As such, it has no default value.

Modes of operation parameter list
Tag Mode Parameter Description
Defaults N/A Not implemented yet
Graphic $text The text for the progress bar caption. This will be the text that is between the
<todo type="graphic" ...></todo> tags.

This parameter is optional.

color The color that will be used to fill the progress bar. The default value is black. This parameter is any valid hex RGB value or HTML color.

This parameter is optional.

group The group of items that are going to be rendered. This parameter is a string value. The default value for this parameter is "global". Group names cannot contain commas as part of their name.

This parameter is optional.

height The height (in pixles, aka "px") of the progress bar. The default value is 10px. This parameter is an integer value.

This parameter is optional.

multilist This is a single word parameter that allows the combining of multiple lists into a single progress bar. This is useful for when you want to display lists of data that are separate but want to have a single progress bar to cover all of the lists. The lists to be combined are given in the "group" parameter separated by commas (group names cannot contain commas). The "noerase" parameter works with this parameter.

This parameter is optional.

noerase This is a single word parameter that will prevent the data for a group from being deleted. This could be useful for implementing an "advanced features todo list". In such a list, the basic features are listed first (which then display their own progress bar) followed by the advanced features (which then displays another progress bar containing both sets of items).

This parameter is optional.

width The width (in pixels, aka "px") of the progress bar. The default value is 400px. This parameter is an integer value.

This parameter is optional.

It is important to note that you cannot (at this point) place the progress bar tag before the item tags. This is due to the fact that HTML is parsed top down, as well as the fact that I have not added any AJAX that would bypass this restriction. Maybe for the next version...
Help N/A Displays this help text.
Item $text The text for the item. This will be the text that is between the <todo type="item" ...></todo> tags.

This parameter is optional.

group The group an item belongs to. This parameter is a string value. The default value for this parameter is "global". Group names cannot contain commas as part of their name.

This parameter is optional.

name The name of the item. This parameter is a string value and must be unique for the group the item is in. If this parameter is not given, a unique value will be assigned.

This parameter is optional.

nostatus This is a single word parameter that will hide the status indicator. This can be useful if you just want to track items but aren't worried about them being marked in the list itself.

This parameter is optional.

percent (Not Implemented) Allows setting the percent completion of an item. This way, if you have a very large item and want to track its completetion state, but it cannot be broken up into smaller items, you can still show how complete it is.

This parameter is optional.

status Determines the status of the item. The default value is "incomplete".

Valid values are:

  • The item is complete.
  • "complete"
  • "completed"
  • "done"
  • "finished"
  • The item is being worked on but is not completed (counts as incomplete).
  • "ip"
  • "in progress"
  • "working"
  • The status of the item is unknown (counts as incomplete).
  • "unknown"
  • The item is incomplete or has not been started on.
  • "incomplete"
  • "pending"
  • "held"

This parameter is optional.

value The "point value" of this item. The default value for any item is 1. This parameter is an integer value. This changes the point value of the item, and changes the final point value of the entire group.

This parameter is optional.

Progress color The color that will be used to fill the progress bar. The default value is black. This parameter is any valid hex RGB value or HTML color.

This parameter is optional.

current The current value of the progress bar. The default value is 0. This parameter is an integer value.

This parameter is optional.

height The height (in pixles, aka "px") of the progress bar. The default value is 10px. This parameter is an integer value.

This parameter is optional.

end The end value of the progress bar. The default value is 100. This parameter is an integer value.

This parameter is optional.

start The start value of the progress bar. The default value is 0. This parameter is an integer value.

This parameter is optional.

width The width (in pixels, aka "px") of the progress bar. The default value is 400px. This parameter is an integer value.

This parameter is optional.

Values group The group to display data for. The default value for this parameter is "global". Group names cannot contain commas as part of their name. This parameter is a string value.

This parameter is optional.

Examples[edit]

Examples can be found *here*. These are working examples.

NOTE: Sorry all. The wiki I was using for my examples was taken down with out my knowledge. I will get some examples up ASAP. - Vadtec 16:25, 27 October 2010 (CST)

If you think of an example that should be included, let me know via the discussion page.

Download instructions[edit]

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

Installation[edit]

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

require_once("$IP/extensions/TODOListProgressBar/TODOListProgressBar.php");

Code[edit]

License[edit]

Copyright © 2010 by Vadtec, vadtec@vadtec.net ("VADTEC")

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND VADTEC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VADTEC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Credits[edit]

A portion of this code is based directly on Progressbar, I have merely modified it to work with my needs. I take no credit for the portion that is based on Progressbar.

Change Log[edit]

  • 20100612.0
    • Inital release
  • 20100613.0
    • Changed all the div elements to use the inline display style rather than the block style.
  • 20100613.1
    • Realized I added an inline where I shouldn't have.
    • Fixed some nasty XSS bugs I had introduced. (Thanks to Max Semenik for noticing this.)
    • Changed the <todo type="item" ... /> tag to allow text to appear between the tags and be displayed along with the status indicator.
  • 20100613.2
    • Made the name parameter optional to simplify the tag syntax.
    • Added a "nostatus" parameter to the item tag.
    • Added an "unknown" status value.
  • 20100613.3
    • Fixed a bug related to "nostatus" causing items marked with nostatus to not be calcualted in the final tally.
  • 20100613.4
    • Added code to allow the parsing of wikitext from within the <todo></todo> tags. (Made it XSS safe.)
    • Added a "noerase" parameter to the graphic tag.
  • 20100614.0
    • Added the "multilist" parameter to allow combining of data sets into one progress bar.
    • Stubbed in part of the "values" tag code.
  • 20100614.1
    • Added a "help" type that displays the help as a wiki page.
  • 2010614.2
    • Added the "progress" type for displaying simple progress bars.
  • 20100621.0
    • Added the "values" type for displaying the list data in tabular form.
    • Added the ISC license to the code.

Code[edit]

<?php
/*
 * TODO List Progress Bar - A MediaWiki Extension
 *
 *  Author: Vadtec (vadtec@vadtec.net)
 *          http://www.mediawiki.org/wiki/User:Vadtec
 *    Date: 2010-06-21
 * Version: 20100621.0
 *
 * A portion of this code is based directly on Progressbar 0.2 
 * (http://www.mediawiki.org/wiki/Extension:Progressbar) from Rohit Kumbhar
 * (http://site.rohitkumbhar.com/). I have merely modified it to work with my
 * needs.
 *
 * To get help with the extension, place a <todo type="help" /> tag somewhere on
 * a wiki page. This will display the help section in a nicely wiki formatted
 * manner.
 *
 * ChangeLog
 *
 * 20100612.0
 *  Inital release
 *
 * 20100613.0
 *  Changed all the div elements to use the inline display style rather than the
 *  block style.
 *
 * 20100613.1
 *  Realized I added an inline where I shouldn't have.
 *  Fixed some nasty XSS bugs I had introduced. (Thanks to MaxSem,
 *  http://www.mediawiki.org/wiki/User:MaxSem, for noticing this.)
 *  Changed the <todo type="item" ... /> tag to allow text to appear between the
 *  tags and be displayed along with the status indicator.
 *
 * 20100613.2
 *  Made the name parameter optional to simplify the tag syntax.
 *  Added a "nostatus" parameter to the item tag.
 *  Added an "unknown" status value.
 *
 * 20100613.3
 *  Fixed a bug related to "nostatus" causing items marked with nostatus to not
 *  be calcualted in the final tally.
 *
 * 20100613.4
 *  Added code to allow the parsing of wikitext from within the <todo></todo>
 *  tags. (Made it XSS safe.)
 *  Added a "noerase" parameter to the graphic tag.
 *
 * 20100614.0
 *  Added the "multilist" parameter to allow combining of data sets into one
 *  progress bar.
 *  Stubbed in part of the "values" tag code.
 *
 * 20100614.1
 *  Added a "help" type that displays the help as a wiki page.
 *
 * 2010614.2
 *  Added the "progress" type for displaying simple progress bars.
 *
 * 20100621.0
 *  Added the "values" type for displaying the list data in tabular form.
 *  Added the ISC license to the code.
 *
 * Copyright © 2010 by Vadtec, vadtec@vadtec.net ("VADTEC")
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND VADTEC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL VADTEC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
 
if(!defined('MEDIAWIKI')) {
        echo("This is an extension to the MediaWiki package and cannot be run standalone.\n");
        die(-1);
}

define('TODOLIST_VERSION', '20100621.0');

$wgExtensionCredits['other'][] = array(
        'name' => 'TODO List Progress Bar',
        'author' => '[http://www.mediawiki.org/wiki/User:Vadtec User:Vadtec]', 
        'url' => 'http://www.mediawiki.org/wiki/User:Vadtec', 
        'description' => 'Creates a visual indicator based on a TODO list (or other list) of items and their completion state.',
        'version' => TODOLIST_VERSION
);

/* Add Extension Functions */
$wgExtensionFunctions[] = 'wfTODOListProgressBarSetup';

/* Setup */
function wfTODOListProgressBarSetup () {
    global $wgParser;
    $wgParser->setHook( 'todo', 'wfTODOListProgressBarParserHook' );
}

class TODOListProgressBar {
	static $data = array();
	static $values = array(); /* This is stubbed in for the future "types" tag. */
	static $type_values = array(
		1 => 'item',
		2 => 'graphic',
		3 => 'values', /* This is not implemented yet. */
		4 => 'progress',
		//5 => 'defaults', /* This is not implemented yet. */
		6 => 'help'
	);
	static $status_values = array(
		1 => 'complete',
		2 => 'completed',
		3 => 'done',
		4 => 'finished',
		5 => 'ip',
		6 => 'in progress',
		7 => 'working',
		8 => 'unknown',
		9 => 'incomplete',
		10 => 'pending',
		11 => 'held',
		12 => 'on hold'
	);
	
	static function processTag($text, $params, $parser) {
		$nostatus = FALSE;
		$noerase = FALSE;
		$multilist = FALSE;
		$text = htmlspecialchars(($text == NULL) ? "" : $text);
		$type = htmlspecialchars($params['type']);
		$name = htmlspecialchars($params['name']);
		$status = htmlspecialchars(($params['status'] != '') ? $params['status'] : "incomplete");
		$color = htmlspecialchars(($params['color'] != '') ? $params['color'] : "black");
		$group = htmlspecialchars(($params['group'] != '') ? $params['group'] : "global");
		$value = htmlspecialchars(is_numeric($params['value']) ? $params['value'] : 1);
		$height = htmlspecialchars(is_numeric($params['height']) ? $params['height'] : 10);
		$width = htmlspecialchars(is_numeric($params['width']) ? $params['width'] : 400);
		$start = htmlspecialchars(is_numeric($params['start']) ? $params['start'] : 0);
		$current = htmlspecialchars(is_numeric($params['current']) ? $params['current'] : 0);
		$end = htmlspecialchars(is_numeric($params['end']) ? $params['end'] : 100);
		if (array_key_exists('nostatus', $params) === TRUE)
			$nostatus = TRUE;
		
		if (array_key_exists('noerase', $params) === TRUE)
			$noerase = TRUE;
		
		if (array_key_exists('multilist', $params) === TRUE)
			$multilist = TRUE;

		/* Check to see if the type is valid. Everything below relies on this. */
		if (array_search($type, self::$type_values) === FALSE)
			return '<div style="display:inline;">[TODO: Invalid "type" parameter.]</div>';
					
		/*
		 * Check to see if the group exists. Avoids issues down below.
		 * Also, by checking to see if it exists before creating it, we don't run
		 * the risk of overwriting data.
		 * We have to skip multilist groups here though, otherwise we get weird groups.
		 */
		if (array_key_exists($group, self::$data) !== TRUE && $multilist === FALSE)
			self::$data[$group] = array();
		
		/* See if we are processing an item. */
		if ($type == "item") {
			/* First, check to see if they provided a name. */
			if ($name == "")
				/* The name parameter is empty, so just give it a numeric name. */
				$name = htmlspecialchars(count(self::$data[$group]) + 1);
			
			/* Next, check to see if the name is unique. */
			if (array_key_exists($name, self::$data[$group]) === TRUE)
				return '<div style="display:inline;">[TODO ITEM: The name "' . $name . '" is not unique for group "' . $group . '".]</div>';

			/* The name is unique so we can proceed. */
			self::$data[$group][$name] = array();
			
			/* Check to see if the status is valid. Remove the invalid name as well. */
			if (array_search($status, self::$status_values) === FALSE) {
				unset(self::$data[$group][$name]);
				return '<div style="display:inline;">[TODO ITEM: The status "' . $status . '" is invalid. Please check the status value.]</div>';
			}
			
			/* The status is valid, handle the value. */
			self::$data[$group][$name]['value'] = $value;
			
			/* Store the text in case the user wants to output the values later. */
			self::$data[$group][$name]['text'] = $text;
			
			/*
			 * Now we have to return a simple string to the user to reflect the status
			 * of the item. We also handle setting the completion status here.
			 */
			$completion = array_search($status, self::$status_values);
			self::$data[$group][$name]['complete'] = ($completion <= 4 ? TRUE : FALSE);
			$output = '<div style="display:inline;">';
			if ($nostatus === FALSE) {
				if ($completion <= 4) {
					$output .= 'COMPLETE ';
				} else if ($completion <= 7) {
					$output .= 'IN PROGRESS ';
				} else if ($completion <= 8) {
					$output .= 'UNKNOWN ';
				} else {
					$output .= 'INCOMPLETE ';
				}
			}
			
			$output .= $parser->recursiveTagParse($text) . '</div>';
			
			self::$values = self::$data;
			
			return $output;
		}
		
		/* See if we are processing a progress bar. */
		else if ($type == "graphic") {
			/*
			 * Basically, since all the parameters for the graphic tag are optional
			 * we can get right down to processing the tag.
			 */
			$start_value = 0;
			$end_value = 0;
			$current_value = 0;
			
			/* Check to see if we are creating a multi-list progress bar or a single progress bar. */
			if ($multilist === FALSE) {
				/* Check to make sure the group name exists in the data set. */
				if (array_key_exists($group, self::$data) === FALSE)
					return '<div style="display:inline;">[TODO GRPAHIC: Error 1: The group "' . $group . '" is invalid.]</div>';
				
				/*
				 * Get the end value we should have for the group. Also get the current
				 * value for the completed items.
				 */
				foreach (self::$data[$group] as $key => $val) {
					$end_value += $val['value'];
					if ($val['complete'] == TRUE)
						$current_value += $val['value'];
				}
				
				/* Check to see if we need to clear the data for the group. */
				if ($noerase === FALSE)
					unset(self::$data[$group]);
			} else {
				/*
				 * Get the end value for all the lists requested.
				 */
				$group = split(",", $group);
				foreach ($group as $key_group => $val_group) {
					/* Check to make sure the group name exists in the data set. */
					if (array_key_exists($val_group, self::$data) === FALSE)
						return '<div style="display:inline;">[TODO GRPAHIC: Error 2: The group "' . $group . '" is invalid.]</div>';
						
					/* Start getting the data as above. */
					foreach (self::$data[$val_group] as $key => $val) {
						$end_value += $val['value'];
						if ($val['complete'] == TRUE)
							$current_value += $val['value'];
					}
					
					/* Check to see if we need to clear the data for the group. */
					if ($noerase === FALSE)
						unset(self::$data[$val_group]);
				}
			}
			
			/*
			 * Just to prevent morons from setting the value of all the items to zero.
			 */
			if ($current_value == 0 && $end_value == 0)
				return '<div style="display:inline;">[TODO GRPAHIC: Error 3: You must supply at least one item that has a value greater than zero.]</div>';
			
			$start = intval($end_value) - intval($start_value);
			$current = intval($current_value) - intval($start_value);
			$actual_percent = round((100 * $current) / $start,2);
			$percent = $actual_percent > 100 ? 100 : intval($actual_percent);
			
			$outside_height = $height;
			$outside_width = $width;
			$inside_height = $height;
			$inside_width = $percent;
			
			$outterDivStyle = "width:".$outside_width."px;height:".$outside_height."px;border:1px solid black;";
			$innerDivStyle = "valign:bottom;background-color:".$color.";background-repeat:repeat;width:".$inside_width."%;height:".$inside_height."px;";
			$labelStr = "<div style=\"width:".$outside_width."px;text-align:center\" ><span style=\"float:left\">".$start_value."</span>Current: ".$current_value."(".$actual_percent."%)<span style=\"float:right\">".$end_value."</span></div>";
			$divStr = $labelStr."<div style=\"width:".$outside_width."px;\" ><div style=\"".$outterDivStyle."\" ><div style=\"".$innerDivStyle."\"></div></div><p style=\"text-align:center;\">".$parser->recursiveTagParse($text)."</p></div>";
			
			self::$values = self::$data;
			
			return $divStr;
		}
		
		/* Check to see if we are processing a progress bar tag. */
		else if ($type == "progress") {
			$start_value = $start;
			$end_value = $end;
			$current_value = $current;
			
			/*
			 * Just to prevent morons from setting the end value to zero.
			 */
			if ($end_value == 0)
				return '<div style="display:inline;">[TODO PROGRESS: You must supply an end value greater than zero.]</div>';
				
			$start = intval($end_value) - intval($start_value);
			$current = intval($current_value) - intval($start_value);
			$actual_percent = round((100 * $current) / $start,2);
			$percent = $actual_percent > 100 ? 100 : intval($actual_percent);
			
			$outside_height = $height;
			$outside_width = $width;
			$inside_height = $height;
			$inside_width = $percent;
			
			$outterDivStyle = "width:".$outside_width."px;height:".$outside_height."px;border:1px solid black;";
			$innerDivStyle = "valign:bottom;background-color:".$color.";background-repeat:repeat;width:".$inside_width."%;height:".$inside_height."px;";
			$labelStr = "<div style=\"width:".$outside_width."px;text-align:center\" ><span style=\"float:left\">".$start_value."</span>Current: ".$current_value."(".$actual_percent."%)<span style=\"float:right\">".$end_value."</span></div>";
			$divStr = $labelStr."<div style=\"width:".$outside_width."px;\" ><div style=\"".$outterDivStyle."\" ><div style=\"".$innerDivStyle."\"></div></div><p style=\"text-align:center;\">".$parser->recursiveTagParse($text)."</p></div>";
			
			return $divStr;
		}
		
		/* Check to see if we are processing a values tag. */
		else if ($type == "values") {
			$output = '';
			
			/* Handle the possibility that we need to only display data for a given group(s). */
			$vals = array();
			
			if ($group != "global") {
				$group = split(",", $group);
				
				foreach ($group as $group_key => $group_val) {
					foreach (self::$values as $values_key => $values_val) {
						if ($group_val == $values_key)
							$vals[$group_val] = self::$values[$group_val];
					}
				}
			} else {
				$vals = self::$values;
			}
			
			/* It is important to note that the data in the values array has already been escaped by the item tag code above. */
			$output .= '
{| width="100%" border="1"
|+Data Values
! width="10%"|Group
! width="10%"|Name
! width="10%"|Value
! width="10%"|Complete
! width="*"|Text
';

			foreach ($vals as $key => $val) {
				
				$group_count = 0;
				$group_total = count($vals[$key]);
				$output .= '
|-
| align="center" rowspan="' . $group_total . '"|' . $key;

				foreach ($val as $key_val => $val_val) {
					$output .= '
| align="center" valign="top"|' . $key_val . '
| align="center" valign="top"|' . $vals[$key][$key_val]['value'] .'
| align="center" valign="top"|' . ($vals[$key][$key_val]['complete'] ? "Yes" : "No"). '
| align="left" valign="top"|' . $vals[$key][$key_val]['text'];

					if ($group_count++ < $group_total)
						$output .= '
|-';
				}
			}
			
			$output .= '
|}';
			
			return $parser->recursiveTagParse($output);
		}
		
		/* Check to see if we are processing a help tag. */
		else if ($type == "help") {
			$text = "\$text"; /* Simple little way of getting around needing to escape the $ below. Makes copy n paste so much easier. */
			/*
			 * This will output the help contents for the extension in a nice wiki table.
			 * This will make keeping the output up-to-date, and I will be able to copy it
			 * more easily to the extension page.
			 */
			$output = <<< EOH
<div align="center">Help for [[Extension:TODOListProgressBar|TODO List Progress Bar]]</div>

The <nowiki><todo /></nowiki> tag has multiple modes of operation:

* Defaults Mode ('''''Not Implemented''''')
** <nowiki><todo type="defaults" ... /></nowiki>
** Sets defaults for the following items and progress bars such as color, width, height, etc.
* Graphic Mode
** <nowiki><todo type="graphic" ...>Caption</todo></nowiki>
** <nowiki><todo type="graphic" ... /></nowiki> (No caption given)
** Used for displaying a progress bar for a list.
* Help Mode
** <nowiki><todo type="help" /></nowiki>
** Renders the help text you are reading at this moment.
* Item Mode
** <nowiki><todo type="item" ...>Item</todo></nowiki>
** <nowiki><todo type="item" ... />Item</nowiki>
** Used for adding items to a list.
* Progress Mode
** <nowiki><todo type="progress" ...>Caption</todo></nowiki>
** <nowiki><todo type="progress" ... /></nowiki>
** Simple progress bar that isn't dependent upon a list.
* Values Mode
** <nowiki><todo type="values" ... /></nowiki>
** Outputs list data in a table.

All <nowiki><todo /></nowiki> tags require the "type" parameter. It only has the following values:
* "defaults" ('''''Not Implemented''''')
* "graphic"
* "help"
* "item"
* "progress"
* "values"


The type parameter tells the code what to do with the tag. As such, it has no default value.

{| width="100%" border="1"
|+Modes of operation parameter list
! width="10%"|Tag Mode
! width="10%"|Parameter
! width="*"|Description
|-
| align="center"|Defaults
| align="center" valign="top"|N/A
| align="left" valign="top"|Not implemented yet
|-
| align="center" rowspan="8"|Graphic
| align="center" valign="top"|$text
| align="left" valign="top"|The text for the progress bar caption. This will be the text that is between the <br /><nowiki><todo type="graphic" ...></todo></nowiki> tags.
'''This parameter is optional.'''
|-
| align="center" valign="top"|color
| align="left" valign="top"|The color that will be used to fill the progress bar. The default value is black. This parameter is any valid hex RGB value or HTML color.
'''This parameter is optional.'''
|-
| align="center" valign="top"|group
| align="left" valign="top"|The group of items that are going to be rendered. This parameter is a string value. The default value for this parameter is "global". Group names cannot contain commas as part of their name.
'''This parameter is optional.'''
|-
| align="center" valign="top"|height
| align="left" valign="top"|The height (in pixles, aka "px") of the progress bar. The default value is 10px. This parameter is an integer value.
'''This parameter is optional.'''
|-
| align="center" valign="top"|multilist
| align="left" valign="top"|This is a single word parameter that allows the combining of multiple lists into a single progress bar. This is useful for when you want to display lists of data that are separate but want to have a single progress bar to cover all of the lists. The lists to be combined are given in the "group" parameter separated by commas (group names cannot contain commas). The "noerase" parameter works with this parameter.
'''This parameter is optional.'''
|-
| align="center" valign="top"|noerase
| align="left" valign="top"|This is a single word parameter that will prevent the data for a group from being deleted. This could be useful for implementing an "advanced features todo list". In such a list, the basic features are listed first (which then display their own progress bar) followed by the advanced features (which then displays another progress bar containing both sets of items).
'''This parameter is optional.'''
|-
| align="center" valign="top"|width
| align="left" valign="top"|The width (in pixels, aka "px") of the progress bar. The default value is 400px. This parameter is an integer value.
'''This parameter is optional.'''
|-
| align="left" valign="top" colspan="2"|It is important to note that you cannot (at this point) place the progress bar tag before the item tags. This is due to the fact that HTML is parsed top down, as well as the fact that I have not added any AJAX that would bypass this restriction. Maybe for the next version...
|-
| align="center"|Help
| align="center" valign="top"|N/A
| align="left" valign="top"|Displays this help text.
|-
| align="center" rowspan="7"|Item
| align="center" valign="top"|$text
| align="left" valign="top"|The text for the item. This will be the text that is between the <nowiki><todo type="item" ...></todo></nowiki> tags.
'''This parameter is optional.'''
|-
| align="center" valign="top"|group
| align="left" valign="top"|The group an item belongs to. This parameter is a string value. The default value for this parameter is "global". Group names cannot contain commas as part of their name.
'''This parameter is optional.'''
|-
| align="center" valign="top"|name
| align="left" valign="top"|The name of the item. This parameter is a string value and must be unique for the group the item is in. If this parameter is not given, a unique value will be assigned.
'''This parameter is optional.'''
|-
| align="center" valign="top"|nostatus
| align="left" valign="top"|This is a single word parameter that will hide the status indicator. This can be useful if you just want to track items but aren't worried about them being marked in the list itself.
'''This parameter is optional.'''
|-
| align="center" valign="top"|percent
| align="left" valign="top"|('''''Not Implemented''''') Allows setting the percent completion of an item. This way, if you have a very large item and want to track its completetion state, but it cannot be broken up into smaller items, you can still show how complete it is.
'''This parameter is optional.'''
|-
| align="center" valign="top"|status
| align="left" valign="top"|Determines the staus of the item. The default value is "incomplete".
Valid values are:
:* The item is complete.
::* "complete"
::* "completed"
::* "done"
::* "finished" 
:* The item is being worked on but is not completed (counts as incomplete).
::* "ip"
::* "in progress" 
::* "working"
:* The status of the item is unknown (counts as incomplete).
::* "unknown"
:* The item is incomplete or has not been started on.
::* "incomplete"
::* "pending"
::* "held"
'''This parameter is optional.'''
|-
| align="center" valign="top"|value
| align="left" valign="top"|The "point value" of this item. The default value for any item is 1. This parameter is an integer value. This changes the point value of the item, and changes the final point value of the entire group.
'''This parameter is optional.'''
|-
| align="center" rowspan="6"|Progress
| align="center" valign="top"|color
| align="left" valign="top"|The color that will be used to fill the progress bar. The default value is black. This parameter is any valid hex RGB value or HTML color.
'''This parameter is optional.'''
|-
| align="center" valign="top"|current
| align="left" valign="top"|The current value of the progress bar. The default value is 0. This parameter is an integer value.
'''This parameter is optional.'''
|-
| align="center" valign="top"|height
| align="left" valign="top"|The height (in pixles, aka "px") of the progress bar. The default value is 10px. This parameter is an integer value.
'''This parameter is optional.'''
|-
| align="center" valign="top"|end
| align="left" valign="top"|The end value of the progress bar. The default value is 100. This parameter is an integer value.
'''This parameter is optional.'''
|-
| align="center" valign="top"|start
| align="left" valign="top"|The start value of the progress bar. The default value is 0. This parameter is an integer value.
'''This parameter is optional.'''
|-
| align="center" valign="top"|width
| align="left" valign="top"|The width (in pixels, aka "px") of the progress bar. The default value is 400px. This parameter is an integer value.
'''This parameter is optional.'''
|-
| align="center"|Values
| align="center" valign="top"|group
| align="left" valign="top"|The group to display data for. The default value for this parameter is "global". Group names cannot contain commas as part of their name. This parameter is a string value.
'''This parameter is optional.'''
|}

Copyright &copy; 2010 by Vadtec, vadtec@vadtec.net ("VADTEC")

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND VADTEC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VADTEC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
EOH;
			//'so that my editor displays the rest of the code properly ::annoyed::	
			
			/* $output does not need htmlspecialchars() applied to it because the text is hard coded. */
			return $parser->recursiveTagParse($output);
		}
	}
}

function wfTODOListProgressBarParserHook ($text, $params = array(), &$parser) {
	return TODOListProgressBar::processTag($text, $params, $parser);
}

TODO (pun)[edit]

  1. Add a <todo type="default" ... /> for setting page wide defaults.
    1. This will require an array to store the defaults so they can be changed.
  2. Add a "percent" parameter that allows giving a percent complete value to items that are not completed.
    1. This will cause only a portion of the items value to be added to the final tally.