Manual:Extension registration/zh

扩展注册（Extension registration）是MediaWiki用于加载扩展和皮肤的机制. 您将配置数据放置在您的扩展或皮肤根目录中，名叫 或 的文件中，然后MediaWiki使用它以注册扩展和皮肤.

Before MediaWiki 1.25, configuration for extensions and skins was done in a PHP file using the extension's or skin's name, for example  or.

这些可以转换为：

如果您保持您的扩展在$IP/extensions以外的位置，您需要覆盖. 如果您的皮肤未在$IP/skins中，您需要覆盖命名错误的. 这必须在您加载任何扩展或皮肤前完成.

Since MW 1.30, namespace IDs defined in extension.json can be overwritten locally, by defining the respective constant in LocalSettings.php before loading the extension. Consider for instance the following namespace declaration in a extension.json file: This would per default cause the constant NS_FOO to be defined to have the value 1212. However, this can be overwritten by defining the respective constant in LocalSettings.php: This would cause the "Foo" namespace to be registered with the ID 6688 instead of 1212. When overriding namespace IDs, don't forget that all talk namespaces must have odd IDs, and the ID of the talk namespace must always be the subject namespace's ID plus one.

用于扩展开发人员的迁移手册

 * 参见扩展注册伤心墙（现已改称超能力墙）.

The script  helps you migrating from PHP entry points to a JSON metadata file. If your extension supports older versions of MediaWiki, you should keep your PHP entry point  until you drop support for those older versions.

示例命令行：

如果您收到常量或函数不能重新定义的错误，您可能需要从 卸载您的扩展. You should replace your PHP entry point file (FooBar.php) with something like the following to not break wikis during the upgrade process.

或皮肤

保留文档
PHP entry points usually have some documentation of configuration settings that is useful and shouldn't be lost. Unfortunately JSON doesn't support comments. It is recommended that you transfer configuration documentation to a  file in the extension's repository. You should also document configuration on-wiki in your Extension:MyExtension page. It is possible to include some documentation directly in the  file as well. Extension registration ignores any key in  starting with ' ' in the top-level structure or under , so you can put comments in those parts of the JSON file. For example:

This should only be used for brief notes and comments.

功能
If you are loading a large number of extensions, extension registration will provide a performance boost as long as you have APC (or APCu) installed. Extensions that are loaded together with  (with plural -s) will be cached together.

属性
A recurring problem is how to "register" something with another extension. Usually this meant that you had to load one extension before another. For example, VisualEditor has a  which allows extensions to add their modules. 然而，在可视化编辑器的入口点却有：

This means that if any extension appends to the array before VisualEditor is loaded, VE will wipe out its entry in this array. Some extensions depended upon a specific load order, others hacked around this with. Extension registration solves this problem with "attributes". In the Math extension, its  would have something like:

Starting with manifest version 2, the attributes need to be defined in the separate section section.

The  node needs to be an object with the extension name as key and an object of attribute/value pairs as the value. Be aware that the key in the subobject must not contain the extension name!

When VisualEditor wants to access this attribute it uses:

要求（依赖性）
Extension registration has a  section, which acts similar to Composer's   section. It allows an extension developer to specify several requirements for the extension, such as a specific MediaWiki version (or greater/less than) or another extension/skin. For example, to add a dependency on a MediaWiki version that is greater than 1.26.0, you can add the following code to :

The key of the  object is the name of the dependency (prior to MediaWiki 1.29.0 only   was supported), the value is a valid version constraint (the format has to match the one used by composer).

In MediaWiki 1.29.0 and above you can also add dependencies on skins and other extensions like so:

Check, if an extension is loaded without actually requiring it
Many extensions may provide features that work only if another extension is loaded too, without really needing this feature for the core extension function to work. As an example: If extension B is loaded, extension A can provide a real WYSIWYG editor, otherwise it will use a simple textarea. Extension A can profit from extension B (if it is loaded), but doesn't require it to be loaded to work properly. For this, you generally check, if the extension is loaded, rather than adding it as a hard dependency.

To implement a standardized way of checking, if an extension is loaded or not (without the need of extra work in an extension that is a soft-dependency in another one), extension registration can be used. It implements an  method, which returns a simple boolean, if the extension is loaded or not (the extension needs to be loaded with extension registration for this to work). Example:

