Manual:Extension.json/Schema

<translate>
This page documents the schema used by <tvar|1>extension.json</>.</translate>
<translate>
All fields are optional unless otherwise specified.</translate>
<translate>
It is currently incomplete.
For the first iteration of this schema see <tvar|1></> (MW 1.25+), for the second see <tvar|2></> (MW 1.29+).
</translate>
== manifest_version ==
This field is required.
This specifies the version of the extension.json file format that is being used. In the future if breaking changes are made to the file format, this number will be incremented to continue supporting extensions using the older format. 
Currently the following values are supported:
* 1: 1.25+
* 2: 1.29+
v2 provides stronger developer validation features, and is recommended if your extension already requires MediaWiki 1.29+. It is not recommended to break MediaWiki compatibility with older versions just to upgrade to a newer manifest_version. There are no plans (as of MediaWiki 1.32) to remove v1.
Example:
{
	"manifest_version": 1
}
Note: This field is typically placed at the bottom of extension.json files.
== name ==
This field is required.
This is the extension's canonical name. It should not be changed once set, as it is used as an API for other extensions to detect what is installed.
{
	"name": "FooBar"
}
== namemsg ==
A localized version of the extension's name. Typically the message key is named in the format <name>-extensionname or <name>-skinname.
{
	"namemsg": "foobar-extensionname"
}
== type ==
The type of extension it is, for sorting on Special:Version. The following types are supported:
* api — API extensions
* antispam — antispam extensions
* editor — extensions for editing content (since 1.31, )
* media — media handlers
* parserhook — extensions that modify, add or replace functionality in the MediaWiki parser
* skin — extensions that modify skins
* specialpage — extensions that add special pages
* variable — make a new variable
* other — does something else
Custom types can be added by using the hook. Known ones include:
* semantic — Semantic MediaWiki extensions
If not set, the extension will default to the "other" section, and if set to an invalid value the extension will not appear on Special:Version.
{
	"type": "specialpage"
}
== author ==
<translate>
The authors of the extension, may contain wikitext.</translate>
<translate>
This can either be a single string, or an array of strings.</translate>
<translate>
Additionally, the special string <tvar|1>...</> may be used to add a generic "<tvar|2></>" suffix using the <tvar|3>version-poweredby-others</> message.
</translate>
== version ==
The current version of the extension. Should be in a format supported by Composer.
== url ==
URL to the extension's "homepage" or documentation. Typically points to https://www.mediawiki.org/wiki/Extension:<extensionname>.
== description ==
Description of the extension, may contain wikitext. Note: it is recommended to use descriptionmsg instead.
== descriptionmsg ==
Localization message key for the extension's description, typically in the format <extensionname>-desc. This will override description.
== license-name ==
The SPDX license identifier for the license the source code is licensed as. If you create a file named COPYING or LICENSE (with an optional .txt extension) in the extension root directory with the contents of the license, it will also be linked and visible from Special:Version.
== requires ==
The requires section allows you to document dependencies on versions of MediaWiki core and other extensions.
{
	"requires": {
		"MediaWiki": ">= 1.27.0",
		"extensions": {
			"FooBar": "*",
			"Baz": ">= 1.2.3"
		}
	}
}
You can use any version specifier that composer supports. For MediaWiki, it is best practice to specify a >= for the minimum supported version, unless you know a future version is explicitly broken. For extensions, if they don't have a version specifier set, or don't use a versioning system, use a plain * to indicate any version is acceptable.
If your extension uses Wikimedia continuous integration, you also need to add extension dependencies to in the integration/config project.
=== platform ===
You can also express a dependency on platform settings, currently limited to PHP version and PHP extensions. Note that most extensions are expected to follow the PHP version requirements for the versions of MediaWiki core they support, and specifying a more restrictive PHP version contraint should only be done in exceptional cases. Checking for PHP extension versions isn't supported right now.
{
	"requires": {
		"MediaWiki": ">= 1.32.0",
		"platform": {
			"php": ">= 7.1",
			"ext-curl": "*"
		}
	}
}
In this example, the extension requires 1.32 (which has a minimum requirement of PHP 7.0), and additionally expresses that it needs a higher dependency of at least PHP 7.1 since it requires usage of some newer PHP feature. Furthermore, it required the curl PHP extension to be installed.
== ResourceFileModulePaths ==
Specifies the default paths to use for all ResourceLoader file modules.
The allowed properties are:
* localBasePath
* remoteExtPath
* remoteSkinPath
These correspond to the same options in each module definition in ResourceModules. If a value is not specified in the module definition, the default value specified here will be used. 
{
	"ResourceFileModulePaths": {
		"localBasePath": "resources",
		"remoteExtPath": "FooBar/resources"
	}
}
== ResourceModules ==
== ResourceModuleSkinStyles ==
== ResourceLoaderSources ==
== ResourceLoaderLESSVars ==
== QUnitTestModule ==
A ResourceLoaderFileModule definition registered only when is true. This follows the same syntax as ResourceModules.
== ConfigRegistry ==
== SessionProviders ==
== AuthManagerAutoConfig ==
The following properties are available:
* preauth: Pre-authentication providers.
* primaryauth: Primary authentication providers.
* secondaryauth: Secondary authentication providers.
== CentralIdLookupProviders ==
== ChangeCredentialsBlacklist ==
== RemoveCredentialsBlacklist ==
== namespaces ==
Method to add extra namespaces.
The following properties are available:
* id: An integer. The numeric identifier of the namespace, as used in the database. Since MW 1.30, the namespace ID can be overwritten locally, by defining the respective constant in LocalSettings.php before loading the extension. Extension code must therefore always use the constant for the namespace ID, and never use the ID as a literal in PHP code.
* constant: A string. The name of the constant that the extension code uses to refer to the namespace ID. 
* name: A string. The name of the namespace, as used in titles.
* gender: Gender object. Properties are either "male" or "female". See gender support. 
* subpages: Boolean. Default is false.
* content: Boolean. Default is false.
* defaultcontentmodel: A string. See .
* protection: Userright(s) required to edit in this namespace. An array or string.
* capitallinkoverride: Set $wgCapitalLinks on a per-namespace basis. Boolean.
* conditional: Whether the namespace is conditional upon configuration and should not be registered (requires separate registration via a hook). Boolean. Default is false.
== TrackingCategories ==
== DefaultUserOptions ==
	"DefaultUserOptions": {
		"math": "png"
	},
