Extension:SubPageList3

Introduction
The Wikiversity community voted overwhelmingly for a subpagelist extension. However Extension:SubPageList2 was declined by Mediawiki developers for technical reasons. The current extension simplifies and fixes the previous extension to meet criteria for implementation on Wikiversity. Generally there is nothing ambitious here. On the contrary this is supposed to be a small, reliable, sound and useful extension with no thrills and a modest but significant organisational value.

Need
Some wikis tend to create their content in clusters of pages rather than as individual articles (e.g. Wikibooks, Wikiversity), and when they do so, they typically use a lot of subpages. This creates an additional layer or organisational complexity, with a corresponding need to help users through this layer of complexity.

Previous version
SubPageList2 was described as follows: ''Sub Page List 2 is an extension that automaticaly creates a list of the subpages of a page. The dynamic created list will be created automatically on every edit of the page where the SubPageList element is given.''

This version

 * Uses the tag to enter a list/menu of a subpage system.
 * The subpage system is that of the current page (by default), or of any specified page elsewhere on the wiki.
 * The subpage system can be displayed as an ordered or unordered indented list, or as a horizontal bar.
 * The subpage list is updated each time the page in which the tag is embedded is updated.

The most important changes are:


 * Bugfixes.
 * Removal of the preview mode and removal of associated caching of actual content of subpages, which considerably shortened and simplified the extension.
 * Generally bringing the other features into line with what would have been expected of a simple subpage list extension.
 * Code size cut from 21kb to 14kb.

History

 * SubPageList1 was written by User:Robchurch and is no longer available. A note in the code of SubPageList2 says that the orginal version of the SubpageList extension... can produce a fatal error while using the element. No further information was given about this. However it might be that the following is meant: that the original SubPageList and SubPageList2 cannot be used together.
 * SubPageList2 was an extension of the above by Schaelles, probably written for a non-Wikimedia project. Date: 2006.
 * A simplified variant was written by User:Karora in January 2008. See below for code.

Code

 * Code snippet from the original - of interest due to the different database call.
 * Code for SubPageList2 (TWO - the older version!). Formatted into a wiki box with colours to make code inspection easy and lazy.
 * Code for Karora Variant. Possibly very experimental. See information at User:Karora/ListSubPages.
 * Code for SubPageList3 (That would be this one).

Feedback from other developers
The following feedback was given about Extension:SubPageList2:

I've done a quick review of this extension: - Unused variables in several places, including variables that get filled with data using string operations (line 547) - The content of the subpages will be loaded even if no preview is  requested (lines 567ff). This costs a lot of ressources. - Odd code: if ( $this->debug || $this->debug == 1 ) { (line 276). The "|| $this->debug == 1" part is superfluous. Overall, I don't think that we should activate this code. JeLuF

To respond to this feedback, the current extension project was created and the changes below implemented.

Things changed

 * Improved use of $wgExtensionCredits as suggested by User:Peterblaise.
 * Corrected typo of array $conditions.
 * Corrected code error where $debug was always on.
 * Removed preview mode. This is a major feature removal. The old version could (allegedly) include previews of the subpages. This was considered far too ambitious and outside the current needs. This also removed a lot of the code which "JeLuF" (above) did not like.
 * Removed the $articlecontent array used for caching subpage previews (as well as a bunch of other variables) plus the code which cached subpage previews.
 * Removed restriction of subpage choice by category and namespace.
 * Removed options for limiting and ignoring certain subpages.
 * Renamed option "deepness" to "depth".
 * Renamed option "mode" to "liststyle".
 * Renamed the tag from "subpages" to "splist" (i.e. subpagelist).
 * Renamed classes and hooks to avoid any conflict with previous extension.
 * Changed default value of showpath attribute to no and changed value normal to full.
 * Renamed options "order" and "ordermethod" to "sort" and "sortby".
 * Added the critical feature whereby grandchildren (and further descendent levels) are indented properly to indicate their level of descendence. Previously this extension simply did a one-level bulleted list which indicated inheritance/descendence only by the use of paths in the text.
 * Replaced the deepness/depth option with some more useful (and simpler) toggles (kidsonly, showparent) because the original option didn't even come near to working properly.
 * Fixed a bunch of problems with namespaces.
 * Added a visible report to the output in the event of there being no subpages to list. Previously the white space gave the feeling of a malfunction.
 * Added a limit (200) to the number of displayable subpage titles after noting that invalid inputs for the parent option might end up extracting too much from the database.
 * Added some validity tests, including a page exists check, to the parent option, because otherwise malicious wiki editing could produce a database output error.
 * Replaced use of REGEXP with LIKE following advice from FlyingParchment.

Detailed list of changes from Extension:SubPageList2
Currently this is a list of all the bells and whistles in SubPageList2, with comments about their fate.

Options in Extension:SubPageList2 which were retained, tested and repaired

 * Debug. Values: 0 = show errors; 1 = hide errors. Illogical. Documentation error, plus code error.
 * Deepness (now depth). Specifies how deep to go. Note bug report by Fungiblename. Completely crazy. Replaced with: kidsonly, showparent.
 * Mode (now liststyle). Remove the "preview" value and keep just the choice between numbered and bulleted lists.
 * Showpath: whether to show just page titles or the full path in the list.
 * Order (now sort): whether to sort subpages in ascending or descending order.
 * Ordermethod (now: sortby): whether to sort subpages by date or title.
 * Parent: used to choose the top level page in the nav. Had namespace issues.

