Développement d'extensions
Si vous avez l'intention de déployer votre extension sur les sites de Wikimedia, lisez Ecrire une extension pour le déploiement . |
Chaque extension se compose de trois parties :
Une extension a au minimum la structure suivante :
- MyExtension/extension.json
- Contient les instructions de l'installateur. Le nom du fichier doit être "extension.json". (Pour les versions antérieures à MédiaWiki 1.25 les instructions d'installation se trouvent dans un fichier
MyExtension/MyExtension.php
nommé d'après l'extension. Beaucoup d'extensions ont encore des fonctionnalités rétro-compatibles dans ce fichier PHP.) - MyExtension/includes/ (or MyExtension/src/)
- Contient le code PHP d'exécution de l'extension.
- MyExtension/resources/ (or MyExtension/modules/)
- Contient les ressources client de l'extension telles que le JavaScript, le CSS ou le LESS.
- MyExtension/i18n/*.json
- Contient les informations d'internationalisation de l'extension.
Lorsque vous développez une extension, remplacez MyExtension ci-dessus par le nom de votre extension. Utilisez la syntaxe UpperCamelCase pour son répertoire et son/ses fichiers PHP; ce sont les conventions générales de nommage des fichiers .[1] (l'extension BoilerPlate est un bon point d'entrée pour commencer votre extension.)
$wgMainCacheType = CACHE_NONE
et $wgCacheDirectory = false
, sinon les messages système et les autres modifications peuvent ne pas apparaître.
Configuration
Votre but en écrivant la partie de configuration est de faire que l'installation de l'extension soit la plus facile possible, pour que les utilisateurs n'aient qu'à ajouter cette ligne dans LocalSettings.php :
wfLoadExtension( 'MyExtension' );
Si vous voulez rendre votre extension configurable par l'utilisateur, vous devez définir et documenter certains paramètres de configuration et le setup utilisateur devrait ressembler à ceci :
wfLoadExtension( 'MyExtension' );
$wgMyExtensionConfigThis = 1;
$wgMyExtensionConfigThat = false;
Pour parvenir à cette simplicité, votre fichier setup doit effectuer un certain nombre de tâches (décrites en détails dans les sections suivantes) :
- enregistrer tout gestionnaire de média, fonctions d'analyseur, pages spéciale, balises XML personnalisées, et les variable utilisées par votre extension.
- définir et / ou valider toutes les variables de configuration que vous avez définies pour votre extension.
- préparer les classes utilisées par votre extension pour l'auto-chargement
- déterminer quelles parties de votre installation doivent être faites immédiatement et quelles autres peuvent être reportées après que le noyau de MediaWiki a été initialisé et configuré.
- définir toutes les accroches supplémentaires nécessaires à votre extension
- créer ou vérifier toutes les nouvelles tables de la base de données nécessaires à votre extension.
- configurer l'internationalisation de votre extension
.md
. Pour l'exemple, voir le fichier README.md
pour Parsoid sur la Diffusion de Phabricator.
Enregistrement des fonctionnalités avec MediaWiki
MediaWiki liste toutes les extensions qui ont été installées sur sa page de Special:Version
.
A titre d'exemple, vous pouvez voir toutes les extensions installées sur ce wiki sur la page Special:Version.
Version de MediaWiki : | ≥ 1.25 |
Pour faire ceci, ajoutez les détails de l'extension à extension.json . L'entrée ressemblera à quelque chose comme ceci :
{
"name": "Example",
"author": "John Doe",
"url": "https://www.mediawiki.org/wiki/Extension:Example",
"description": "This extension is an example and performs no discernible function",
"version": "1.5",
"license-name": "GPL-2.0-or-later",
"type": "validextensionclass",
"manifest_version": 1
}
Beaucoup de ces champs sont optionnels, mais il est encore bon de les remplir.
La manifest_version
fait référence à la version du schéma pour lequel le fichier extension.json est écrit.
Les versions disponibles sont 1 ou 2. Voir ici la documentation de cette fonctionnalité.
A moins que vous n'ayez besoin de supporter une version plus ancienne de MediaWiki, choisissez la dernière.
En plus de l'enregistrement ci-dessus, vous devez également définir les accroches de votre fonction dans MediaWiki. Ce qui figure ci-dessus ne configure que la page Special:Version . La manière dont vous faites cela dépend du type de votre extension. Pour les détails, voyez la documentation de chaque type d'extension :
Rendre votre extension configurable par l'utilisateur
Si vous voulez que l'utilisateur puisse configurer votre extension, vous devrez fournir une ou plusieurs variables de configuration. C'est une bonne idée que de donner à ces variables un nom unique. Elles devront aussi suivre les conventions de nommage de MediaWiki (par exemple les variables globales doivent commencer par $wg).
Par exemple, si votre extension s'appelle "MyExtension", vous devriez peut-être nommer toutes vos variables de configurations en commençant par $wgMyExtension
.
Ce que vous choisissez n'a pas réellement d'importance tant que personne du cœur de MediaWiki ne commence ses variables de cette manière et vous avez fait un travail raisonnable en vérifiant que personne parmi les extensions publiées n'a fait commencer ses variables de la sorte.
Les utilisateurs n'apprécieront pas de devoir choisir entre votre extension et d'autres extensions parce que vous avez choisi des noms de variables qui se chevauchent.
Une bonne idée aussi est d'inclure la documentation détaillée de toutes les variables de configuration dans vos informations d'installation.
Voici un exemple de boiler plate qui peut être utilisé pour commencer :
{
"name": "BoilerPlate",
"version": "0.0.0",
"author": [
"Your Name"
],
"url": "https://www.mediawiki.org/wiki/Extension:BoilerPlate",
"descriptionmsg": "boilerplate-desc",
"license-name": "GPL-2.0-or-later",
"type": "other",
"AutoloadClasses": {
"BoilerPlateHooks": "includes/BoilerPlateHooks.php",
"SpecialHelloWorld": "includes/SpecialHelloWorld.php"
},
"config": {
"BoilerPlateEnableFoo": {
"value": true,
"description": "Enables the foo functionality"
}
},
"callback": "BoilerPlateHooks::onExtensionLoad",
"ExtensionMessagesFiles": {
"BoilerPlateAlias": "BoilerPlate.i18n.alias.php"
},
"Hooks": {
"NameOfHook": "BoilerPlateHooks::onNameOfHook"
},
"MessagesDirs": {
"BoilerPlate": [
"i18n"
]
},
"ResourceModules": {
"ext.boilerPlate.foo": {
"scripts": [
"resources/ext.boilerPlate.js",
"resources/ext.boilerPlate.foo.js"
],
"styles": [
"resources/ext.boilerPlate.foo.css"
]
}
},
"ResourceFileModulePaths": {
"localBasePath": "",
"remoteExtPath": "BoilerPlate"
},
"SpecialPages": {
"HelloWorld": "SpecialHelloWorld"
},
"manifest_version": 2
}
Remarquez qu'après l'appel à wfLoadExtension( 'BoilerPlate' );
la variable globale $wgBoilerPlateEnableFoo
n'existe pas.
Si vous initialisez la variable, par exemple à LocalSettings.php
, la valeur par défaut qui se trouve dans extension.json ne sera pas utilisée.
Pour plus de détails sur la façon d'utiliser une variable globale dans les extensions personnalisées, veuillez vous référer à Manuel:Configuration pour les développeurs .
Préparer des classes pour l'auto-chargement
Si vous choisissez des classes pour implémenter votre extension, Mediawiki fournit un mécanisme simplifié pour aider PHP à trouver le fichier source dans lequel se trouve votre classe.
Dans la plupart des cas cela évite d'écrire votre propre méthode d' __autoload($classname)
.
Pour utiliser le mécanisme d'auto-chargement de MediaWiki, ajoutez les entrées dans le champ AutoloadClasses . La clé de chaque entrée est le nom de la classe; la valeur est le fichier qui héberge la définition de la classe. Pour une extension simple ne comportant qu'une seule classe, on donne souvent à la classe le nom de l'extension et donc la section d'auto-chargement pourrait ressembler à ceci (avec une extension appelée MyExtension) :
{
"AutoloadClasses": {
"MyExtension": "includes/MyExtension.php"
}
}
Le nom de fichier est relatif au répertoire dans lequel se trouve le fichier extension.json .
Pour les extensions plus complexes, voir les Espaces de noms. Pour plus de détails voir Manual:Extension.json/Schema#AutoloadNamespaces.
Définir des accroches supplémentaires
Voir Manuel:Accroches .
Ajouter des tables dans la base de données
Assurez-vous que l'extension ne modifie pas les tables de la base de données du noyau. A la place, l'extension doit créer de nouvelles tables avec des clés externes vers les tables MediaWiki correspondantes.
Si votre extension a besoin d'ajouter ses propres tables de base de données, utilisez l'accroche LoadExtensionSchemaUpdates . Voir la page du manuel pour davantage d'informations sur l'utilisation.
Configurer l'internationalisation
Voir:
Ajouter des journaux
Sur MediaWiki, toutes les actions des utilisateurs sur le wiki sont tracées pour la transparence et la collaboration. Voir Enregistrer dans Special:Log pour savoir comment faire.
Gérer les dépendances
Supposez qu'une extension nécessite la présence d'une autre extension, par exemple parce que les fonctionnalités des tables de la base de données doivent être utilisées et que l'on ne veut pas voir les messages d'erreur dans le cas où elles sont absentes.
Par exemple l'extension CountingMarker demande la présence de l'extension HitCounters pour certaines fonctions.
Une manière de spécifier cela serait d'utiliser la clé requires
dans extension.json.
Une autre option est d'utiliser ExtensionRegistry (disponible depuis MW 1.25) :
if ( ExtensionRegistry::getInstance()->isLoaded( 'HitCounters', '>=1.1' ) {
/* do some extra stuff, if extension HitCounters is present in version 1.1 and above */
}
Currently (as of February 2024, MediaWiki 1.41.0) the name of the extension-to-be-checked needs to exactly match the name in their extension.json.[2][3]
Example: if you want to check the load status of extension "OpenIDConnect", you have to use it with a space
if ( ExtensionRegistry::getInstance()->isLoaded( 'OpenID Connect' ) {
...
}
Internationalisation
|
$wgMainCacheType = CACHE_NONE
et $wgCacheDirectory = false
, sinon vos modifications des messages système ne seraient pas affichées.Si vous voulez que votre extension soit utilisable sur les wikis qui ont des lecteurs multilingues, vous devez ajouter une prise en charge de l'internationalisation à votre extension.
Enregistrer les messages dans <clé-de-langue>.json
Enregistrer les définitions de messages dans un fichier d'internationalisation JSON, un par clé de langue dans laquelle votre extension a été traduite. Les messages sont enregistrés avec une clé de message et le message lui-même, en utilisant le format standard JSON. Chaque identifiant de message doit être en minuscules et ne doit pas contenir d'espaces. Chaque clé doit commencer par le nom de l'extension en minuscules. Un exemple que vous pouvez trouver par exemple dans l'extension MobileFrontend. Voici un exemple de fichier JSON minimal (dans ce cas en.json:
en.json
{
"myextension-desc": "Adds the MyExtension great functionality.",
"myextension-action-message": "This is a test message"
}
Enregistrer la documentation des messages dans qqq.json
La documentation concernant les clés des messages peut être mise dans le fichier JSON pour le pseudo langage avec le code qqq. Une documentation de l'exemple ci-dessus peut-être :
qqq.json:
{
"myextension-desc": "The description of MyExtension used in Extension credits.",
"myextension-action-message": "Adds 'message' after 'action' triggered by user."
}
Charger le fichier d'internationalisation
Dans votre extension.json, indiquez l'emplacement des fichiers pour les message systèmes (le dossier i18n/ par exemple).
{
"MessagesDirs": {
"MyExtension": [
"i18n"
]
}
}
Utilisation de wfMessage dans PHP
Dans votre code d'installation et d'implémentation, remplacez chaque utilisation littérale du message par un appel à wfMessage( $msgID, $param1, $param2, ... )
.
Dans les classes qui implémentent IContextSource (tout comme dans quelques autres telles que les sous-classes de SpecialPage), vous pouvez utiliser $this->msg( $msgID, $param1, $param2, ... )
à la place.
Exemple:
wfMessage( 'myextension-addition', '1', '2', '3' )->parse()
Utiliser mw.message sous JavaScript
Il est aussi possible d'utiliser les fonctions i18n en JavaScript. Voir API Messages pour les détails.
Types d'extensions
Les extensions peuvent être catégorisées sur la base des techniques de programmation utilisées pour implémenter leurs actions. Les extensions les plus complexes utilisent plus d'une des techniques suivantes :
- Sous-classement: MediaWiki s'attend à ce que certains types d'extensions soient implémentés en tant que sous-classes d'une classe de base fournie par MediaWiki:
- Pages spéciales – Les sous-classes de la classe SpecialPage sont utilisées pour construire des pages dont le contenu est généré dynamiquement en utilisant une combinaison de l'état actuel du système, des paramètres d'entrée de l'utilisateur, et des requêtes à la base de données. A la fois, des rapports et des formulaires de saisie de données peuvent être générés. Ils sont utilisés à la fois pour des raisons statistiques et administratives.
- Habillages – Les habillages modifient l'aspect et le comportement de Mediawiki en modifiant le code qui génère les pages en sous-classant la classe Mediawiki SkinTemplate .
- Accroches – Une technique pour injecter du code php personnalisé aux points-clés du traitement MediaWiki. Elles sont largement utilisées par l'analyseur de MediaWiki, son moteur d'internationalisation, son système de gestion des extensions, et son système de maintenance des pages.
- Associations balise-fonction – Balises de style XML associées à une fonction PHP générant du code HTML. Vous n'avez pas besoin de vous limiter au formatage du texte à l'intérieur des balises. Vous n'avez même pas besoin de l'afficher. Plusieurs extensions de balises utilisent le texte comme paramètre ce qui guide la génération du HTML pour inclure les objets Google, les formulaires d'entrée de données, les flux RSS, et les extraits des articles wiki sélectionnés.
- Mots Magiques – Une technique pour faire correspondre une variété de chaînes de caractères wiki à un ID unique qui est lié à une fonction. A la fois les variables et les fonctions analyseur utilisent cette technique. Tout texte associé à cet identifiant sera remplacé par la valeur retournée par la fonction. La correspondance entre les chaînes de texte et l'identifiant est stockée dans le tableau $magicWords. L'interprétation de l'identifiant est un processus un peu plus complexe – voir Manuel:Mots Magiques pour plus d'information.
- Variable – Les variables sont quelque part comme un abus de langage. Il existe des morceaux de texte wiki qui ressemblent à des modèles mais qui n'ont pas de paramètre et qui ont reçu des valeurs en dur. Le marquage standard de wiki tel que
{{PAGENAME}}
ou{{SITENAME}}
sont des exemples de variables. ils tirent leur nom du source de leur valeur: une variable PHP ou quelque chose qui pourrait être assigné à une variable, par exemple une chaîne, un nombre, une expression, ou la valeur de retour d'une fonction. - Fonctions d'analyse –
{{functionname: argument 1 | argument 2 | argument 3...}}
. De même manière que les extensions de balises, les fonctions d'analyseur traitent les paramètres et retournent une valeur. A l'inverse des extensions de balises, le résultat des fonctions d'analyseur est du texte wiki.
- Variable – Les variables sont quelque part comme un abus de langage. Il existe des morceaux de texte wiki qui ressemblent à des modèles mais qui n'ont pas de paramètre et qui ont reçu des valeurs en dur. Le marquage standard de wiki tel que
- Modules API – vous pouvez ajouter des modules personnalisés à l'API d'action de MediaWiki, appelables par JavaScript, les robots ou les clients tiers.
- Modèles de pages de contenu – Si vous devez enregistrer des données dans des formats autres que du wikicode, JSON, etc. alors vous pouvez créer un nouveau ContentHandler .
Support des autres versions du cœur
Il existe deux conventions largement répandues pour supporter les versions plus anciennes du cœur MediaWiki :
- Master : la branche principale (master) de l'extension est compatible avec autant d’anciennes versions du noyau que possible. Ceci résulte en une lourde charge de maintenance (les développements à compatibilité ascendante doivent être conservés longtemps, et les modifications de l'extension doivent être testées avec plusieurs versions de MediaWiki), mais les sites qui utilisent les anciennes versions de MediaWiki bénéficient des fonctions ajoutées récemment par l'extension.
- Branches de version : les branches de version de l'extension sont compatibles avec les branches correspondantes du noyau, c'est à dire que les sites qui utilisent MediaWiki 1.43 doivent utiliser la branche REL1_43 de l'extension. (pour les extensions qui se trouvent dans gerrit, ces branches sont créées automatiquement lorsque de nouvelles versions de MediaWiki sont diffusées). Le résultat est un code plus propre et un développement plus rapide, mais les utilisateurs qui travaillent avec les anciennes versions du noyau ne bénéficient pas des corrections de bogues ni des nouvelles fonctionnalités, sauf si elles ont été introduites manuellement a posteriori.
Les mainteneurs de l'extension doivent déclarer avec le paramètre compatibility policy
du modèle {{Extension }} la convention suivie.
Licence
MediaWiki est un projet à source libre et les utilisateurs sont encouragés à créer les MediaWiki extensions sous licence Open Source Initiative (OSI) approved et compatible avec GPL-2.0-or-later (licence logicielle standard de Wikimedia).
Nous recommandons d'adopter l'une des licences suivantes compatibles pour vos projets dans Gerrit :
- Licence publique générale GNU, version 2 ou plus récente (GPL-2.0-or-later)
- License MIT (MIT)
- Licence BSD (BSD-3-Clause)
- Licence Apache 2.0 (Apache-2.0)
Pour les extensions qui ont une licence compatible, vous pouvez demander un accès développeur aux dépôts des sources MediaWiki concernant les extensions.
Pour préciser la licence dans le code et avec « license-name
» une clé doit être fournie pour obtenir son nom court, par exemple « GPL-2.0-or-later » ou « MIT » conformémént à la liste des identifiants sur spdx.org.
Publication
Pour auto-catégoriser et pour standardiser la documentation de votre extension existante, veuillez voir Modèle:Extension . Pour ajouter votre nouvelle extension à ce Wiki:
Un développeur qui partage son code sur le dépôt de code MediaWiki doit s'attendre à :
- Des retours / des critiques / des revues de code
- Les revues et commentaires faits par les autres développeurs sur des points comme l'utilisation des composants logiciels, la sécurité, l'efficacité et l'utilisabilité.
- Des ajustements de la part de développeurs
- D'autres développeurs modifiant le code que vous avez proposé afin de l'améliorer ou d'y faire du nettoyage pour qu'il satisfasse aux nouvelles méthodes et classes de composants logiciels, aux conventions de codage et aux traductions.
- Un accès amélioré pour les administrateurs des wikis
- Si vous décidez de mettre votre code sur le wiki, un autre développeur peut décider de le déplacer vers le dépôt de code MediaWiki pour en faciliter la maintenance. Vous pouvez alors créer un Compte développeur pour continuer à le maintenir.
- De futures versions par d'autres développeurs
- De nouvelles branches de votre code, créées automatiquement en tant que nouvelles versions de MediaWiki, peuvent être publiées. Vous devriez effectuer un portage vers ces branches si vous voulez gérer d'anciennes versions.
- Votre code pourra être intégré dans d'autres extensions qui ont un objectif identique ou similaire - en incorporant les meilleurs fonctionnalités de chaque extension.
- Des crédits
- Le crédit de votre travail sera préservé dans les versions futures - y compris les extensions intégrées dans d'autres extensions.
- De même, vous devriez créditer les développeurs de toutes les extensions dont vous avez emprunté le code - en particulier lorsque vous incorporez leur code ailleurs.
Tout développeur qui ne se sent pas à l'aise quant à l'une de ces actions ne devrait pas héberger son code dans le dépôt de code. Vous êtes malgré tout encouragé à créer une page de résumé pour votre extension sur le wiki, afin de permettre aux autres d'en avoir connaissance et de savoir où la télécharger.
Déploiement et enregistrement
Si vous pensez déployer votre extension sur les sites Wikimedia (en incluant éventuellement Wikipedia), un examen supplémentaire est justifié en termes de performances et de sécurité. Consulter Ecrire une extension pour le déploiement .
Si votre extension ajoute des espaces de noms, vous pouvez enregistrer ses espaces de noms par défaut; de manière équivalente, si elle ajoute des tables de bases de données ou des champs, vous pouvez les enregistrer sur Préfixes des champs de base de données .
Veuillez être conscient que la relecture et le déploiement des nouvelles extensions sur les sites Wikimedia peuvent être extrêmement lents, et dans certains cas ont pris plus de deux ans. [4]
Documentation d'aide
Vous devez fournir la documentation d'aide dans le domaine publique pour les fonctions offertes par votre extension.
The convention is for extensions to have their user-focused help pages under a pseudo-namespace of Help:Extension:<ExtensionName>
, with whatever subpages are required (the top level page will be automatically linked from the extension infobox if it exists).
Aide:CirrusSearch est un bon exemple de documentation.
Vous devez donner aux utilisateurs un lien vers la documentation à l'aide de la fonction addHelpLink() .
Diffusion des mises à jour
Il existe un certain nombre d'approches communes pour publier les mises à jour des extensions.
These are generally defined according to the compatibility policy of the extension (master
, rel
, or ltsrel
):
master
- Les versions peuvent être marquées avec des numéros de version sur la branche principale (master) et les documents fournis sur la page d'accueil de l'extension décrivant quelles versions de l'extension sont compatibles avec quelles versions du noyau. Les branches de version seront toujours créées automatiquement et vous pouvez les supprimer si elles ne sont pas destinées à être utilisées.rel
andltsrel
- Release by backporting changes to theREL1_*
branches (either all changes, or only critical ones). Les numéros de version ne sont généralement pas nécessaires à moins que l'extension soit une dépendance d'une autre (le numéro de version peut ensuite être fourni dans la configuration de l'autre extension pour s'assurer que les combinaisons incompatibles ne sont pas installées). De nombreuses extensions resteront avec le même numéro de version pendant des années.
Fournir du support / collaborer
Les développeurs d'extensions doivent ouvrir un compte sur Phabricator de Wikimedia, et demander un nouveau projet pour l'extension. Cela fournit un espace public où les utilisateurs pourront soumettre les problèmes et les suggestions, et vous pourrez collaborer avec les utilisateurs et les autres développeurs pour trier les bogues et planifier les fonctionnalités de votre extension.
Voir aussi
- Manuel:Enregistrement des extensions - provides further developer documentation on how to register extensions and skins.
- API:Extensions – explique comment votre extension peut fournir une API aux clients
- Manuel:Etendre le balisage wiki
- Conventions de codage
- Meilleures pratiques pour les extensions
- ResourceLoader
Learn by example
- Extension:Examples – implémente quelques exemples de fonctionnalités avec une documentation en ligne complète
- Extension:BoilerPlate – une extension Boilerplate fonctionnelle, utile comme point de départ pour votre propre extension (dépôt git)
- Lisez l'extension Example et basez votre propre code sur l'extension BoilerPlate.
- cookiecutter-mediawiki-extension – un modèle cookiecutter qui génère une extension standard (avec variables, etc.)
- Vous permet d'avancer rapidement avec votre propre extension.
- Peut aussi générer l'extension BoilerPlate.
- List of simple extensions - recopiez les parties de code spécifique