== HiddenPrefs ==
== GroupPermissions ==
== RevokePermissions ==
== GrantPermissions ==
== GrantPermissionGroups ==
== ImplicitGroups ==
== GroupsAddToSelf ==
== GroupsRemoveFromSelf ==
== AddGroups ==
== RemoveGroups ==
== AvailableRights ==
== ContentHandlers ==
== RateLimits ==
== RecentChangesFlags ==
== MediaHandlers ==
== ExtensionFunctions ==
== ExtensionMessagesFiles ==
== MessagesDirs ==
If you use the default directory layout with localized messages in the i18n/ directory, you can specify:
"MessagesDirs": {
	"ExtensionName": [
		"i18n"
	]
},
== ExtensionEntryPointListFiles ==
== SpecialPages ==
== AutoloadClasses ==
== AutoloadNamespaces ==
Array containing mapping of namespaces to directories in a PSR-4 compatible manner. Here's an example:
{
	"AutoloadNamespaces": {
		"MediaWiki\\Linter\\": "includes/"
	}
}
In this case all of the PHP classes are under the MediaWiki\Linter\ namespace, and the naming of the classes directly maps to the files located in the includes/ directory (relative to the extension.json file). Note that the namespace portion must end with \\.
Extensions using this feature should require at least MediaWiki 1.31 in extension.json file:
{
	"requires": {
		"MediaWiki": ">= 1.31.0"
	},
}
For example, see Gerrit change 468385.
== TestAutoloadClasses and TestAutoloadNamespaces ==
Both are the same as AutoloadClasses and AutoloadNamespaces, except that they are only used when running tests.
For example, see Gerrit change 556240.
== Hooks ==
{
	"Hooks": {
		"ParserFirstCallInit": "MassMessageHooks::onParserFirstCallInit"
	}
}
It's possible to register multiple callbacks for the same hook event:
{
	"Hooks": {
		"ParserFirstCallInit": [
			"MassMessageHooks::onParserFirstCallInitOne",
			"MassMessageHooks::onParserFirstCallInitTwo"
		]
	}
}
== JobClasses ==
== LogTypes ==
== LogRestrictions ==
== FilterLogTypes ==
== ActionFilteredLogs ==
== LogNames ==
== LogHeaders ==
== LogActions ==
== LogActionsHandlers ==
== Actions ==
== APIModules ==
== APIFormatModules ==
== APIMetaModules ==
== APIPropModules ==
== APIListModules ==
== ValidSkinNames ==
== FeedClasses ==
== SkinOOUIThemes ==
Map of skin names to OOUI themes to use.
{
	"SkinOOUIThemes": {
		"yourskinname": "Apex"
	}
}
== OOUIThemePaths ==
Map of custom OOUI theme names to paths to load them from.
{
	"OOUIThemePaths": {
		"YourTheme": {
			"scripts": "resources/ooui/oojs-ui-yourtheme.js",
			"styles": "resources/ooui/oojs-ui-{module}-yourtheme.css",
			"images": "resources/ooui/{module}.json"
		}
	},
}
; scripts 
: Path to script file.
; styles 
: Path to style files. {module} will be replaced with the module's name.
; images 
: Path to images (optional, can be set to null). {module} will be replaced with the module's name.
== PasswordPolicy ==
== FileExtensions ==
== RawHtmlMessages ==
== ReauthenticateTime ==
== callback ==
A function to be called right after MediaWiki processes this file.
== config ==
The config section is where you can define configuration settings that sysadmins can change to configure the extension. This section should only be used for things that are configured in LocalSettings.php - if it is supposed to be modified by other extensions, you should use attributes, or if it is just class metadata, use a private static variable or something like that. The format of config changed in manifest_version 2, this documentation covers its usage in manifest_version 1.
A simple example:
{
 "config": {
 "FooBarUseExtraFeature": false
 }
}
This is equivalent to writing $wgFooBarUseExtraFeature = false; in PHP. Note that the typical "wg" prefix is not included, as that will be added by default. If your settings start with a different prefix like $eg, you can use the magic _prefix key:
{
	"config": {
		"_prefix": "eg",
		"FooBarUseExtraFeature": false
	}
}
This is now equivalent to writing $egFooBarUseExtraFeature = false; in PHP.
A more complex example:
{
	"config": {
		"FooBarEnabledNamespaces": {
			"0": true,
			"2": true,
			"4": true,
			"_merge_strategy": "array_plus"
		},
		"FooBarCoolStuff": {
			"sysop": {
				"foo": true,
				"bar": false
			},
			"_merge_strategy": "array_plus_2d"
		}
	}
}
The first setting, $wgFooBarEnabledNamespaces, has keys that are numbers, so PHP will turn them into integers, even though they are strings in JSON. Because of how PHP treats integer keys when merging arrays, we need to use a different type of merge here, so we set a different "merge strategy" using the magic key. In the second example, we have a nested array, which requires a different type of merging, since we want to allow people to continue writing $wgFooBarCoolStuff['user']['foo'] = true; in their LocalSettings.php.
=== Changes in manifest version 2 ===
With MediaWiki 1.29, a new manifest_version (2) was introduced. In this version, the config section is improved in several ways. To support these changes, the signature of a set of configuration option and configuration value changed a bit. The key of the config object is still the configuration name, however, the value of that key is an object, which describes this configuration option, where one of the values is the value. You can find information about what the specific keys and values for a configuration option are on the extension registration documentation page. An easy example of the new schema, which simply is one configuration option and it's value, would look like:
{
	"config": {
		"FooBarUseExtraFeature": {
			"value": false
		}
	},
	"manifest_version": 2
}
A more complex one would look like:
{
	"config_prefix": "eg",
	"config": {
		"MyExtSetting": {
			"value": true,
			"path": false,
			"description": "The description for the configuration",
			"descriptionmsg": "myextension-config-myextsetting",
			"public": true
		},
		"FooBarCoolStuff": {
			"value": {
				"sysop": {
					"foo": true,
					"bar": false
				}
			},
		 "merge_strategy": "array_plus_2d"
		}
	},
	"manifest_version": 2
}
==== Paths ====
As demonstrated in the example above, a configuration option can have the path key defined. When present and set to true, the value of the setting will be interpreted as a path local to the extension. For example, an extension might define its configuration as
{
	"config": {
		"Setting": {
			"value": "some_file.txt",
			"path": true
		}
	},
	"manifest_version": 2
}
The value for the configuration option "Setting" will be resolved to $wgExtensionDirectory/FooBar/some_file.txt.
=== Merge strategies ===
The following merge strategies are available:
* array_merge: Default, does not need to be explicitly set. Any keys that are integers will be re-numbered when merging.
* array_plus: Handles keys with integers properly.
* array_plus_2d: Handles nested arrays to a depth of 2 properly (e.g. ). 
* array_plus_recursive: Handles arrays even deeper than 2, though realistically, a configuration setting that is nested more than 2 arrays suggests too many things are being configured in one setting, and splitting it into multiple might be a good idea.
* array_replace_recursive: TODO why should this be used?
== config_prefix ==
Prefix to put in front of configuration settings when exporting them to $GLOBALS.
== ParserTestFiles ==
== ServiceWiringFiles ==
== attributes ==
Registration information for other extensions. This allows one extension to register things with other extensions. Attributes must be PHP arrays, either a list (JSON array) or associative (JSON object)
In manifest_version 1 these were top level keys that could be arbitrarily named:
"EventLoggingSchemas": {
 "MySchema": 123
}
In manifest_version 2, these are now under the top level attributes key, and then nested under the extension name that the attribute belongs towards. The attribute name is still EventLoggingSchemas. If that extension (EventLogging in this example) is not installed, the attributes won't be loaded into the registry.
"attributes": {
 "EventLogging": {
 "Schemas": {
 "MySchema": 123
 }
 }
}
To access the value of an attribute in PHP, you can use the ExtensionRegistry:
$schemas = ExtensionRegistry::getInstance()->getAttribute( 'EventLoggingSchemas' );
== load_composer_autoloader ==
Load the composer autoloader for this extension, if one is present. This should be used if the extension has dependencies on libraries that are specified in composer.json. It is basically equivalent to the following code:
if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
	require_once __DIR__ . '/vendor/autoload.php';
}