Manual:Erweiterungsregistrierung
MediaWiki Version: | ≥ 1.25 Gerrit change 166705 |
Extension registration ist das Verfahren, das MediaWiki zum Laden von Erweiterungen und Skins nutzt.
Die Konfigurationsdaten werden in eine Datei namens extension.json
oder skin.json
geschrieben, welche im Stammverzeichnis der Erweiterung oder des Skins abgelegt wird. MediaWiki verwendet diese Dateien, um Erweiterungen und Skins zu registrieren.
Umstellungen für Webseiten-Verwalter
Vor MediaWiki 1.25 wurde die Konfiguration für Erweiterungen und Skins in einer PHP-Datei vorgenommen, die den gleichen Namen wie die Erweiterung trug, zum Beispiel MyExtension.php
oder MySkin.php
.
require_once "$IP/extensions/Hello/Hello.php";
require_once "$IP/extensions/FooBar/FooBar.php";
$wgFooBarEnable = true;
require_once "$IP/skins/Baz/Baz.php";
require_once "/tmp/extension/some/where/else/BarFoo/BarFoo.php";
Das schreibt sich jetzt so:
wfLoadExtensions( [ 'Hello', 'FooBar' ] );
$wgFooBarEnable = true;
wfLoadSkin( 'Baz' );
wfLoadExtension( 'BarFoo', '/tmp/extension/some/where/else/BarFoo/extension.json' );
Custom locations
Dies muss geschehen, bevor irgendeine Erweiterung oder ein Skin geladen wird.
- If you keep your extensions in a location different from
$IP/extensions
, you need to override$wgExtensionDirectory
, or use the second parameter ofwfLoadExtension()
, to specify the directory in which to find the extension.- If one or more of your extensions are stored in additional locations, use the second parameter of
wfLoadExtension()
to specify the location of the.json
file for each of those extensions. wfLoadExtensions()
(plural) always uses$wgExtensionDirectory
and cannot be overridden.
- If one or more of your extensions are stored in additional locations, use the second parameter of
$wgExtensionDirectory = '/some/path'; wfLoadExtension( 'FooBar' ); // Looks in $wgExtensionDirectory for /some/path/FooBar/extension.json wfLoadExtension( 'Hello', '/some/other/path/HelloV2/Hello.json' ); // Sucht nach /some/other/path/HelloV2/Hello.json
- Wenn die Skins nicht im Verzeichnis
$IP/skins
gespeichert sind, muss das ungünstig benannte$wgStyleDirectory
angepasst werden.- If one or more of your skins are stored in additional locations, use the second parameter of
wfLoadSkin()
to specify the location of the.json
file for each of those skins. wfLoadSkins()
(plural) always uses$wgStyleDirectory
and cannot be overridden.
- If one or more of your skins are stored in additional locations, use the second parameter of
$wgStyleDirectory = '/my/skins'; wfLoadSkins( [ 'BarBaz', 'BazBar' ] ); // Looks in $wgStyleDirectory for both /my/skins/BarBaz/skin.json and /my/skins/BazBar/skin.json wfLoadSkin( 'BamBam', '/yet/another/path/BamBam/skin.json' ); // Sucht nach /yet/another/path/BamBam/skin.json
Umstellungen für Entwickler von Erweiterungen
Seit MW 1.30 können Namensraum-IDs, die in extension.json
definiert sind lokal überschrieben werden, indem die entsprechende Konstante in LocalSettings.php
definiert wird, bevor die Erweiterung geladen wird.
Betrachte beispielsweise die folgende Deklaration von Namensräumen in extension.json
:
"namespaces": [
{
"id": 1212,
"constant": "NS_FOO",
"name": "Foo"
},
{
"id": 1213,
"constant": "NS_FOO_TALK",
"name": "Foo_Talk"
}
]
Dies würde standardmäßig dazu führen, dass die Konstante NS_FOO so definiert wird, dass sie den Wert 1212 hat. Dies kann allerdings überschrieben werden, indem die entsprechende Konstante in LocalSettings.php definiert wird:
define( 'NS_FOO', 6688 );
define( 'NS_FOO_TALK', 6689 );
wfLoadExtension( "Foo" );
Dies würde dazu führen, dass der „Foo“-Namensraum mit der ID 6688 anstelle der ID 1212 registriert wird. Beim Überschreiben von Namensraum-IDs ist zu beachten, dass alle Diskussions-Namensräume ungerade IDs haben müssen, und dass die ID eines Diskussions-Namensraumes immer der des Inhalts-Namensraums + 1 entsprechen muss.
Das Skript maintenance/convertExtensionToRegistration.php
hilft dabei, PHP-Eintrittspunkte in eine JSON-Metadaten-Datei zu migrieren.
Wenn die Erweiterung ältere Versionen von MediaWiki unterstützt, sollten der PHP-Eintrittspunkt FooBar/FooBar.php
beibehalten werden, solange die Unterstützung für die älteren Versionen bestehen bleibt.
Beispiel für Befehlszeilen :
$ cd core
$ php maintenance/convertExtensionToRegistration.php extensions/MassMessage/MassMessage.php
$ php maintenance/convertExtensionToRegistration.php skins/MonoBook/MonoBook.php --skin
Wenn der Fehler angezeigt wird, dass Konstanten oder Funktionen nicht neu definiert werden konnten, kann es nötig sein, die Erweiterung aus LocalSettings.php
zu deinstallieren.
Sie sollten Ihre PHP Einsprungpunkt-Datei (FooBar.php) mit einem Code wie folgendem ersetzen, damit Wikis während des Aktualisierungsprozesses nicht abbrechen.
<?php
if ( function_exists( 'wfLoadExtension' ) ) {
wfLoadExtension( 'FooBar' );
// Keep i18n globals so mergeMessageFileList.php doesn't break
$wgMessagesDirs['FooBar'] = __DIR__ . '/i18n';
$wgExtensionMessagesFiles['FooBarAlias'] = __DIR__ . '/FooBar.alias.php';
wfWarn(
'Deprecated PHP entry point used for the FooBar extension. ' .
'Please use wfLoadExtension() instead, ' .
'see https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extension_registration for more details.'
);
return;
} else {
die( 'This version of the FooBar extension requires MediaWiki 1.29+' );
}
Oder Skins
<?php
if ( function_exists( 'wfLoadSkin' ) ) {
wfLoadSkin( 'FooBar' );
// Keep i18n globals so mergeMessageFileList.php doesn't break
$wgMessagesDirs['FooBar'] = __DIR__ . '/i18n';
$wgExtensionMessagesFiles['FooBarAlias'] = __DIR__ . '/FooBar.alias.php';
wfWarn(
'Deprecated PHP entry point used for the FooBar skin. Please use wfLoadSkin instead, ' .
'see https://www.mediawiki.org/wiki/Extension_registration for more details.'
);
return;
} else {
die( 'This version of the FooBar skin requires MediaWiki 1.25+' );
}
Dokumentation erhalten
PHP-Einstiegspunkte enthalten normalerweise eine Dokumentation der Konfigurationseinstellungen, die nützlich ist und aufbewahrt werden sollte.
Unfortunately JSON doesn't support comments. It is recommended that you transfer configuration documentation to a README
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 extension.json
file as well.
Extension registration ignores any key in extension.json
starting with '@
' in the top-level structure, so you can put comments in those parts of the JSON file. For example:
{
"@note": "This file must be kept in sync with LocalisationUpdate.php",
"@name": ...
Version 1 of the extension.json
format also allowed @note
in config
section, but this is no longer recommended or supported in version 2. description
field of the config variable should be used instead.
Dies sollte nur für kurze Notizen und Kommentare verwendet werden.
Funktionen
Wenn Sie eine große Anzahl von Erweiterungen laden, bietet "extension registration" eine Leistungssteigerung, sofern APC (or APCu) installiert ist. Erweiterungen, die zusammen mit wfLoadExtensions
(mit Plural -s) geladen werden, werden zusammen gecacht.
Eigenschaften
Ein immer wieder auftretendes Problem ist, wie man etwas bei einer anderen Erweiterung "registriert".
Normalerweise hat dies bedeutet, dass man eine Erweiterung vor einer anderen laden musste.
Zum Beispiel hat VisualEditor ein $wgVisualEditorPluginModules
, das es Erweiterungen ermöglicht ihre Module hinzuzufügen.
Allerdings sieht das Array beim Laden des VisualEditors so aus:
$wgVisualEditorPluginModules = [];
Wenn eine Erweiterung das Array erweitert bevor VisualEditor geladen ist, wird VE beim Laden alle Einträge aus dem Array löschen.
Einige Erweiterungen hingen von einer bestimmten Ladereihenfolge ab, andere hackten um diese mit $wgExtensionFunctions
herum.
Extension registration löst dieses Problem mit "Eigenschaften".
In der Erweiterung Math ist in ihrer extension.json
etwa folgendes eingetragen:
{
"VisualEditorPluginModules": [
"ext.math.visualEditor"
]
}
Seit manifest version 2 müssen Attribute in einem eigenen Abschnitt attributes
definiert werden.
Der attributes
-Knoten muss ein Objekt mit dem Erweiterunsnamen als Schlüssel und einem Objekt von Attribut-Wert-Paaren als Wer sein. Beachte dass der Schlüssel in diesem Objekt nicht den Erweiterungsnamen erhalten muss!
{
"attributes": {
"VisualEditor": {
"PluginModules": [
"ext.math.visualEditor"
]
}
},
"manifest_version": 2
}
Wenn VisualEditor auf dieses Attribut zugreifen möchte, ruft er folgende Funktion auf:
ExtensionRegistry::getInstance()->getAttribute( 'VisualEditorPluginModules' );
Anforderungen (Abhängigkeiten)
Extension registration verfügt über einen requires
-Abschnitt, der sich ähnlich zu Composers require
-Abschnitt verhält.
Er erlaubt einem Erweiterungs-Entwickler mehrere Anforderungen für die Erweiterung, wie beispielsweise eine spezifische MediaWiki Version (oder größer / kleiner als) oder eine andere Erweiterung oder einen anderen Skin anzugeben.
Um zum Beispiel die Abhängigkeit von einer MediaWiki-Version größer als 1.26.0 zu ergänzen, kann folgender Code in extension.json
eingefügt werden: [1]
{
"requires": {
"MediaWiki": ">= 1.26.0"
}
}
Der Schlüssel des requires
Objekts ist der Name der Abhängigkeit ist (vor MediaWiki 1.29.0 war nur MediaWiki
unterstützt), der Wert ist eine gültige Versions-Einschränkung (das Format muss dem von Composer verwendeten entsprechen).
In MediaWiki 1.29.0 und darüber können auch Abhängigkeiten von Skins und anderen Erweiterungen wie folgt hinzugefügt werden:
{
"requires": {
"MediaWiki": ">= 1.29.0",
"extensions": {
"ExampleExtension": "*"
},
"skins": {
"ExampleSkin": "*"
}
}
}
- Die Erweiterungen und Skins, die hier angegeben sind, müssen ebenfalls das Extension-registration-System verwenden, das auf dieser Seite beschrieben wird, damit dies funktioniert.
- Der String der hinzugefügt wurde, um die Erweitrung oder Skins anzugeben, müssen mit dem String in dem "name"-Feld der entsprechenden "extension.json" oder des entsprechenden "skin.json" identisch sein.
- Für Erweiterungen, die Wikimedias Continuous integration verwenden, müssen Abhängigkeiten auch zu zuul/parameter_functions.py hinzugefügt werden.
In MediaWiki 1.33.0(?!??) and above you can also add dependencies on PHP like so:
{
"requires": {
"MediaWiki": ">= 1.33.0",
"platform": {
"php": ">= 7.0.3"
}
}
}
Überprüfe, ob eine Erweiterung geladen ist, ohne sie tatsächlich zu benötigen
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.
Um eine standardisierte Möglichkeit der Überprüfung zu implementieren, ob eine Erweiterung geladen ist oder nicht (ohne die Notwendigkeit von Mehrarbeit in einer Erweiterung, die eine weiche Abhängigkeit von einer anderen hat), kann Extension registration verwendet werden. Sie implementiert eine isLoaded
-Methode, die über ein einfaches boolean zurückgibt, ob die Erweiterung geladen ist oder nicht (die Erweiterung muss mithilfe von "Extension registration" geladen werden, damit dies funktioniert). Beispiel:
if ( ExtensionRegistry::getInstance()->isLoaded( 'ExtensionB' ) ) {
// do things only, if extension B is loaded
}
MediaWiki Version: | ≥ 1.32 Gerrit change 455752 |
Seit MediaWiki 1.32 ist es ebenfalls möglich, zu prüfen, ob eine Erweiterung geladen ist und eine angegebene Composer-Versionseinschränkunge erfüllt.
if ( ExtensionRegistry::getInstance()->isLoaded( 'ExtensionB', '>=1.2' ) ) {
// do things only, if extension B is loaded and has a version of 1.2 or greater.
}
Möchtest du in älteren Versionen von MediaWiki prüfen, ob eine Erweiterung geladen ist, kannst du diese Information mit der getAllThings
-Methode erhalten, die auch Danksagungsinformationen (Credits) für alle geladenen Erweiterungen enthält. Zum Beispiel:
$bVersion = ExtensionRegistry::getInstance()->getAllThings()['ExtensionB']['version'] ?? null;
if ( $bVersion !== null && version_compare( $bVersion, '2.1.0', '>=' ) ) {
// do things only, if extension B is loaded and has a version number greater than or equal to 2.1.0
}
Alternativ: Falls die Erweiterung B eine spezielle Konstante für diesen Zweck beim Laden definiert, ist es möglich zu überprüfen ob diese definiert ist:
if ( defined( 'ExtensionBVersion' ) ) { // You could also check for a version, if the constant holds the version
// do things only, if extension B is loaded
}
Es ist eine unschöne Art und Weise, die vermieden werden sollte, zu überprüfen, ob eine bestimmte Klasse einer Erweiterung vorhanden ist oder nicht, z.B. mit diesem Code:
if ( class_exists( 'ExtensionBHooks' ) ) {
// do things only, if extension B its classes exist
}
Es könnte zu Problemen führen, wenn die Erweiterung im Dateisystem vorhanden, jedoch nicht geladen ist, z.B. wenn Composer für das automatische Laden verwendet wurde. Wenn die Klasse umbenannt wurde oder nicht mehr besteht (zum Beispiel, weil sie nicht öffentlich ist), wird dies auch zu Problemen führen.
Im Allgemeinen wird es bevorzugt, Code über Composer-Bibliotheken anstelle von Erweiterungen zu teilen. Wenn die Klassen einer Erweiterung nur existieren müssen, aber die Erweiterung weder konfiguriert noch geladen sein muss, um das gewünschte zu tun, ist das ein starkes Indiz dafür, dass der Code in eine Composer-Bibliothek abgespalten werden sollte, zu der stattdessen eine Abhängigkeit bestehen sollte.
Konfigurationen (Erweiterungs/Skin-Einstellungen)
Standardmäßig nimmt extension.json
an, dass die Konfigurationseinstellungen mit einem "wg"-Präfix beginnen.
Wenn das nicht der Fall ist, ist es möglich das Präfix mit einem speziellen Schlüssel zu überschreiben:
{
"config": {
"_prefix": "eg",
"MyExtSetting": true
}
}
Das verwendet das Präfix "eg" und setzt die globale Variable $egMyExtSetting
auf true.
Seit manifest version 2 stellt der Einstellungs-Abschnitt der Extension registration deutlich mehr Features zur Verfügung und erlaubt dir, die Einstellungsmöglichkeiten viel detaillierter zu beschreiben. Anstelle eines einzelnen „Schlüssel -> Wert“-Feldes für Einstellungsmöglichkeiten kannst du auch die folgenden Informationen ergänzen:
Die allgemeine Struktur der config
verändert sich ein wenig zu der folgenden, stärker objektorientierten Version:
{
"config_prefix": "eg",
"config": {
"MyExtSetting": {
"value": true,
"path": false,
"description": "The description for the configuration",
"descriptionmsg": "myextension-config-myextsetting",
"public": true
}
},
"manifest_version": 2
}
value
Der Konfigurationswert wird an diesen Ort verschoben. Dies ist der einzige notwendige Schlüssel eines Konfigurationsobjektes.
path
Der boolsche Wert des path
-Schlüssels gibt an, ob der Wert der Einstellungsoption als Pfad im Dateisystem interpretiert werden soll, relativ zum Wurzelverzeichnis der Erweiterung.
Z. B., wenn der Wert der Einstellung myFile.png
ist und path
true ist, ist der tatsächliche Wert path
.
description
Der description
-Schlüssel für eine Einstellung kann einen nicht lokalisierten String erhalten, welcher verwendet werden kann, um sie anderen Entwicklern oder Benutzern (Systemadministratoren) deriner Erweiterung zu erklären.
It may also be used as tooltip text on the parameters section of the extension infobox on the MediaWiki.org extension description page.
Der Wert des description-Schlüssel wird normalerweise nicht im Wiki angezeigt; sieh dir allerdings den Ausblick an, um mehr Informationen darüber zu erhalten, wie dieses Feature in Zukunft verwendet werden könnte!
descriptionmsg
Es ist ebenfalls möglich, einen Nachrichten-Schlüssel (descriptionmsg
) als Beschreibung in MediaWikis internes Lokalisierungssystem hinzufügen, der in Zukunft verwendet werden wird, um die Beschreibung im Wiki anzuzeigen.
public / private
Diese Option ist ein boolscher Wert, der standardmäßig auf false gesetzt ist, was bedeutet, dass die Einstellung und ihr Wert als "private" markiert sind. Dieser Wert wird im Moment nirgendwo verwendet; sieh dir den Ausblick an, um mehr über diese Option herauszufinden.
Ausblick
Die oben genannten Änderungen sind auch als Vorbereitungen für ein verbresserungs Konfigurations-Management in MediaWiki zu verstehen. Die obigen Informationen erlauben unns bspw., diese Optionen von Erweiterungen im MediaWiki-Benutzerinterface anzuzeigen. Zu diesem Zweck werden die lokalisierte Beschreibung (descriptionmsg
und description
) sowie der Hinweis, ob die Option gezeigt werden soll oder nicht (public
) benötigt.
Automatisiertes Auffinden von Unit-Tests
MediaWiki erlaubt jeder Erweiterung, phpunit-Tests zu registrieren. Ohne Erweiterungsregistrierung wäre es nötig, einen Hook-Handler für den UnitTestsList -Hook zu registrieren, was in etwa so aussehen würde:
public static function onUnitTestsList( array &$paths ) {
$paths[] = __DIR__ . '/tests/phpunit/';
}
(wie auf der Handbuch-Seite beschrieben). Dieser Code ist allerdings für viele Erweiterungen identisch, sodass man ihn als unnötige Codedopplung bezeichnen könnte.
Wenn eine Erweiterung Erweiterungsregistrierung verwendet und die phpunit-Tests sich im tests/phpunit/
-Unterverzeichnis der Erweiterung befinden, wird der phpunit-Wrapper von MediaWiki diese Unit-Tests mithilfe von Erweiterungsregistrierung automatisiert finden.
Daher ist es nicht mehr nötig, diesen Hook zu registrieren und anzugeben, dass die Unit-Tests im Standardverzeichnis gespeichert sind.
Anpassen der Registrierung
Siehe auch composer.json
Wenn eine Erweiterung oder Skin Bibliotheksabhängigkeiten hat, kann es auch eine composer.json
-Datei geben, siehe Manual:Composer.json best practices . Verwende das load_composer_autoloader
-Feld, damit MediaWiki das automatische Laden von Composer verwendet, wenn dies angebracht ist.
Some metadata fields overlap between extension.json
and composer.json
(discussed in task T89456), including :
url
andhomepage
license-name
andlicense
Code Stewardship
- Gewartet von Kernplattform-Team .
- Echtzeit-Chat (IRC): #mediawiki-core connect
- Problem-Tracker: Phabricator MediaWiki-Configuration (Ein Problem melden)
Siehe auch
- Handbuch:extenstion.json/Schema
- Melde Fehler dem MediaWiki-Configuration-Projekt.
- Alte Versionen der Manual:Developing extensions#Setup (vor Mai 2015) und
$wgExtensionCredits
beschreiben den alten Ansatz, Erweiterungsinformationen in PHP-Code und Variablen zu deklarieren - Bekannte Einschränkungen
- Überblick über die Architektur
docs/extension.schema.v2.json
ist das Schema fürextension.json
(und skin.json).- RfC zur Umsetzung der Registrierung von Erweiterungen
- Extension registration wall of superpowers! — summary of which extensions are still to be converted.
- task T98668 — Tracking ticket for converting all extensions and skins on Git to use extension registration.