Manuel:Enregistrement des extensions
Version de MediaWiki : | ≥ 1.25 Gerrit change 166705 |
L’enregistrement des extensions est un mécanisme utilisé par MediaWiki pour charger les extensions et les habillages.
Vous placez les données de configuration dans un fichier nommé extension.json
ou skin.json
dans le dossier racine de votre extension ou votre habillage et MediaWiki utilise ces données pour enregistrer les extensions et les habillages.
Migration pour les administrateurs de sites
Avant la version 1.25 de MediaWiki, la configuration des extensions et des habillages était réalisée dans un fichier PHP portant le nom de l’extension ou de l’habillage, par exemple MyExtension.php
ou 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";
Cela peut être converti en :
wfLoadExtensions( [ 'Hello', 'FooBar' ] );
$wgFooBarEnable = true;
wfLoadSkin( 'Baz' );
wfLoadExtension( 'BarFoo', '/tmp/extension/some/where/else/BarFoo/extension.json' );
Emplacements personnalisés
Cela doit être fait avant tout chargement d’extension ou d’habillage à partir d'emplacements non standard des repertoires :
- Si vous conservez vos extensions dans un endroit différent de
$IP/extensions
, vous devez modifier$wgExtensionDirectory
ou utiliser le second paramètre dewfLoadExtension()
pour spécifier le répertoire dans lequel se trouve l'extension.- Si une ou plusieurs de vos extensions sont stockées à des endroits supplémentaires, utilisez le second paramètre de
wfLoadExtension()
pour spécifier l'emplacement du fichier.json
pour chacune de ces extensions. wfLoadExtensions()
(plusieurs) utilise toujours$wgExtensionDirectory
et ne peut être redéfini.
- Si une ou plusieurs de vos extensions sont stockées à des endroits supplémentaires, utilisez le second paramètre de
$wgExtensionDirectory = '/some/path'; wfLoadExtension( 'FooBar' ); // Cherche /some/path/FooBar/extension.json dans $wgExtensionDirectory wfLoadExtension( 'Hello', '/some/other/path/HelloV2/Hello.json' ); // Cherche /some/other/path/HelloV2/Hello.json
- Si vos habillages ne sont pas situés dans
$IP/skins
, vous devez modifier la variable (mal nommée)$wgStyleDirectory
ou utiliser le second paramètre dewfLoadSkin()
, pour spécifier le répertoire dans lequel se trouve l'habillage.- Si un ou plusieurs de vos habillages sont stockés à des endroits supplémentaires, utilisez le second paramètre de
wfLoadSkin()
pour spécifier l'emplacement du fichier.json
pour chacun de ces habillages. wfLoadSkins()
(plusieurs) utilise toujours$wgStyleDirectory
et ne peut être redéfini.
- Si un ou plusieurs de vos habillages sont stockés à des endroits supplémentaires, utilisez le second paramètre de
$wgStyleDirectory = '/my/skins'; wfLoadSkins( [ 'BarBaz', 'BazBar' ] ); // Cherche dans $wgStyleDirectory pour à la fois /my/skins/BarBaz/skin.json et /my/skins/BazBar/skin.json wfLoadSkin( 'BamBam', '/yet/another/path/BamBam/skin.json' ); // Cherche /yet/another/path/BamBam/skin.json
Migrer, pour les développeurs d’extensions
Depuis MediaWiki 1.30, les IDs des espaces de noms définis dans extension.json
peuvent être remplacés localement, en définissant la constante respective dans LocalSettings.php
avant de charger l'extension.
Supposez par exemple la déclaration d'espace de noms suivante dans un fichier extension.json
:
"namespaces": [
{
"id": 1212,
"constant": "NS_FOO",
"name": "Foo"
},
{
"id": 1213,
"constant": "NS_FOO_TALK",
"name": "Foo_Talk"
}
]
Par défaut, cela fera que la constante NS_FOO sera définie avec la valeur 1212. Néanmoins ceci peut être réécrasé en définissant la constante respective dans le fichier LocalSettings.php :
define( 'NS_FOO', 6688 );
define( 'NS_FOO_TALK', 6689 );
wfLoadExtension( "Foo" );
Cela entraînerait l'enregistrement de l'espace de noms « Foo » avec l'ID 6688 au lieu de 1212. Lorsque vous redéfinissez les IDs des espaces de noms, n'oubliez pas que tous les IDs des espaces de discussion doivent avoir des valeurs impaires, et les IDs des espaces de discussion doivent avoir pour valeur celle de l'ID de l'espace de nom du sujet, plus un.
Le script maintenance/convertExtensionToRegistration.php
vous aide à migrer vos points d’entrée PHP vers un fichier de métadonnées JSON.
Si votre extension prend en charge d’anciennes versions de MediaWiki, vous pouvez garder votre point d’entrée PHP FooBar/FooBar.php
jusqu’à ce que vous retiriez le support pour ces anciennes versions.
Exemple de lignes de commande :
$ cd core
$ php maintenance/convertExtensionToRegistration.php extensions/MassMessage/MassMessage.php
$ php maintenance/convertExtensionToRegistration.php skins/MonoBook/MonoBook.php --skin
Vous pourriez avoir besoin de désinstaller votre extension dans LocalSettings.php
si vous avez des erreurs disant que des fonctions ou des constantes ne peuvent pas être redéfinies.
Vous devriez remplacer votre fichier de point d’entrée PHP (FooBar.php) par quelque chose qui ne casse pas les wikis durant le processus de mise à jour.
<?php
if ( function_exists( 'wfLoadExtension' ) ) {
wfLoadExtension( 'FooBar' );
// garder i18n global pour que mergeMessageFileList.php continue à fonctionner
$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+' );
}
Ou, pour les habillages :
<?php
if ( function_exists( 'wfLoadSkin' ) ) {
wfLoadSkin( 'FooBar' );
// garder i18n global pour que mergeMessageFileList.php continue à fonctionner
$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+' );
}
Conserver la documentation
Les points d’entrée PHP contiennent généralement de la documentation pour les options de configuration, ce qui est utile et ne devrait pas être perdu.
Malheureusement, le JSON ne permet pas d’inclure de commentaires. Il est recommandé de déplacer la documentation de la configuration dans un fichier README
placé dans le dépôt de l'extension.
Vous devriez aussi documenter votre extension sur ce wiki dans la page Extension:MonExtension.
Il est en plus possible d’inclure un peu de documentation directement dans le fichier extension.json
.
Le système d’enregistrement des extensions ignore toutes les clés dans extension.json
dont les noms commencent avec le caractère '@
' dans la structure de niveau le plus global; vous pouvez ainsi insérer des commentaires à ces endroits du fichier JSON. Par exemple :
{
"@note": "This file must be kept in sync with LocalisationUpdate.php",
"@name": ...
La version 1 du format extension.json
autorise aussi @note
dans la section config
, mais cela n'est plus recommandé ni pris en charge dans la version 2. Utilisez le champ description
de la variable config à la place.
Ceci ne devrait être utilisé que pour les notes courtes et les commentaires.
Fonctionnalités
Si vous chargez un grand nombre d’extensions, l’enregistrement d’extensions permettra un gain de performance tant que APC (ou APCu) est installé. Les extensions qui sont chargées ensemble avec wfLoadExtensions
(avec un suffixe -s marquant le pluriel) seront mises en cache ensemble.
Attributs
Un problème récurrent est la façon « d’enregistrer » quelque chose avec une autre extension.
En général, cela signifie que vous avez à charger une extension avant l'autre.
Par exemple, l’Editeur Visuel a un $wgVisualEditorPluginModules
qui permet aux extensions d’ajouter leurs modules.
Ainsi, dans le point d’entrée de l’Editeur Visuel, il y a :
$wgVisualEditorPluginModules = [];
Cela signifie que si une extension ajoute quelque chose au tableau avant que l’Editeur Visuel ne soit chargé, celui-ci effacera l’entrée dans ce tableau.
Certaines extensions dépendent d’un ordre de chargement particulier, d’autres utilisent cela avec $wgExtensionFunctions
.
L’enregistrement d’extensions résoud ce problème avec les « attributs ».
Dans l’extension Math, son extension.json
aurait quelque chose comme :
{
"VisualEditorPluginModules": [
"ext.math.visualEditor"
]
}
A partir de manifest version 2, les attributs doivent être définis dans la section séparée attributes
.
Le noeud attributes
doit être un objet avec le nom de l'extension comme clé et un objet de paires attribut/valeur pour valeur. Notez bien que la clé du sous-objet ne doit pas contenir le nom de l'extension !
{
"attributes": {
"VisualEditor": {
"PluginModules": [
"ext.math.visualEditor"
]
}
},
"manifest_version": 2
}
Quand l’Editeur Visuel veut accéder à cet attribut, il utilise :
ExtensionRegistry::getInstance()->getAttribute( 'VisualEditorPluginModules' );
Prérequis (dépendances)
L'enregistrement d'extension possède une section requires
, qui agit de manière similaire à la section require
de Composer.
Elle permet à un développeur d'extensions de spécifier plusieurs prérequis pour l'extension, comme une version spécifique de MediaWiki (ou plus récent que, plus ancien que) ou une autre extensions ou habillage.
Par exemple, pour ajouter une dépendance sur une version de MediaWiki plus récente que 1.26.0, vous pouvez ajouter le code suivant dans extension.json
: [1]
{
"requires": {
"MediaWiki": ">= 1.26.0"
}
}
La clé de l'objet requires
est le nom de la dépendance (avant MediaWiki 1.29.0 seulement MediaWiki
était pris en charge), la valeur est une contrainte de version valide (le format doit être compatible avec celui utilisé par Composer).
Dans MediaWiki 1.29.0 et plus récent vous pouvez aussi ajouter des dépendances vers des habillages ou d'autres extensions comme par exemple :
{
"requires": {
"MediaWiki": ">= 1.29.0",
"extensions": {
"ExampleExtension": "*"
},
"skins": {
"ExampleSkin": "*"
}
}
}
- Les extensions et habillages spécifiés ici doivent aussi utiliser le système d'enregistrement des extensions décrit sur cette page pour que cela fonctionne.
- La chaîne ajoutée pour préciser l'extension ou l'habillage doit être la même que la chaîne spécifiée dans le champ « name » du fichier « extension.json » ou « skin.json » respectif.
- Pour les extensions qui utilisent l'intégration continue de Wikimedia, les dépendances doivent également être ajoutées à zuul/parameter_functions.py
Dans MediaWiki 1.33.0 (?) et ultérieur, vous pouvez aussi ajouter des dépendances sur PHP ainsi :
{
"requires": {
"MediaWiki": ">= 1.33.0",
"platform": {
"php": ">= 7.0.3"
}
}
}
Vérifier qu'une extension est chargée alors qu'elle n'est pas nécessaire
Beaucoup d'extensions peuvent apporter des fonctionalités qui ne travaillent que si une autre extension est également chargée, sans que cette fonctionalité ne soit réellement demandée pour que la fonction d'extension du noyau soit opérationnelle. Comme exemple : si l'extension B est chargée, l'extension A peut fournir un éditeur réellement WYSIWYG, sinon on utilisera une simple zone textuelle. L'extension A peut profiter de l'extension B (si elle est chargée), mais n'en n'a pas besoin pour être chargée et fonctionner correctement. Pour cela on regarde habituellement si l'extension est chargée plutôt que de l'ajouter comme dépendance codée en dur.
Pour implémenter une manière standardisée pour vérifier qu'une extension est chargée ou pas (sans avoir besoin de développement supplémentaire dans une extension qui dépend logiciellement d'une autre), l'enregistrement d'extension peut être utilisé. Il implémente une méthode isLoaded
, qui retourne un booléen indiquant si l'extension est chargée ou pas (l'extension doit être chargée avec l'enregistrement d'extension pour que cela fonctionne). Exemple:
if ( ExtensionRegistry::getInstance()->isLoaded( 'ExtensionB' ) ) {
// exécuter seulement si l'extension B est chargée
}
Version de MediaWiki : | ≥ 1.32 Gerrit change 455752 |
Depuis MediaWiki 1.32 il est également possible de vérifier si une extension est chargée et si elle satisfait une contrainte de version de Composer :
if ( ExtensionRegistry::getInstance()->isLoaded( 'ExtensionB', '>=1.2' ) ) {
// exécuter seulement si l'extension B est chargée et que sa version est 1.2 ou supérieur.
}
Si vous vouliez vérifier qu'une version spécifique d'une extension était chargée dans les précédentes versions de MediaWiki, ce type d'information peut être extrait avec la méthode getAllThings
, qui retourne l'information de crédit pour toutes les extensions chargées. Exemple:
$bVersion = ExtensionRegistry::getInstance()->getAllThings()['ExtensionB']['version'] ?? null;
if ( $bVersion !== null && version_compare( $bVersion, '2.1.0', '>=' ) ) {
// exécuter seulement si l'extension B est chargée et que sa version est 2.1.0 ou supérieur.
}
De la même manière, si l'extension B définit une constante spéciale dans ce but durant le chargement, il est possible de vérifier si elle est définie :
if ( defined( 'ExtensionBVersion' ) ) { // You could also check for a version, if the constant holds the version
// exécuter seulement si l'extension B est chargée
}
Une autre manière parallèle qui doit être évitée est de vérifier si une classe spécifique de l'extension B existe ou pas, par exemple en utilisant le code :
if ( class_exists( 'ExtensionBHooks' ) ) {
// exécuter seulement si l'extension B existe
}
Ceci peut ne pas fonctionner si l'extension existe dans le système de fichiers mais n'est pas chargée, par exemple si Composer a été utilisé pour l'auto-chargement. Si une classe a été renommée ou cesse d'exister (par exemple parce qu'elle ne fait plus partie des paquets publiques) cela va provoquer également la rupture.
En général, il est préférable de partager le code par des composants Composer plutôt que des extensions. Si les classes d'une extension n'ont besoin que d'exister, mais que l'extension n'a pas besoin d'être configurée ni chargée pour ce que vous voulez en faire, c'est une très bonne indication que le code doit être découpé dans un composant Composer duquel vous devez dépendre à la place.
Configurations (vos paramètres d'extensions et d'habillages)
Par défaut, extension.json
suppose que vos paramètres de configuration commencent avec le préfixe « wg ».
Si ce n'est pas le cas, vous pouvez réécraser le préfixe en utilisant une clé spéciale :
{
"config": {
"_prefix": "eg",
"MyExtSetting": true
}
}
Cela va utiliser le préfixe « eg » et mettre la variable globale $egMyExtSetting
à true.
À partir de manifest version 2, la section de configuration de l'enregistrement des extensions fournit beaucoup plus de fonctionnalités et vous permet de décrire vos options de configuration de manière beaucoup plus détaillée. Au lieu d'avoir enregistré une seule clé → valeur pour vos options de configuration, vous pouvez également ajouter les informations suivantes.
La structure générale de la config
change légèrement par la suite, en devenant une version plus orientée objet :
{
"config_prefix": "eg",
"config": {
"MyExtSetting": {
"value": true,
"path": false,
"description": "Description de la configuration",
"descriptionmsg": "myextension-config-myextsetting",
"public": true
}
},
"manifest_version": 2
}
value
La valeur de la configuration a été déplacée à cet endroit. C'est la seule clé obligatoire pour un objet configuration.
path
La valeur booléenne de la clé path
indique si la valeur de l'option de configuration doit être interprétée comme un chemin dans le système de fichiers, relativement au répertoire racine de l'extension.
Par exemple, si la valeur de la configuration est myFile.png
et que path
vaut true, la valeur actuelle sera /path/to/the/wiki/extensions/MyExtension/myFile.png
.
description
La clé description
pour une option de configuration peut contenir une chaîne non traduite, qui peut être utilisée pour expliquer l'option de configuration de votre extension, aux autres développeurs ou aux utilisateurs (administrateurs système).
Peut être aussi utilisé comme texte d'infobulle pour la section des paramètres dans la boîte d'information de l'extension, sur la page de description de l'extension de MediaWiki.org.
La valeur de la clé de decription n'est habituellement pas affichée pour l'IHM du wiki, néanmoins, cherchez sur le sujet pour avoir plus d'informations sur la manière dont cette fonctionalité pourrait être utilisée dans le futur !
descriptionmsg
Il existe aussi la possbilité d'ajouter en tant que description (descriptionmsg
), une clé du message dans le sytème de localisation interne de MediaWiki, ce qui dans le futur, sera utilisé pour présenter la description au niveau de l'interface utilisateur de l'installation MediaWiki.
public / private
Cette option est un booléen, qui vaut false
par défaut, ce qui signifie que l'option de configuration et la valeur sont marquées "private".
Cette valeur est utilisée nulle part en ce moment, cherchez un peu sur le sujet pour en découvrir plus à propos de cette option.
Perspectives
Les modifications mentionnées ci-dessus sont également des étapes préparatoires pour une gestion améliorée de la configuration dans MediaWiki. Ces changements nous permettent par exemple d'afficher les options de configuration des extensions dans l'IHM MediaWiki. Pour cela, le message de description traduit (descriptionmsg
et description
) ainsi que l'indication si l'option de configuration peut être affichée ou pas (public
) sont nécessaires.
Auto-découverte des tests unitaires
MediaWiki permet à toute extension d'enregistrer des tests unitaires php. Sans l'enregistrement d'extension, vous devriez enregistrer un gestionnaire pour l'accroche UnitTestsList , qui ressemblerait à ceci :
public static function onUnitTestsList( array &$paths ) {
$paths[] = __DIR__ . '/tests/phpunit/';
}
(comme décrit sur la page du manuel). Cependant, ce code a la même apparence pour beaucoup d'extensions, vous pouvez donc appeler cela une duplication inutile du code.
Si votre extension utilise l'enregistrement des extensions et que vos tests phpunit se trouvent dans le sous-répertoire tests/phpunit/
de votre extension, le conteneur phpunit de MediaWiki va découvrir automatiquement les tests unitaires avec l'aide de l'enregistrement des extensions.
C'est pourquoi il n'est plus utile d'enregistrer l'accroche, ni de spécifier que les tests unitaires sont stockés dans le répertoire par défaut.
Personnaliser l’enregistrement
Et composer.json
Si une extension ou un habillage dépendent de bibliothèques, il peut exister également un fichier composer.json
, voir Manuel:Bonnes pratiques pour composer.json . Utilisez le champ load_composer_autoloader
pour que MediaWiki se serve de l'auto-chargement de Composer quand c'est nécessaire.
Quelques champs de métadonnées sont les mêmes entre extension.json
et composer.json
(discussion dans tâche T89456), dont :
url
ethomepage
license-name
etlicense
Gestion du code
- Maintenu par l' Equipe Plateforme noyau .
- Discussion en direct (IRC): #mediawiki-core connect
- Suivi des problèmes : Phabricator MediaWiki-Configuration (rapporter un problème)
Voir aussi
- Manuel:Extension.json/Schéma
- Rapportez les bogues dans le projet MediaWiki-Configuration.
- Les anciennes versions de Développer des extensions/paramètres (avant mai 2015) et
$wgExtensionCredits
décrivent l’ancienne approche de déclaration des informations des extensions dans les variables et le code PHP - Limitations connues
- Aperçu de l’architecture
docs/extension.schema.v2.json
est le schéma pourextension.json
(et skin.json).- RfC à propos de l’implémentation d’un système d’enregistrement d'extensions
- Mur d'enregistrement d'extensions de super pouvoirs ! — résumé des extensions qui doivent encore être converties.
- tâche T98668 — Ticket pour le suivi de la conversion de toutes les extensions et habillages sur Git afin qu'ils utilisent l'enregistrement d'extension.