## The Treeview skin for MediaWiki

The Treeview skin for MediaWiki was developed many years ago for the comp.lang.c wiki, [clc-wiki.net](https://clc-wiki.net/). It has for many years also been made available for general use.

Its main feature is to add to MediaWiki a hierarchical treeview in the sidebar. This hierarchy is built up mostly automatically from wiki article titles with colons in them: the colons are treated as separators in the same way that slashes are used as a directory separators in filesystems.

In more detail, its features are:

* The treeview is expandable/collapsable through Javascript load-on-demand falling back to full-page reload (update: full-page reload has been disabled because some bots misbehave, and, even when instructed not to by robots.txt, they incessantly crawl the virtually endless query strings which support the persistence of the expanded state of the treeview when in full-page reload mode); customisable through the MediaWiki:Treeview article. Category hierarchies can also be loaded into the treeview.

* The ability to specify remappings for displayed title names in the MediaWiki:Treeview config page to deal with MediaWiki's underscore conversion where it's unwanted, e.g., for articles describing standardised programming variables that have underscores in their name.

* A navigation bar based on the hierarchy for easier browsing.

* A few controls to assist with diagnosing caching and parsing problems, visible at Special:Hierarchy.

Further description of the skin's features is in the help files in the help-articles/ directory, and in the file describing its client-side Javascript functionality, README.treeview_javascript.

The CHANGELOG describes externally visible changes relevant to upgraders.

## Disclaimers

This Treeview skin and its supporting Hierarchy extension are released unpolished. For many years now, they have been in maintenance-only mode, being updated only minimally such that they continue to function on newer versions of MediaWiki.

Their code and structure, then, are in several ways not very modern nor up to date. The skins/Treeview/ directory, for example, is cluttered with files, many of which more properly belong in subdirectories.

There might be minor bugs in the code, although it should be fairly stable: it has been used in production on clc-wiki.net for many years.

See also the "Limitations" and "Performance and scalability" sections below.

## Compatibility, requirements and recommendations

* MediaWiki 1.44.*. It will probably also work on earlier recent(ish) versions.
* PHP 8.3 and above. Again, it will probably also work on earlier versions, probably quite old ones.
* A cache manager for best results (see "Performance and scalability" below). If a cache manager is enabled then per-user translations of treeview strings are disabled (see "Limitations" below).

The skin was heavily and deliberately, for compatibility, based on MonoBook. It includes a few files copied from Monobook, in particular icons but also CSS. Since then, Monobook has been updated. This skin has not always incorporated those updates.

## Installation

* Recursively copy the directories and files under the to-upload-to-your-mediawiki-directory/ to your mediawiki directory.

* To LocalSettings.php, add the following lines, edited to your requirements, taking note of the comments, and being careful that $wgGroupPermissions is not being overwritten later in the file by a pre-existing full-array assignment (these variables are described under "Variables and settings"):

```php
wfLoadExtension('Hierarchy');
wfLoadSkin('Treeview');

# Optionally set Treeview as the default skin ($wgDefaultSkin is probably
# already set elsewhere in the file).
$wgDefaultSkin = 'treeview';

# Customise your logo path as desired.
$wgLogo        = "$wgStylePath/Treeview/clc-wiki.png";

# Customise these permissions as required; they are described beside the
# $wgGroupPermissions entry under "Variables and settings" in README.Treeview.
$wgGroupPermissions['sysop']['rebuildtreeview'    ] = true;
$wgGroupPermissions['sysop']['parsetreeview'      ] = true;
$wgGroupPermissions['sysop']['treeviewcachestatus'] = true;

# Not required if $wgCachePages and $wgUseFileCache are both false.
# path/to/file is a file that the web-server has read/write permission on.
$wgCacheEpochTouchFile = "/path/to/file";

# Uncomment this if $wgUseDatabaseMessages is false but an editable
# configuration at the default configuration message page is required.  The
# default configuration is the 'Treeview' message in the 
# extensions/Hierarchy/i18n/[lang].json files.
#$wgHierarchyPage = 'MediaWiki:Treeview';

# Database additions are required prior to (optionally) uncommenting this, as
# described in its entry under "Variables and settings" in README.Treeview.
#$wgStoreTreeviewNodeIdsInDB = true
```

* Optionally, review the "Variables and settings" section to see if anything applies.

* Optionally, to have the custom node icons that this configuration references displayed, upload the images in the Treeview/icons-for-upload/ directory to the wiki using Special:Upload or a batch upload tool (see the README in that directory).

* Optionally, edit the new MediaWiki:Treeview configuration article to suit site requirements. CAUTION: If database messages are not being used - i.e., if $wgUseDatabaseMessages is set false - then $wgHierarchyPage must be set for edits to take effect, i.e., for the default page location uncomment the line added to LocalSettings.php above (the $wgHierarchyPage setting's description below has more information):
```php
$wgHierarchyPage = 'MediaWiki:Treeview';
```

* Optionally, but recommended, create the help articles based on the files in the directory help-articles/.  The suggested title of the article for the imported file Help.Treeview_skin.Treeview.wiki is 'Help:Treeview skin:Treeview', and the suggested title of the article for the imported file Help.Treeview_skin.Syntax.wiki is 'Help:Treeview skin:Syntax'. Optionally, edit or translate these files first, but be aware that a later release might meaningfully change their supplied content files.

## Variables and settings

This alphabetical list describes all global variables that apply to this skin and that can be set in LocalSettings.php. Each of these is specific to the Treeview skin and/or Hierarchy extension unless otherwise stated. Item symbols have these meanings:
```
+ A mandatory setting.
* A significant or likely to be useful setting, but not mandatory.
- A lower-level or less likely to be useful setting.
```

\- `$wgAllowRelNext` (boolean; default: true)
Whether to add rel="next" to navigation links where appropriate - this might prompt browsers to precache pages, hitting the wiki server more often than is necessary.  The extra traffic can be avoided by setting this variable to false.

\+ `$wgCacheEpochTouchFile` (string; REQUIRED - no default - the extension will abort and display a diagnostic if this variable is unset when client and/or file caching is enabled)
The path to a file whose last-modified time is set and consulted by the Hierarchy extension to ensure that file/client-cache invalidations can be performed - a dynamic version of `$wgCacheEpoch`.  The web-server must have read/write permission on that file.  This setting is necessary only if both client (`$wgCachePages`) and file (`$wgUseFileCache`) caching are enabled. Those two variables are defined by MediaWiki core; most (all?) MediaWiki releases set `$wgCachePages` to true in DefaultSettings.php.  The way to set appropriate permissions on such a file varies by operating system.  On a UNIX or similar system (Linux, *BSD, Solaris, etc), ask your system administrator to create the file with permissions set to 550 and with user and group ownership set to the user and group that the webserver is running under (typically both are 'apache'), and located e.g. at yourmediawikiroot/cache_epoch_touchfile.  Then for the same example, add to LocalSettings.php:
```php
$wgCacheEpochTouchFile = 'yourmediawikiroot/cache_epoch_touchfile';
```
As a last resort, or while your admin is otherwise occupied, simply adding to LocalSettings.php:
```php
$wgCacheEpochTouchFile = '/tmp/mediawiki_treeview_cache_epoch_touchfile';
```
will probably work under a UNIX system.

\- `$wgCookiePath` (not Treeview-specific - set by MediaWiki core in DefaultSettings.php - probable default value is '/')
The root path of this site against which to store skin/treeview state cookies in browsers.  If multiple wikis are hosted on the same domain, this can be set to a different top-level directory for each, e.g. '/mediawiki1' and '/mediawiki2', but beware rewrite rules - e.g. don't set `$wgCookiePath` to `$wgScriptPath` (which at time of writing itself defaults to '/mediawiki') if '/mediawiki' is being converted by a webserver rewrite rule to '/wiki' and `$wgArticlePath` is set to '/wiki/$1', because then the treeview javascript will be storing cookies at /mediawiki and not finding them when new pages are loaded under /wiki.

\* `$wgGroupPermissions` (array; no default settings are applied i.e. maximally restrictive permissions; this is a MediaWiki-core array - be careful not to overwrite the value of any previously set members)
This structure can be used to set access to the Treeview/Hierarchy actions for viewing parse diagnostics, rebuilding the treeview and viewing its cache status.  A tab is added to the page actions when viewing the configuration page (or its stand-in) for each action for which the corresponding right is active.  The actions are also accessible at Special:Hierarchy.  So e.g. to allow anyone to view the configuration's parse diagnostics, to allow only logged-in users to view the treeview's cache status, and to allow only bureaucrats to rebuild the treeview in cache, add these lines to LocalSettings.php in an appropriate location:

```php
$wgGroupPermissions['*'         ]['parsetreeview'      ] = true;
$wgGroupPermissions['user'      ]['treeviewcachestatus'] = true;
$wgGroupPermissions['bureaucrat']['rebuildtreeview'    ] = true;
```

\* `$wgHierarchyPage` (string; default: none - if this variable is unset then the 'Treeview' message is used rather than an article - the practical effect of this is described in the square brackets below)
\[IMPORTANT: If `$wgUseDatabaseMessages` is set false, then it is mandatory to set (in LocalSettings.php) `$wgHierarchyPage` to 'MediaWiki:Treeview' prior to editing that article (so that changes take effect), and to leave `$wgHierarchyPage` unset prior to any edits if the 'MediaWiki:Treeview' article does not already exist (so that the default configuration is used).  Note: `$wgUseDatabaseMessages` is a MediaWiki-core variable whose default value in most (all?) MediaWiki versions is true, so typically this paragraph does not apply.\]
The name of the page from which the treeview's configuration is sourced.
The page needn't be in the 'MediaWiki' namespace but it should be a content page -  i.e. pages in the Special and Image namespaces are invalid.
This page is to the Treeview skin what the 'Sidebar' message (accessible as the 'MediaWiki:Sidebar' article when `$wgUseDatabaseMessages` is true) is to the Monobook skin.
Side-note: the original source of this configuration text is the 'Treeview' message in the `$messages[$wgLanguageCode]` array in the extensions/Hierarchy/Hierarchy.i18n.php file, where `$wgLanguageCode` represents the value of the identically named MediaWiki-core variable that specifies the wiki's user-interface language e.g. 'en' for English.

\- `$wgShowCopyrightIcon` (boolean; default: true)
Whether to show the copyright icon in the footer.

\- `$wgShowPoweredByIcon` (boolean; default: true)
Whether to show the powered-by icon in the footer.

\* `$wgStoreTreeviewNodeIdsInDB` (boolean; default: unset i.e. false)
Whether to store treeview node ids in a database table, created as described beside "TABLE CREATION" below.  This ensures that the same id is used for a node between treeview rebuilds when the referenced article originally was non-existent and later is created (node-ids normally include the numeric article-id as a component when the article exists).  This can help to avoid minor load-on-demand glitches when the article is created (triggering a treeview rebuild) and the node is expanded in a treeview on a previously opened page.  When `$wgStoreTreeviewNodeIdsInDB` is false, the likely outcome is an error message displayed in the branch indicating that the node no longer exists and prompting for a re-sync.  When true, the node will simply expand as usual.
TABLE CREATION: Create the database table within the `$wgDBname` database using the SQL in Hierarchy/treeview_tables.sql after replacing the symbol `/*$wgDBprefix*/` in that file with the value (possibly empty) of `$wgDBprefix` as set (or not set i.e. empty) in LocalSettings.php.

\- `$wgTreeviewHelpPage` (string; default: 'Help:Treeview skin:Treeview')
The page that the question mark in the treeview menu bar links to.
\[Note: the treeview menu bar has been disabled as it was too arcane, so this setting no longer has any purpose.\]

\- `$wgTreeviewIconHeight` (integer; default: 13)
The expected height in pixels of the icons used in the treeview.

\- `$wgTreeviewIconWidth` (integer; default: 13)
The expected width in pixels of the icons used in the treeview.

## Limitations

1. Not a responsive design; i.e., not suitable for viewing on mobile devices.

2. Probably not very scalable, and optimal performance requires a cache manager (see "Performance and scalability" below).

3. If a cache manager is enabled then the treeview code disables per-user translations of treeview strings - i.e., if $wgLanguageCode is set to 'nl' (Dutch) and a user sets his/her language preference to 'en' (English), then treeview node titles and tooltips will be displayed in Dutch regardless.

## Other languages

Customised text for other languages may be added in the extensions/Hierarcy/i18n/ directory. If you do this, I'd love it if you sent me a copy so I can include it in the next release.

## Performance and scalability

The treeview component of the skin was designed for optimal performance when a caching plugin for MediaWiki is present. These days, MediaWiki by default falls back to using a database cache when no other cache is configured, which offers acceptable performance.

For better performance, try a cache manager such as Memcached.

Be aware though that in both cases, limitation #2 above applies.

Performance may be unacceptably slow without any caching at all. This is because the entire treeview will be rebuilt on each page view, without being able to avoid this on the next view by retrieving it from the cache and only updating nodes that have changed. It would be possible to improve performance for a no-cache setup, but there is currently no plan nor intention to do so.

The Treeview skin is probably best suited to small-medium sized sites with low-moderate traffic. It probably won't scale well unless:
* The number of nodes in the treeview is restricted, and/or,
* The wiki is infrequently edited and is infrequently changed in ways that otherwise trigger a treeview rebuild (see below under "Triggering a treeview rebuild").  If the number of nodes is not simultaneously restricted though, PHP memory requirements might then become significant.

Some representative data: for a treeview with 252 nodes, the cached object size was 286667 bytes, which could be reduced to 20319 bytes with compression.

### Performance priorities

When designing the skin and after assuming the presence of a cache, priority was then assigned from highest to lowest to the speed of:

1. On-demand xml loads of nodes through Special:Hierarchy when anonymous.
2. On-demand xml loads of nodes through Special:Hierarchy when logged-in AND page views when anonymous.
3. Page views when logged in.
4. All other - mostly page edits

## Triggering a treeview rebuild

To trigger a cache invalidation and a complete rebuild of the treeview, which will also invalidate all page entries in the file and client caches if either of those caches is enabled, do one of the following:
* Follow the 'Rebuild treeview' link on the Special:Hierarchy page, or when it appears as a tab when viewing the configuration page/stand-in page, or otherwise supply an action=rebuildtreeview url query parameter when accessing that page.
  *Requirements: the 'rebuildtreeview' right.*
* Save the article with the title specified by the $wgHierarchyPage setting - by default this is 'MediaWiki:Treeview'.  There is no need to make changes to the article before saving it, although in earlier MediaWiki versions this page itself will not be rebuilt unless changes are made or it is later purged.
  *Requirements: $wgHierarchyPage is set and/or $wgUseDatabaseMessages is true; the right to edit or create new pages in the MediaWiki or other applicable namespace.*
* Save a new article.
  *Requirements: the right to create new pages.*
* Move an article.
  *Requirements: the 'move' right.*
* Delete an article.
  *Requirements: the 'delete' right.*
* Undelete an article.
  *Requirements: the 'undelete' right.*
* Edit a message upon which the treeview depends.
  *Requirements: $wgUseDatabaseMessages is true; the right to edit pages in the MediaWiki namespace.*
* Upload an image used as a treeview icon.
  *Requirements: the 'upload' right.*

## Logo generation

The representative clc-wiki.png logo file was generated using ImageMagick:

```sh
convert -size 130x29 xc:transparent -background '#fefef9' -antialias -emboss 2 -style italic -pointsize 28 -fill '#608CEB' -stroke '#C0C0FF' -draw "text 20,24 'clc-wiki'" clc-wiki.png
```

You can, if you like, generate your own by tweaking that command.

You might generally want to choose a logo height slightly less than MediaWiki's usual logo height to make room for the treeview.

## Skin design notes

contentborder_topleft.basedesign.png and contentborder_topleft.basecurve.png are development image files not necessary in production. The ImageMagick command
to generate the border image is:

```sh
convert -resize 85x70 contentborder_topleft.basedesign.png contentborder_topleft.png
```

The contentborder_top.png and contentborder_left.png files can then be extracted as the 5x5 pixel boxes top-right and bottom-left respectively. It's handy to set their background colour to white in case of browsers unable to deal with png transparency (although, these many years since this skin was first written, there aren't likely to be any anymore), e.g.:

```sh
convert -background white contentborder_left.png contentborder_left.png
```

(This doesn't remove transparency for browsers that support it.)

## Contributions and patches

Contributions and patches are welcome so long as they're coded neatly and are licenced as GPL2 and also grant permission to the skin's maintainer to separately licence the patch under a scheme of the skin maintainer's choice (it would be acceptable for the patch author to require that s/he be listed in the credits of any released code that incorporates the patch, or parts of it, under
a new licence).

Contributed code might be reformatted to match the style of the rest of the treeview code.

## Public distribution and versioning

The skin+extension is released as an "unpolished" version.

Distribution should occur as a set of related files rather than individually, because any two separate files from different releases might be incompatible.

## Licence

The public licence covering the entirety of the Hierarchy extension and the Treeview skin - code and documentation - is the [General Public Licence 2](http://www.gnu.org/copyleft/gpl.html) (GPL2) or a later version of that licence. This is required for the code because it extends MediaWiki which is under that licence.

Other licencing terms might be provided to well-intentioned inquirers.

## Home page and public repository

* [Home page](https://creativeandcritical.net/mediawiki-treeview-skin).
* [Public repository](https://github.com/lairdshaw/mediawiki-treeview-skin).