Options in Extension:SubPageList2 which were axed

 * Category: was used to restrict selected subpages to those belonging to a specific category.
 * Count: maximum number of subpages to display.
 * Ignore: list of subpages to ignore.
 * Namespace: was used to restrict subpage selection by namespace.
 * Previewcount: used to determine how much of a subpage was previewed; as the preview feature is being removed, this is no longer needed.
 * Previewmode: ditto.
 * Headline: was an option for the preview mode.

MediaWiki versions tested

 * Server #1: MediaWiki: 1.11.1 / PHP: 5.2.3 (cgi) / MySQL: 4.1.22
 * (internal; not accessible)
 * Server #2: MediaWiki: 1.11.1 / PHP: 5.2.3 (cgi) / MySQL: 4.1.22
 * View some of the tests here: http://www.qedoc.org/en/index.php?title=Subpagelist_Extension
 * Server #3: MediaWiki: 1.6.10 / PHP: 4.4.7 (cgi) / MySQL: 4.1.22
 * This extension does not, unfortunately, work with Mediawiki 1.6, nor is it likely any simple hack would help.

Things actually tested

 * Tested the following options and established that they appear to work as they should: sort, sortby, liststyle, showpath.
 * Tested (after fixing): parent option (especially with namespaces), kidsonly, showparent (replacements for the depth option).
 * Tested indentation ability up to great-great-grandchildren.
 * Tested namespace stuff more.
 * Tested putting the output results inside tables and formatted divs to see how well this works with attractive menu box templates.
 * Tested namespace stuff even more.
 * Tried exploiting vulnerabilities in the parent option and successfully produced database errors; then programmed safety mechanisms to prevent such exploitation.

Observations

 * The original documentation says that the subpage list is only updated when the page containing the tag is updated. In practice it was noted that sometimes this was true and sometimes not (i.e. sometimes the list appeared to update even when the page containing the tag had not been updated).
 * Probably a mirage.
 * The parent attribute must have the namespace removed before it does anything.

Bugs

 * The entire way SubPageList2 deals with grandchildren and their descendents was unacceptably buggy.
 * Fixed in initial release.
 * There is a namespaces issue with the parent option if any namespace crossing is attempted. First, the parent option cannot be used with a namespace. Second, the subpagelist then assumes that all subpages are in the same namespace as the page in which the tag is embedded, not the namespace of the page given as the parent of the list.
 * Fixed in initial release.

Things changed

 * User:Sayuri went through the code with some minor tweaks, which have been adopted: corrected URL to extension; turned authors list into an array; removed closing ?> (PHP close tag); corrected copyright symbol.

Wishlist for version 1.1

 * Add options for showing extra data after each page in the list; e.g. page visits, last edit date, page size.

Installation

 * Download the zip file and extract the one PHP file from it.
 * Upload SubPageList3.php to your extension directory. It does not need a subdirectory, unlike more complex extensions.
 * Add the following lines at the end of your LocalSettings.php:

The tag
Simply place where you wish your subpage list to appear.

Attributes of the splist tag
Example with use of all available attributes.




 * Liststyle: default is unordered; values are ordered|unordered|bar. Toggles list between  and  lists. The bar value causes the list to align horizontally with &middot; symbols acting as delimiters (for bar lists rather than tree lists).
 * Sort: default is asc; values are asc|desc. Toggles list between ascending and descending sort order. By default, the tag sorts subpages in ascending alphabetical order; all sorting, however, is subject to hierarchical position - i.e. pages will always be subordinated to their parents; sorting is only among siblings.
 * Sortby: default is title; values are title|lastedit. Toggles list sort determinant between title and date of the last edit.
 * Showpath: default is no; values are no|notparent|full. Determines how the title of each page is displayed in the list. "No" means that only the subpage title (i.e. the bit after the last slash) is displayed. "Notparent" shows the full path without the top level. "Full" shows all levels in the page title name including the top level (e.g. "my page/my subpage/my subpage2").
 * Kidsonly: default is no; values are yes|no. If this is set to "yes", then only the first generation of subpages (i.e. the children but not the grandchildren) is displayed. This is especially useful if the liststyle is set to bar. It's also good if you just want a list rather than a tree.
 * Parent: by default the tag analyses the subpage system of its own page. However you can set the tag to analyse and display the subpage system of any other page on the wiki. Use local name format. E.g. "parent=Template:FOO" (with a namespace) or "parent=My Page" (in the main namespace). A common source of error is typing the page name incorrectly. The extension checks whether or not the page you name actually exists, and will report an error if it doesn't.
 * Showparent: default is no; values are yes|no. If this is set to "yes", then the page indicated by parent (above) will be inserted as the top level item in the list. If the list is a bulletted list, then this top level item will have a bullet and the rest of the list will be indented one level further than it would be otherwise.
 * Debug: you can switch debugging on by setting this option to 1; the debugging goes no further than reporting invalid input for the other options.

CSS formatting
The parser puts a  around the list with the class "subpagelist".

Acknowledgements
Thanks are due to the following, all of whom helped to degrees large and small. The bugs are all mine, though! Apologies to anyone I have forgotten - so many have helped that it is difficult to remember everyone.
 * Coding help: Duesentrieb, FlyingParchment, Sayuri, PeterBlaise, JeLuF.
 * Encouragement: everyone at Wikiversity who wanted this extension.