Extension:Page Exchange

Page Exchange (abbreviated "PX") is an extension that allows for instaling 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
 * Allowing 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.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 usable, you will need to populate the global variable $wgPageExchangePackageFiles with one or more URLs in LocalSettings.php.

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.
 * - 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.
 * - 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