Extension:Page Exchange

Page Exchange (abbreviated "PX") is an extension that enables installing and updating "packages", which are groups of one or more wiki pages. The pages in a package usually have one common purpose, such as defining an entire data structure. Packages are defined in JSON files, known as "package files", which use a custom syntax described below. Anyone can publish such package files, just by putting them online. In order to use a particular file, a wiki administrator just needs to add its URL to the $wgPageExchangePackageFiles variable in LocalSettings.php; see below.

Once this extension has been installed, and one or more package files are included in LocalSettings.php, all the installation and upgrading of packages is done at the page Special:Packages.

If a package contains JavaScript or CSS pages - defined as pages named MediaWiki:PageName.js or MediaWiki:PageName.css - then those JavaScript or CSS pages will get loaded for users on every page of the wiki, as is already done with the pages MediaWiki:Common.js and MediaWiki:Common.css.

Uses
PX packages can be created for a variety of purposes:
 * Enabling wikis to have a data structure similar to, or inspired by, a popular wiki such as Wikipedia
 * Enabling those running a wiki farm to impose a standard starting set of pages across all wikis
 * Allowing users who are getting started with extensions that can involve complex syntax and rules (Cargo, Page Forms, Semantic MediaWiki and related extensions, Scribunto, etc.) to download working examples to their wiki
 * Allowing consultants who develop their own branded bundle of extensions to also add wiki pages and images to their offering
 * A substitute for a lightweight extension or skin, assuming that extension consists of only JavaScript and/or CSS
 * An alternative way to do a transfer of content (pages and/or images) between wikis, on a regular basis or even just once.

In all these cases (except for the last one or two), there could be multiple versions of each package in different languages, so that (ideally) every wiki that wants such a package could have one available in its own language.

Download
You can download the Page Exchange code, in .zip format, here: https://github.com/wikimedia/mediawiki-extensions-PageExchange/archive/0.2.3.zip

You can also download the code directly via Git from the MediaWiki source code repository (see available tags). From a command line, call the following:

Installation
Once you have obtained a "PageExchange" directory and placed it in your /extensions directory, add the following to LocalSettings.php:

Then go to the MediaWiki /maintenance directory, and run the following:

The installation and other handling of packages can be done by anyone with the 'pageexchange' permission; by default, this is available to those in the 'sysop' group. To extend this permission to, for instance, anyone in the 'bureaucrat' group, you can add the following to LocalSettings.php:

Finally, in order for this extension to be useful, you will need to populate the global variable $wgPageExchangePackageFiles with one or more URLs in LocalSettings.php, in the following format:

See the next section for some examples of package files that can be used.

Usable package files
Anyone can create their own package files. If you have created a package file meant to be widely useful, feel free to add it to the list below, with a short description of the package(s) it defines.


 * https://raw.githubusercontent.com/WikiWorks/Page-Exchange-packages/master/books-cargo.json - a data structure, and sample data, for books and their authors, using Cargo and Page Forms
 * https://raw.githubusercontent.com/WikiWorks/Page-Exchange-packages/master/books-smw.json - a data structure, and sample data, for books and their authors, using Semantic MediaWiki and Page Forms

Including JavaScript and CSS pages
You can have a package include JavaScript or CSS pages, which are pages that have the namespace "NS_MEDIAWIKI" and a name that ends with ".js" or ".css". Any such page will then get loaded during all regular page loads, as already happens with the pages MediaWiki:Common.js and MediaWiki:Common.css.

If a package contains any such JS or CSS page, only users who have permission to edit JS or CSS pages on the wiki (in addition to the permission to access Special:Packages) will be allowed to install it.

This functionality will only work for sites that have $wgUseSiteJs and $wgUseSiteCss both set to true (they are both true by default). Unfortunately it will also only work on sites running MediaWiki 1.35 and higher.

Enabling on MW < 1.35
If you are running a lower version of MediaWiki, you can enable this functionality on your wiki, if you don't mind making some small changes to the MediaWiki code. In the file /includes/resourceloader/ResourceLoaderSiteModule.php, under the line:

...add the following line:

Similarly, in the file /includes/resourceloader/ResourceLoaderSiteStylesModule.php, under the line:

...add the following line:

Package file syntax
Packages are defined in "package files": JSON files available at some public URL, each of which defines one or more packages. There is no limit to the number of packages that can be defined in one package file, and the packages can be completely unrelated to one another. Each package, in turn, includes one or more wiki pages.

Here is the set of parameters that can be set for an overall package file:
 * - The default publisher
 * - The default URL for the publisher
 * - The default author
 * - The default language for all defined packages, using the (usually) two-letter IETF language tag for that language.
 * - The default license under which these packages are published.
 * - Holds the set of packages, with the package name as the key and the set of package parameters as the values.

Here is the set of parameters that can be set for a single package:
 * - (mandatory) A text identifier for this package, which is ideally globally unique. Ideally it uses reverse domain name notation. For example, for a package in the Spanish language for a CRM data structure, created by a company called Acme, whose internet domain is acme.com, the package identifier could be "com.acme.CRM.es". You can feel free to be creative within this system. For example, if you are publishing a package on your own and do not have your own internet domain, but you do have a username on mediawiki.org ("Joey User"), then you could give such a package the identifier "org.mediawiki.user.Joey_User.CRM.es". The important thing is uniqueness. It's also important, once people have started using a package, not to change its global ID - changing it would prevent people who have already downloaded the package from updating to more recent versions.
 * - The publisher
 * - The URL for the publisher
 * - The author or authors of this package
 * - The language for this package, using the IETF language tag
 * - A URL for a web page describing this entire package, if one exists.
 * - A version number for the package, which can be updated so that users know if their local copy of the package is out of date.
 * - The name of the license under which this package is published.
 * - An array of the names of any extensions required for this package to work. (In the future, this parameter may also allow defining specific versions that are required for specific extensions, but this is not currently possible.)
 * - An array of the names of any additional packages required by this package.
 * - Holds the set of pages in this package.

And finally, here is the set of parameters for an individual page:
 * - The name (minus of the namespace) of a wiki page
 * - The namespace code for the namespace of the wiki page, though stored as a string (like "NS_TEMPLATE"). The default is "NS_MAIN".
 * - The URL at which the contents of the page can be found. This can be any URL, and does not have to be part of a wiki. If you are using a MediaWiki wiki page for the URL, make sure that the URL ends with "?action=raw" (or "&action=raw"), so that only the actual wikitext for the page is retrieved.
 * - If this is a file/image page (i.e. with a "namespace" value of "NS_FILE"), this parameter holds the actual file, while the "url" parameter holds a URL containing the text contents of the wiki page.

Version history

 * 0.1 - May 15, 2020 - Initial version


 * 0.2 - June 10, 2020 - Added special handling for imported JS, CSS pages; bug fixes
 * 0.2.1 - June 25, 2020 - Fixes for display of installed packages
 * 0.2.2 - July 7, 2020 - Fixed handling for MW < 1.32
 * 0.2.3 - December 14, 2020 - Added "licenseName" property to packages; fixed handling for MW 1.34+; other bug fixes