Since MediaWiki 1.32 it's also possible to check if an extension is loaded and satisfies a given composer version constraint:

If you would like to check if a specific version of an extension is loaded in earlier versions of MediaWiki, information like that can be extracted with the  method, which returns credit information for all loaded extensions. Example:

Alternatively, if the extension B defines a special constant meant for this purpose during loading, it is possible to check, if it is defined:

A more brittle way, that should be avoided is to check if a specific class of extension B exists or not, e.g. using this code:

This might break if the extension exists in the file system but is not loaded, e.g. if composer was used for autoloading. If the class was renamed or ceases to exist (e.g. because it is not package public) this will also break.

In general it is preferred to share code via composer components instead of extensions. If the classes of an extension only need to exist, but the extension does not need to be configured nor loaded, for what you want to do, that is a strong indicator that that code should be split off into a composer component you should depend on instead.

配置（您的扩展/皮肤设置）
By default, extension.json assumes that your config settings start with a "wg" prefix.

If that's not the case, you can override the prefix by using a special key:

That would use a prefix of "eg", and set the global variable  to true.

Starting with manifest version 2, the configuration section of extension registration provides a lot more features and allows you to describe your configuration options much more detailed. Instead of having a single key -> value store for your configuration options, you can also add the following information.

The general structure of the  changes slightly to the following, more object-oriented version:

值
The value of the configuration moved to this place. This is the only required key for a configuration object.

路径
The boolean value of the  key identifies, if the value of the configuration option should be interpreted as a filesystem path, relative to the extension directory root. E.g., if the value of the configuration is  and the   is true, the actual value will be.

描述
The  key for a configuration option can hold a non-localized string, which can be used to explain the configuration option to other developers or the users (system administrators) of your extension. The value of the description key is usually not exposed to the frontend of the wiki, however, take a look to the outlook for more information how this feature could be used in the future!

There's also the possibility to add a message key of MediaWiki's internal localisation system as a description, which, in the future, will be used to expose the description in the frontend of the MediaWiki installation.

公开/私有
This option is a boolean, which defaults to false, which means, that the configuration option and the value is marked as "private". This value is not used anywhere at the moment, take a look to the outlook to find out more about this option.

Outlook
The mentioned changes above are also preparation steps for an improved configuration management in MediaWiki. The above changes allow us to, e.g., expose the configuration options of extensions in the MediaWiki UI. For this, the localised description message ( and  ) and the indication, if the configuration option should be exposed or not  is needed.

单位测试自动发现
MediaWiki允许任意扩展注册phpunit测试. Without extension registration, you would need to register a hook handler for the hook, which would look something like:

(as described on the manual page). However, this code looks the same for a lot of extensions, so you could call it unnecessary code duplication. If your extension uses extension registration and your phpunit tests are located in the  subdirectory of your extension, the phpunit wrapper of MediaWiki wil autodiscover the unit tests with the help of extension registration. Therefore, you don't need to register the hook anymore and you don't need to specify, that your unit tests are saved in the default directory.

定制注册
Sometimes extensions need to do non-standard things during registration, or are just very complex. You can specify a 'callback' key in your  if you need to execute some PHP code. The value should be set to a valid PHP callable, for example:. will execute this callback after it processes the  file.

The callback isn't a normal hook function, it runs in early initialization.

See for what sort of things may require custom registration.

See ExtensionFunctions and the SetupAfterCache, BeforeInitialize and ApiBeforeMain hooks for other ways of programmatically interacting with configuration.

同样在composer.json
If an extension or skin has library dependencies, it may have a  file as well, see. Use the  field to make MediaWiki use Composer's autoloading when appropriate. Some metadata fields overlap between  and   (discussed in T89456), including
 * and
 * and

参见

 * Report bugs against the MediaWiki-Configuration project.
 * Old versions of Manual:Developing extensions#Setup (prior to May 2015) and describe the old approach of declaring extension information in PHP code and variables
 * is the schema for  (and skin.json).
 * RfC about implementing extension registration
 * Extension registration wall of superpowers! — summary of which extensions are still to be converted.
 * T98668 — Tracking ticket for converting all extensions and skins on Git to use extension registration.
 * RfC about implementing extension registration
 * Extension registration wall of superpowers! — summary of which extensions are still to be converted.
 * T98668 — Tracking ticket for converting all extensions and skins on Git to use extension registration.