Bonnes pratiques pour les extensions
Cette page documente un guide de développement de MediaWiki, construit au fil du temps par consensus des développeurs (ou parfois simplement par un des développeurs principaux) |
Cette page documente les meilleures pratiques actuelles pour développer les extensions MédiaWiki. Sauf indication contraire, ceci s'applique également aux habillages.
A chaque élément ci-dessous on attribue une appréciation qui montre son importance relative. La notation utilise les mots clé définis pour les besoins, par la RFC 2119. Voici ce qu'ils signifient en fonction du contexte :
- MUST: cet élément est obligatoire. Les éléments concernés signifient que votre extension fonctionnera mais qu'elle risque de ne pas perdurer.
- SHOULD: cet élément est recommandé. Les éléments concernés signifient de même que votre extension fonctionnera bien et continuera de fonctionner convenablement à l'avenir.
- OPTIONAL: cet élément est facultatif. Nous vous encourageons à le privilégier. Les éléments concernés sont les extensions pouvant être considérées comme répondant à la norme d'or à laquelle nous aspirons tous, et utilisables comme exemple pour les autres développeurs.
Flux de travail
- MUST: utiliser le suiveur de problèmes standard. Créez ou demandez la création d'un projet dans Phabricator pour votre extension.
- MUST: utiliser le système standard Relecture de code .
- MUST: avant le déploiement sur les wikis de la Fondation Wikimedia – effectuer la revue des performances et de la sécurité .
- SHOULD: l'extension doit être adaptée à l'utilisation sur n'importe quel wiki, éviter les spécificités de codage en dur pour la Fondation Wikimedia ou d'autres organisations.
- SHOULD: avant le déploiement sur les wikis de la Fondation Wikimedia – ajouter l'extension ainsi que votre équipe sur la page des mainteneurs .
- SHOULD: avoir plusieurs maiteneurs ! Il faut deux mainteneurs au minimum. (pas forcément issus du personnel de la Fondation Wikimedia).
- OPTIONAL: créer un guide d'installation MediaWiki-Docker pour votre extension.
- OPTIONAL: créer un rôle MediaWiki-Vagrant pour votre extension.
Architecture du code
- MUST: utiliser la journalisation structurée, avec un nom de canal propre à votre extension et une utilisation appropriée des niveaux de sévérité des messages. Ceci aide au debogage. Pour le déploiement de la Fondation Wikimedia, cela aide également votre équipe à surveiller l'extension. Voir aussi : Logstash sur Wikitech.
- SHOULD: fournir la même fonctionnalité via l'API Action ou l'API REST que par l'interface graphique (
index.php
).- OPTIONAL: La fonctionnalité doit être implémentée sans duplication excessive du code (par exemple partager une classe de service du serveur ayant une API allégée et utiliser des liens vers les pages spéciales).
- SHOULD: utiliser Dependency Injection (DI) et les classes de services enregistrées dans l'intégration de services.
- SHOULD: éviter les états globaux, particulièrement pour les singletons ou pour les états masqués par des variables de classe statiques (sauf pour les journaux de débogage et les autres états internes du processus courant et non pas pour un wiki ou un appelant particulier). Eviter les appels statiques pour tout ce qui n'est pas une méthode utilitaire sans état.
- SHOULD: éviter l'utilisation d'anciennnes fonctions globales ou statiques non refactorisées provenant de classes non liées lorsque vous écrivez de nouvelles classes de service basées sur DI.
- SHOULD: ne générer des exceptions que pour des situations qui ne sont pas à gérer par les appelants et qui sont donc censées être remontées.
- SHOULD: ne pas coder en dur le wikicode ni les suppositions à propos des modèles, surtout s'ils ne deviennent plus configurables par chaque site Web.
- SHOULD: le code doit être compréhensible par toute personne familière avec le domaine en question.
- SHOULD: séparer les sujets clairement entre ce qui est fait actuellement et la manière dont cela est présenté à l'utilisateur.
- SHOULD: réfléchir à deux fois avant d'ajouter de nouvelles API publiques qui doivent rester compatibles avec l'existant vis à vis des contenus, telles qu'une fonctionnalité de nouvelle syntaxe de wikicode.
- SHOULD: ne pas lier intrinsèquement la fonctionnalité de l'habillage à celle de l'extension.
- SHOULD: ne pas ajouter de nouvelles préférences utilisateur , sauf si vous avez de bonnes raisons de le faire.
- OPTIONAL: exposer les méthodes JavaScript pour qu'elles soient utilisables par user scripts et les gadgets , et pour permettre le débogage facile à partir de la console.
Documentation
- MUST: avoir une page Extension:… sur mediawiki.org.
- MUST: l'ajouter aux catégories de l'extension concernées.
- MUST: expliquer brièvement ce que cela fait.
- MUST: documenter les accroches fournies dans
Extension:Nom de l'extension/Hooks/nom de l'accroche
en utilisant {{Template:ExtensionHook}} (s'il y en a). - MUST: lister toutes les extensions dont elle dépend et décrire comment les installer et les configurer.
- SHOULD: définir les règles de compatibilité de votre extension dans la boîte d'information.
- SHOULD: décrire tous les paramètres de configuration en un seul endroit, du plus fréquent au plus rarement utilisé.
- OPTIONAL: mentionner les extensions similaires et les comparer en indiquant en quoi elles diffèrent de celles-ci.
- OPTIONAL: écrire les instructions pour désinstaller l'extension ou documenter la capacité limitée à la désinstaller.
- MUST: avoir une page Help:Extension:… sur mediawiki.org si l'extension possède des interfaces utilisateur sur le web.
- OPTIONAL: ajouter des captures d'écran pour diverses langues et dans l'idéal inclure un exemple de langue RTL s'écrivant de droite à gauche (right-to-left ).
- OPTIONAL: mentionner quelques cas aux limites qui ont été testés pour – prouver que l'on ne s'est pas simplement limité aux tests des articles élémentaires ou génériques.
- SHOULD: utiliser de manière cohérente
<code>
,<syntaxhighlight>
,<kbd>
, et<pre>
dans la documentation selon le cas. - OPTIONAL: ajouter ou mettre à jour la page de l'extension sur WikiApiary .
Structure des fichiers
Dans l'ensemble, l'arborescence des fichiers de l'extension doit être organisée : le nommage est cohérent, la structure des répertoires est logique et ordonnée.
- MUST: en utilisant la structure de répertoire classique suivante :
src/
(lorsque vous utilisez l'espacement de noms PSR4, préféré) ouincludes/
: contient toutes les classes PHP (et uniquement).- fichiers i18n pour les alias des pages spéciales, les mots magiques et les espaces de noms situés dans le répertoire racine.
- SHOULD: utiliser la structure PSR-4 pour les classes et les fichiers, en utilisant Extension.json/Schema#AutoloadNamespaces dans
extension.json
au lieu de lister toutes les classes. - SHOULD: classes de l'espace de noms
MediaWiki\Extension\<nom de l'extension>
(ouMediaWiki\Skin\<nom de l'habillage>
s'il s'agit d'un habillage). LeMediaWiki\<nom de l'extension>
est autorisé si celui-ci est un mot unique qui se suffit à lui-même et non pas un mot générique (c'est à dire ni un verbe, ni un nom). - SHOULD: une classe par fichier.
modules/
(ouresources
) - contient le JavaScript et le CSS pour ResourceLoader .- ligne de commande
maintenance/
scripts de maintenance i18n/
- mettre les messages traduits dans des fichiers JSON.sql/
- fichiers SQL concernant les modifications de la base de données (par exemple appelés par LoadExtensionSchemaUpdates )tests/
:tests/parser/
- contient les fichiers de test de l'analyseur syntaxique .tests/phpunit/
- contient les cas de test de PHPUnit .tests/phpunit/unit/
- contient les cas de test qui étendentMediaWikiUnitTestCase
tests/phpunit/integration/
- contient les cas de test qui étendentMediaWikiIntegrationTestCase
tests/qunit/
- contient les cas de test de Qunittests/selenium/
- contient les fichiers de test du navigateur Selenium .
COPYING
ouLICENSE
- contient la copie complète de la licence sous laquelle le code est diffusé.
- SHOULD: éviter d'avoir trop de fichiers dans le répertoire racine.
- SHOULD: éviter l'utilisation imbriquée de repertoires multiples où chacun ne contient qu'un ou deux éléments.
- SHOULD: éviter d'avoir des fichiers énormes, ou beaucoup de très petits fichiers (mais garder toujours une classe par modèle de fichier – trop de petites classes est souvent le signe d'une mauvaise conception).
- SHOULD: créer un fichier README qui résume la documentation et contient les instructions détaillées d'installation.
- SHOULD: déclarer les ressources externes dans un fichier
foreign-resources.yaml
.
Base de données
- MUST: si des tables sont ajoutées à la base de données, utiliser l'accroche LoadExtensionSchemaUpdates pour garantir que update.php fonctionne.
- MUST: utiliser la bibliothèque Wikimedia-Rdbms pour tous les accès à la base de données. De la sorte cela évite la plupart des vecteurs d'attaque d'injection de SQL, respecte que les transactions soient correctement effectuées, et que les meilleures pratiques soient suivies pour les performances.
- SHOULD: bien fonctionner dans un environnement distribué (concurrenciel, bases de données multiples, clustering).
- SHOULD: si la persistance est nécessaire, créer un bon SQL (clés primaires, indices si nécessaire) et utiliser un mécanisme de mise en cache si nécessaire.
- SHOULD: ne jamais ajouter de champs aux tables du noyau ni les altérer d'aucune manière. Pour conserver les données associées aux tables du noyau, créer une table spécifique à l'extension et faire référence à la clé principale de la table de base. Cela facilite la suppression d'une extension.
- SHOULD: doit utiliser le schéma abstrait .
- OPTIONAL: si l'extension laisse des données et accepte la désinstallation, fournir un script de maintenance qui automatise l'opération (par exemple supprimer les tables, effacer les entrées du journal associées ainsi que les propriétés de page).
Conventions de codage
D'une manière générale suivre les conventions de codage MediaWiki pour PHP , JavaScript , CSS , et tout autre langage utilisé pour lequel elles sont définies.
- SHOULD: exécuter MediaWiki-CodeSniffer pour adopter les conventions PHP (voir les points d'entrée de l'intégration continue ).
- SHOULD: exécuter l'analyse statique de Phan pour PHP (voir les points d'entrée de l'intégration continue ).
- SHOULD: exécuter ESLint pour les conventions JavaScript et l'analyse statique (voir les points d'entrée de l'intégration continue ).
- SHOULD: exécuter Stylelint pour les conventions CSS (voir les points d'entrée de l'intégration continue ).
- SHOULD: éviter de mettre tout le code à l'intérieur d'une seule et longue fonction (particulièrement vrai en JavaScript).
- OPTIONAL: utiliser les commentaires dans le code généralement pour justifier l'existence de ce code, et non pour dire ce qu'il fait. Dans les longs blocs de code, ajouter des commentaires indiquant ce que chaque paragraphe fait est bon pour une analyse facile, mais en général, les commentaires doivent se concentrer sur les questions qui ne peuvent pas être répondues en lisant simplement le code.
Tests
- SHOULD: Fournir et exécuter les tests PHPUnit et QUnit .
- OPTIONAL: Séparer les tests unitaires des tests d'intégration (voir Phab:T87781).
- SHOULD: Si vous utilisez les fonctions d'analyse syntaxique ou les balises, fournissez et exécutez les tests d'analyse syntaxique .
- OPTIONAL: Fournir et exécuter les tests du navigateur .
- OPTIONAL: Tester des langues qui s'écrivent de droite à gauche pour vérifier le right-to-left (RTL) ! (comment vérifier ?).
- OPTIONAL: Tester la traduction des messages ! (comment vérifier ?).
Langue
Différents aspects du support des langues sont également connus sous le nom de Internationalisation (L10n), d'internationalisation (i18n), de multilingualisation ou encore de mondialisation. Dans l'ensemble, votre extension doit être entièrement utilisable et compatible avec les langues différentes de l'anglais et celles qui ne s'écrivent pas de gauche à droite.
- MUST: utiliser les fonctions Internationalisation appropriées (wfMessage ), et ne pas utiliser de chaînes non traductibles dans le code.
- MUST: utiliser les systèmes standard de traduction dans MediaWiki.
- MUST: utiliser un préfixe nommé, clair et unique, après l'extension pour tous les messages d'interface.
- MUST: soumettre régulièrement les messages à, et fusionner les traductions mises à jour de, Translatewiki.net . Pour les extensions hébergées dans Wikimedia Gerrit, les personnes de translatewiki.net feront généralement proactivement cela pour vous. Ils démarrent un processus automatique qui s'abonne aux nouveaux messages de votre extension, et exportent et fusionnent automatiquement les traductions mises à jour dans votre répertoire une fois par jour. Si après une semaine, rien n'est changé, contacter les équipes de la TWN.
- MUST: ajouter la documentation des messages de
qqq.json
pour tous les messages qui existent dansen.json
- SHOULD: passer lint sur les fichiers de messages dans l'intégration continue en utilisant banana-checker.
- SHOULD: échapper les paramètres des messages traduits le plus pès possible de la sortie. documenter si les fonctions utilisent ou acceptent le wikicode avec du HTML.
- OPTIONAL: si une extension utilise des termes particuliers, écrire un glossaire de ces termes et le connecter à partir de la documentation du message. Exemple : Glossaire.
Accessibilité
Se référer au Guide d'accessibilité pour les développeurs . Noter que cela n'est pas encore intégré dans les règles et en ce qui concerne les meilleures pratiques pour les extensions cela peut être considéré comme facultatif, les discussions sont en attente.
Sécurité
Voir aussi Sécurité pour les développeurs .
- MUST: les bombardements devraient échapper aux arguments.
- MUST: toutes les actions d'écriture doivent être protégées contre Forge des requêtes inter-sites (CSRF).
- MUST: assurez-vous que les problèmes liés à la confidentialité (vérification de l'utilisateur, révision et suppression du journal, et suppression) sont aussi couverts lors de la refactorisation ou de la rédaction de nouveau code.
- SHOULD: utiliser le système des jetons CSRF standard de MediaWiki.
- SHOULD: ne pas modifier le HTML après qu'il ait été purifié (le modèle commun est l'utilisation d'expressions régulières, mais c'est mauvais).
- SHOULD: ne charger aucune ressource venant de domaines externes. Cela est aussi nécessaire pour la confidentialité et améliore les performances.
- SHOULD: discuter d'abord avec la communauté, de la création de nouveaux droits utilisateur ou de groupes d'utilisateurs. L'ajout de droits utilisateur est facile dans le code mais doit être soigneusement examiné en ce qui concerne celui qui peut accorder ces droits et à qui ces droits iront par défaut.
Ne pas réinventer ni abuser MediaWiki
Comme principe général, ne pas réimplémenter ni ajouter les fonctionnalités déjà fournies dans le noyau MediaWiki.
- MUST: utiliser les conteneurs pour les éléments tels que WebRequest avec
$_GET
, etc. - MUST: utiliser les accroches là où c'est possible plutôt que des contournements ou d'autres manières de modifier, d'injecter ou d'étendre la fonctionnalité.
- MUST utiliser les méthodes de purification de MediaWiki par exemple celles des classes Html et Sanitizer.
- MUST: ne pas désactiver le cache de l'analyseur syntaxique sauf s'il y une bonne raison.
- MUST: utiliser Composer pour la gestion des bibliothèques PHP tierces.
- SHOULD: ne pas réinventer la roue. Préférer les bibliothèques stables et régulièrement maintenues quand elles existent.
- SHOULD: ne pas désactiver OutputPage . (T140664)
- SHOULD: s'il existe une abstraction (comme Manuel:ContentHandler ), utilisez-la plutôt que les accroches.
- SHOULD: ne pas chercher la complication – utiliser les fonctionnalités standard telles que les tests de extension.json ou le matériel de détection automatique de PHPUnit.
- SHOULD: utiliser la configuration globale de MediaWiki comme le mode en lecture seule.
Hors catégorie
- Savoir quand utiliser les méthodes ParserOutput avec les méthodes similaires sur OutputPage.
Meta
La première ébauche de cette page a été faite durant le Hackathon Wikimania 2017.
Voir aussi
- API:Client code/Règles d'or
- Technical Collaboration Guidance
- w:User:Risker/Risker's checklist for content-creation extensions
- Best practices for using MediaWiki
- phab:T172845 - « Qu'est-ce qui fait qu'une extension MediaWiki est d'une grande qualité ? » – session de hackathon