Extension:CollaborationKit/Technical documentation

CollaborationKit is a MediaWiki extension that uses ContentHandler, special pages, and EditPage extensions to make it easier to organize on-wiki projects.

Content models
CollaborationKit implements two novel content models: CollaborationHubContent and CollaborationListContent. Both of these content models represent data in JSON according to the schemas defined in CollaborationHubContentSchema.php and CollaborationListContentSchema.php respectively. Pages of either content type are validated against their respective schemas through the schema validation library in EventLogging. Note, however, that this library does not work perfectly, especially since it is not caught up with the latest version of the JSON Schema specification. There are long term plans to integrate a schema validation library in core MediaWiki and use that instead; see Requests for comment/JSON validation.

Each of these content models use a serialization format called text/x-collabkit for editing. The details depend on the content model, but the basic thing is that each high-level key-value pair is represented as one or more lines, separated by a specific number of hyphens, with the order of these blocks of text pre-determined by the serialization/deserialization methods. For sub-objects, key-value pairs are presented, one per line, as key=value. For arrays, each item in the array is one line, with key-value pairs separated by vertical pipes. In some cases, this serialization is used to build the editing interface, minimizing exposure of code-like syntax to the user. The exact JSON stored in the database can be edited directly through the "Edit as JSON" tab, or through the  parameter in the edit URL.

Most forms of page interaction that exist with MediaWiki also work with these content models. They can be deleted, moved, etc. like other pages.

CollaborationHubContent
The CollaborationHubContent model represents "Collaboration Hubs," which are landing pages for on-wiki projects. Collaboration Hubs are essentially shell pages that then transclude other pages, including little content of its own.

The pages that are transcluded are called "features," corresponding to sections on the hub page and (usually) corresponding to project subpages. In addition to the named features, two additional pages are transcluded: the /Announcements subpage, which is wikitext, and /Members, which is CollaborationListContent. These subpages are created upon hub creation via Special:CreateCollaborationHub, but if those subpages don't exist, then the hub handles it gracefully.

Example
A sample Collaboration Hub:

{   "display_name": "Project Hampshire", "introduction": "A WikiProject dedicated to the ceremonial county of Hampshire in the United Kingdom.", "footer": "", "image": "Flag_of_Hampshire.svg", "colour": "red", "content": [ {           "title": "WPX:WikiProject Hampshire/Requests", "image": "quotes", "display_title": "Requests" },       {            "title": "WPX:WikiProject Hampshire/Resources", "image": "book", "display_title": "Resources" }   ] }

Let's break this down:
 * display_name – a name to show other than the actual page title (optional)
 * introduction – Some introductory content. Supports any arbitrary wikitext.
 * footer – To display on the bottom of the page. Supports any arbitrary wikitext; you could use this for navboxes, categories, etc.
 * image – An image to serve as an "icon" for the project. Can be any image accessible on the wiki or a key for one of the "canned icons."
 * colour – Can be one of 23 preset colours. The image and colour collectively are the "hub theme"
 * content – the main body of the project. Each object in this array is a "feature," a project subpage containing something of interest to the project. The parameters for the content object include:
 * title – the full name of the page to transclude. Generally, features are subpages of the project, but they do not have to be!
 * image – an icon to use in the hub's auto-generated table of contents, typically one of the canned icons. As with the image parameter above, you could also use an on-wiki image for this (though it probably won't look as good)
 * display_title – Normally the subpage name would be displayed as the section header and table of contents item (e.g. "X" for "Project:Foo/X"), but this parameter lets you override that.

Announcements are shown below the introduction, members in a box to the right of the introduction, the table of contents and the transcluded pages below that, and the footer below that.

Internally there is an attribute called displaymode, set to one of "normal" or "error." It is only used internally. If the page fails to validate against the schema, the displaymode is set to error, and an error message is shown with a text serialization of the offending JSON, internally represented by an attribute called errortext.

Also defined as part of the schema is a "scope" object, allowing the user to define the scope of the project in terms of included and excluded page titles and categories (including to a specified category recursion depth). If you add a scope object to a hub it will pass validation but not actually do anything.

Transclusion behavior
A note on how features are transcluded: there are different rules for how this works with different content models:
 * wikitext – Generic wikitext pages only have the lead section ("section zero") transcluded. This is intentional; this allows the lead to serve as a teaser or summary, with a link in the feature header that leads people to the full page contents.
 * CollaborationHubContent – Only the hub image and hub introduction are presented. This is partly in keeping with the above principle but also because of implementation issues involving how the MediaWiki parser handles transclusion.
 * CollaborationListContent – In the future this will be highly configurable, but for the time being, the default transclusion options are used, which are defined in the  method and currently are:
 * includeDesc (include list description text): false
 * maxItems (maximum number of items to show per column): 5
 * defaultSort: random
 * offset: 0
 * tags: none
 * mode: normal (as opposed to no-img)
 * showColumnHeaders: true
 * iconWidth: 64px

In theory any arbitrary content model could be transcluded, but this has only been tested on the above three (and the UI does not exactly encourage it).

Editing
CollaborationKit extends the EditPage class to build a custom editor for CollaborationHubContent. The first step is to convert the stored JSON into the text/x-collabkit serialization. The format is as follows:

Display name --- Introduction --- Footer --- Image --- Colour --- Features

That's precisely 23 hyphens between each section. To use the above section, the serialization would look something like this:

Project Hampshire --- A WikiProject dedicated to the ceremonial county of Hampshire in the United Kingdom. ---

--- Flag_of_Hampshire.svg --- red --- WPX:WikiProject Hampshire/Requests|image=quotes|display_title=Requests WPX:WikiProject Hampshire/Resources|image=book|display_title=Resources

Each of those sections correspond to input fields on the form.

Let's look more closely at the bottom section. Each line corresponds to a transcluded feature. The first, unlabeled parameter is the full page title. Each subsequent parameter is optional, but includes  which can be a filename or canned icon, and   to use a label other than the subpage name.

If you have JavaScript enabled, the colour dropdown and image input field are replaced with a "hub theme" widget. The image selector in particular makes use of the "media search" widget, formerly a part of VisualEditor but upstreamed to core MediaWiki in 2016.

CollaborationListContent
The CollaborationListContent model represents "Collaboration Lists," which are lists of page titles with associated pictures, notes, and other attributes. The main goal of this content model is to allow users to develop lists of pages to work on that are visually appealing and can be selectively transcluded. In other words, one does not need to transclude the entire list. Through the  ParserFunction, different criteria can be applied. This way, large lists can be embedded in other pages without it being overwhelming.

Example
{   "options": {}, "displaymode": "normal", "description": "Help us with these tasks!", "columns": [ {           "items": [ {                   "title": "Heather Macy", "notes": "Predicted class: Stub" },               {                    "title": "Judith L. Rapoport", "notes": "Predicted class: C"               }, {                   "title": "Catherine King (scientist)", "notes": "Predicted class: C"               } ],           "label": "Assess for quality", "notes": "Determine the quality of these articles" },       {            "items": [ {                   "title": "Monika Auweter-Kurtz", "notes": "German physicist • More information on Wikidata" },               {                    "title": "Maja Žvanut", "notes": "Slovene art historian • More information on Wikidata" },               {                    "title": "Selda Ekiz", "notes": "No English description available • More information on Wikidata" }           ],            "label": "From Wikidata", "notes": "Automatically generated list of missing articles" }   ] }

Special pages
CollaborationKit implements two special pages: Special:CreateCollaborationHub and Special:CreateHubFeature.