Manuel:Architecture de MediaWiki

This page is a translated version of the page Manual:MediaWiki architecture and the translation is 80% complete.
Ce document résulte du projet MediaWiki architecture document dont le contenu a été développé pour être inclus dans le livre Architecture des applications à source ouvert. Le chapître du livre comprend une section donnant un aperçu historique correspondant à l'historique de MediaWiki, et cette page wiki a été modifiée plusieurs fois depuis que le chapitre a été publié en 2012.

Depuis le début, MediaWiki a été développé spécifiquement pour être le logiciel de Wikipedia. Les développeurs ont travaillé pour faciliter la réutilisation par des utilisateurs tiers, mais l'influence de Wikipedia et les biais ont formaté l'architecture de MediaWiki tout au long de son histoire.

Wikipedia figure parmi les dix sites web les plus populaires du monde, obtenant actuellement environ 400 millions de visiteurs uniques par mois. Avec plus de 100 000 vues par seconde. Wikipedia ne prend pas en charge la publicité commerciale; il est entièrement géré par une organisation non commerciale, la Fondation Wikimedia qui reçoit des donations en tant que source principale du modèle de fonds. Cela signifie que MediaWiki ne doit pas simplement fournir un super site web mais aussi le faire avec un budget restreint. Pour rester compatible avec ces demandes, MediaWiki doit rester compétitif avec les performance, la mise en cache et l'optimisation. Les fonctionnalités coûteuses qui ne peuvent être activées sur Wikipedia sont soit annulées ou désactivées à l'aide des variables de configuration; il y a toujours un compromis entre la performance et le nombre de fonctionnalités.

L'influence de Wikipedia sur l'architecture de MediaWiki ne se limite pas à la performance. A l'opposé des CMS génériques, MediaWiki a été écrit à l'origine dans un but bien précis : prendre en charge une communauté qui crée et maintient la connaissance libre et réutilisable sur une platforme libre. Cela signifie par exemple que MediaWiki ne comprend pas les fonctionnalités régulières que l'on trouve dans les CMS d'entreprise (comme la publication facile des flux de travail ou les ACLs), mais offre une variété d'outils pour gérer les pourriels et le vandalisme.

Ainsi, depuis le début les besoins et les actions de la communauté en constante évolution des contributeurs de Wikipedia a influencé le développement de MediaWiki, et réciproquement. L'architecture de MediaWiki a été dirigée plusieurs fois par les initiatives démarrées ou demandées par la communauté, telles que la création de Wikimedia Commons, ou la fonctionnalité des versions balisées (Flagged Revisions). Les développeurs ont fait des modifications majeures, comme le préprocesseur MediaWiki 1.12, car la façon dont MediaWiki a été utilisé par les wikipediens l'a rendu nécessaire.

MediaWiki a également gagné une solide base d'utilisateurs externes en devenant un logiciel libre depuis ses débuts. Les utilisateurs tiers savent bien que tant qu'un site web qui possède un profil majeur tel que Wikipedia, utilise MediaWiki, le logiciel sera maintenu et amélioré. MediaWiki était à l'origine orienté site Wikimedia, mais des efforts ont été faits pour le rendre plus générique et mieux accomoder les besoins de ces utilisateurs tiers. Par exemple, MediaWiki est fourni avec un installateur basé sur le web, rendant ainsi le processus d'installation beaucoup moins pénible que si tout devait être fait en mode ligne de commande et que le logiciel contenait les chemins codés en dur pour Wikipedia.

MediaWiki est, et reste encore, le logiciel de Wikipedia; cela se voit au long de son histoire et dans son architecture.

Base de code et pratiques MediaWiki

Architecture générale
couche utilisateur navigateur web
couche réseau Varnish
Serveur web Apache
couche logique Scripts PHP de MediaWiki
PHP
couche de données Système de fichiers Base de données MySQL (programme et contenu) Système de mise en cache

PHP

PHP a été choisi comme environnement pour la Phase II du logiciel de Wikipedia en 2001; MediaWiki n'a cessé de croître depuis organiquement et reste toujours en évolution. La plupart des développeurs MediaWiki sont bénévoles et contribuent sur leur temps libre; ils furent très peu nombreux au début. Certaines décisions ou omissions dans l'architecture du logiciel peuvent apparaître mauvaises à postériori, mais il est difficile de reprocher aux concepteurs de ne pas avoir implémenté certaines abstractions qui apparaîssent aujourd'hui comme critiques, lorsque la base de code initiale était si petite et que le temps nécessaire à la développer était si court.

Par exemple, MediaWiki utilise des noms de classes non préfixés, ce qui peut poser problème lorsque le noyau PHP et les développeurs PECL ajoutent de nouvelles classes. Comme conséquence, la classe Namespace de MediaWiki doit être renommée en MWNamespace pour être compatible avec PHP 5.3. L'utilisation d'une manière cohérente d'un préfixe pour toutes les classes (comme "MW") aurait facilité l'inclusion de MediaWiki dans une autre application ou une bibliothèque.

Le fait de se baser sur PHP n'a pas été probablement le meilleur choix au niveau performance, car ce langage n'a pas bénéficié des améliorations que certains autres langages dynamiques auraient pu recevoir. L'utilisation de Java aurait certes été plus favorable pour les performances et pour l'exécution simplifiée du déploiement pour les tâches de maintenance du serveur. D'un autre côte PHP est très populaire ce qui facilite le recrutement de nouveaux développeurs.

Même si MediaWiki contient encore du code ancien un peu sale, la plus grande partie des améliorations a été faite au fil des années, et les nouveaux éléments d'architecture ont été introduits dans MediaWiki tout au long de son histoire. Cela comprend les classes Parser, SpecialPage, et Database, la classe Image et la hiérarchie de la classe FileRepo, ResourceLoader, et la hiérarchie de Action. MediaWiki a débuté sans aucun de ces éléments, mais chacun d'eux tous prend en charge les fonctionnalités qui ont existé depuis le commencement. Beaucoup de développeurs sont intéressés principalement par le développement des fonctionnalités et l'architecture est souvent laissée de côté, puis reprise ultérieurement quand le coût du travail dans une architecture qui n'est plus adaptée se fait sentir.

Sécurité

Parce que MediaWiki est la plateforme pour les sites ayant un profil de grande valeur tels que Wikipedia, les développeurs du noyau et les relecteurs de code on renforcé les règles strictes de sécurité. Pour qu'il soit plus facile d'écrire du code sécurisé, MediaWiki fournit au développeurs des sur-couches (wrappers) autour de la sortie HTML et des requêtes à la base de données, pour gérer l'échappement. Pour nettoyer l'entrée utilisateur, on utilise la classe WebRequest, qui analyse les données passées dans l'URL ou un formulaire via POST. Il supprime les barres obliques des guillemets magiques, enlève les caractères d'entrée non autorisés et normalise les séquences Unicode. Nous évitons le Cross-site request forgery (CSRF) en utilisant les jetons, et le cross-site scripting (XSS) en validant les entrées et en échappant les sorties, habituellement avec la fonction PHP htmlspecialchars(). MediaWiki fournit également (et utilise) un nettoyeur HTML avec la classe Sanitizer, et des fonctions de la base de données qui empêchent l'injection de SQL.

Configuration

MediaWiki offre des centaines de paramètres de configuration stockés dans des variables PHP globales. Leur valeur par défaut est définie dans DefaultSettings.php, mais l'administrateur système peut réécraser ces valeurs en mettant à jour LocalSettings.php.

MediaWiki se basait à l'origine sur les variables globales, à la fois pour la configuration et pour le traitement des contextes. Les variables globales causent de sérieux problèmes de sécurité avec la fonction PHP register_globals (dont MediaWiki n'a pas besoin depuis la version 1.2). Ce système limite également les abstractions potentielles pour la configuration et rend le processus de démarrage plus difficile à optimiser. De plus, l'espace de noms de configuration est partagé avec les variables utilisées pour l'enregistrement et le contexte des objets, ce qui peut présenter des conflits potentiels. D'un point de vue utilisateur, les variables de configuration globales faisaient que MediaWiki semblait difficile à configurer et à maintenir. Le développement de MediaWiki a reposé sur le déplacement progressif des contextes à partir des variables globales vers les objets. En enregistrant le contexte des traitements dans les variables des membres des objets, nous permettons à ces objets d'être réutilisés d'une manière beaucoup plus souple.

Stockage de la base de données et du texte

 
Schéma de la base de données du noyau MediaWiki

MediaWiki utilise un serveur de base de données relationnelle depuis le logiciel de la Phase II. Le système de base de données (DBMS) par défaut (et le mieux pris en charge) de MediaWiki est MySQL, utilisé sur tous les sites Wikimedia, mais d'autres types de DBMS (comme PostgreSQL, Oracle, ou SQLite) ont leurs implémentations prises en charge par la communauté. Un administrateur système peut choisir son DBMS lors de l'installation de MediaWiki, et MediaWiki fournit à la fois un niveau d'abstraction de la base de données et un niveau d'abstraction pour les requêtes qui simplifient l'accès à la base de données pour les développeurs.

L'organisation actuelle contient des dizaines de tables. La plupart concernent le contenu du wiki (comme les tables page, revision, category, et recentchanges). Les autres tables contiennent les données relatives aux utilisateurs (user, user_groups), aux fichiers de médias (image, filearchive), à gestion du cache (objectcache, l10n_cache, querycache) et aux outils internes (job pour la file d'attente des tâches), entre autre. Les tables d'index et de résumé sont très souvent utilisées dans MediaWiki, depuis que les requêtes SQL qui balaient un très grand nombre de lignes peuvent être très coûteuses, particulièrement sur les sites Wikimedia. Il n'est pas recommandé habituellement de faire des requêtes qui ne sont pas indexées.

La base de données a subit des dizaines de modifications du schéma au fil des années, la plus importante ayant été le découplage du stockage du texte et la gestion du suivi des versions dans MediaWiki 1.5.

 
Principales tables de contenu de MediaWiki 1.4 et 1.5.

Dans le modèle 1.4, le contenu était stocké dans deux tables importantes, cur (contenant le texte et les métadonnées de la version actuelle de la page) et old (contenant les versions antérieures); les pages supprimées était gardées dans archive. Lorsqu'une modification était faite, la version antépénultième était recopiée dans la table old, et la nouvelle modification était sauvegardée dans cur. Lorsqu'une page était renommée,le titre de la page devait être mis à jour dans les métadonnées de toutes les versions de old, ce qui pouvait prendre un certain temps. Lorsqu'une page était supprimée, ses entrées dans les deux tables cur et old devaient être copiées dans la table archive avant d'être supprimées; ce qui impliquait de recopier le texte de toutes les versions, qui pouvait être conséquent et prendre du temps.

Dans le modèle 1.5, les métadonnées des versions et le texte des versions furent séparés : les tables cur et old ont été remplacées par page (métadonnées des pages), revision (métadonnées de toutes les versions, anciennes ou actuelles) et text (texte de toutes les versions, anciennes, actuelles ou supprimées). Maintenant, quand une modification est réalisée, les métadonnées des versions n'ont plus besoin d'être recopiées dans les tables : l'ajout d'une nouvelle entrée et la mise à jour du pointeur page_latest suffisent. De même, les métadonnées de la version n'incluent plus le titre de la page mais seulement son ID : cela supprime le besoin de renommer toutes les versions lorsqu'une page change de nom.

La table revision stocke les métadonnées de chaque version, et non pas le texte de leur contenu; à la place, elles contiennent l'ID du texte qui pointe vers la table text, qui contient le texte actuel. Lorsqu'une page est supprimée, le texte de chacune des versions de la page reste en place et n'a pas besoin d'être déplacé vers une autre table. La table text est composée de correspondances entre les IDs et les blobs de texte; un champ d'indicateurs renseigne si le blob du texte est compressé (gzip) afin d'économiser de l'espace, ou si le blob du texte est seulement un pointeur vers un espace de stockage textuel externe. Les sites Wikimedia utilisent une grappe de stockage MySQL externe pour la sauvegarde, avec des blobs de quelques dizaines de versions. La première version du blob est stockée entièrement, et les versions suivantes de la même page sont stockées comme sous forme de différences (diffs) relatives à la version précédente; les blobs sont ensuite compressés avec gzip. Les versions sont groupées par page; elles ont tendance à se ressembler, donc les diffs restent relativement petits et gzip fonctionne très bien. Le taux de compression des sites Wikimedia approche les 98 %.

MediaWiki inclus également la gestion du partage de charge (load balancing), ajoutée dès 2004 dans MediaWiki 1.2 (lorsque Wikipedia a reçu un second serveur — ce fut alors un très gros défi). Le partage de charge (décision du code PHP de MediaWiki pour déterminer à quel serveur il faut se connecter) est dorénavant une partie critique de l'infrastructure de Wikimedia, ce qui explique son influence sur certaines décisions de l'algorithme dans le code. L'administrateur système peut spécifier dans la configuration de MediaWiki qu'il y a un serveur de base de données maître, et n'importe quel nombre de serveurs de base de données esclave; vous pouvez utiliser un système de pondération de chaque serveur pour profiler la répartition de la charge. Toutes les écritures sont envoyées au maître mais les lectures sont réparties sur les serveurs en fonction de leur pondération par le système de gestion de la charge. Il garde trace également du délai de réplication de chaque esclave. Si le temps de latence pour la réplication sur un esclave dépasse les 30 secondes, celui-ci ne recevra plus de demandes de lecture pour les traiter; si tous les esclaves se retrouvent dans cette situation alors MediaWiki passe automatiquement en mode lecture seule.

Le garant de la chronologie dans MediaWiki s'assure que le temps de réplication ne fait jamais qu'un utilisateur puisse voir une page sur laquelle il a demandé une action et où cette dernière n'aurait pas encore été réalisée. Ceci est fait en stockant la position du master dans la session utilisateur si la requête qu'il a faite comprenait une demande d'écriture. La prochaîne fois que l'utilisateur fait une demande de lecture, le partage de charge relit cette position à partir des données session, et essaie de sélectionner un esclave qui a atteint cette position de réplication pour lui distribuer la demande. Si aucun n'est trouvé, on attend jusqu'à ce que l'un d'entre-eux se libère. Il peut sembler aux autres utilisateurs que l'action n'est pas encore exécutée mais la chronologie reste cohérente pour chaque utilisateur.

Demandes, mise en cache et livraison

Flux du travail de l’exécution d’une requête web

index.phpest le point d'accès principal de MediaWiki, et gère la plupart des requêtes traitées par les serveurs de l'application (c'est à dire les requêtes non satisfaites par l'infrastructure de la gestion du cache; voir ci-dessous). Le code exécuté à partir de index.php réalise les contrôles de sécurité, charge les paramètres de configuration par défaut de includes/DefaultSettings.php, devine la configuration avec includes/Setup.php, et applique les paramètres du site contenus dans LocalSettings.php. Ensuite il instancie un objet MediaWiki object ($mediawiki), et crée un objet Title ($wgTitle) qui dépend du titre et des paramètres de l'action contenue dans les paramètres de la requête.

index.php peut prendre une variété de paramètres d'action dans l'URL de la requête; l'action par défaut est view, qui affiche la vue habituelle du contenu d'un article. Par exemple la requête https://en.wikipedia.org/w/index.php?title=Apple&action=view affiche le contenu de l'article « Apple » de la Wikipedia anglophone.[1]. Les autres actions fréquentes incluent edit (ouvrir un article pour le modifier), submit (afficher ou enregistrer un article), history (afficher l'historique d'un article) et watch (ajouter un article à la liste de suivi de l'utilisateur). Les actions administratives comprennent delete (pour supprimer un article) et protect (pour empêcher de modifier un article).

MediaWiki::performRequest() est ensuite appelé pour gérer la majeure partie de la requête de l'URL. Il vérifie les mauvais titres, lit les restrictions, les redirections locales entre wikis, les boucles de redirection, et détermine si la requête concerne une page normale ou une page spéciale.

Les demandes de pages usuelles sont gérées pour MediaWiki::initializeArticle(), pour créer des objets Article pour la page ($wgArticle), puis pour MediaWiki::performAction() qui gère les actions standard. Un fois l'action terminée, MediaWiki::doPostOutputShutdown() finalise la requête en validant les transactions dans la base de données, en générant le HTML, et en activant les mises à jour différées via la file d'attente des travaux. MediaWiki::restInPeace() valide (commit) les mises à jour différées et ferme la tâche simplement.

Si la page demandée est une page de type Special: (c'est à dire qui n'est pas une page de contenu wiki normale, mais une page liée à un logiciel particulier tel que Statistics), SpecialPageFactory::executePath est appelé à la place de initializeArticle(); puis le script PHP correspondant est appelé. Les pages spéciales peuvent faire toutes sortes de manipulations magiques, et chacune d'elles a un rôle particulier, habituellement indépendant de tout article et de son contenu. Les pages spéciales fournissent différentes sortes de rapports (les modifications récentes, les journaux, les pages sans catégorie) ainsi que les outils d'administration du wiki (le blocage des utilisateurs, la modification des droits utilisateur), entre autres. Le flux de travail de leur exécution dépend de la fonction réalisée.

Plusieurs fonctions contiennent du code de profilage, ce qui permet de suivre le flux de travail de leur exécution à des fins de débogage, dans le cas où le profilage est activé. Le profilage est réalisé en appelant les fonctions wfProfileIn et wfProfileOut pour respectivement démarrer et arrêter le profilage d'une fonction à tracer; ces deux fonctions utilisent le nom de cette dernière, comme paramètre. Sur les sites Wikimedia, le profilage est réalisé sur un pourcentage de l'ensemble des requêtes afin de préserver les performances. MediaWiki envoie les paquets UDP à un serveur central qui les collecte et produit les données de profilage.

Assemblage d’une page non mise en cache

Lors de l'affichage d'une page, le code HTML peut être puisé directement du cache (voir ci-dessous); s'il ne s'y trouve pas on expanse d'abord les modèles, puis les fonctions d'analyse syntaxique et les variables. Ceci crée le wikicode expansé, qui est un résultat intermédiaire pouvant être vu avec Special:ExpandTemplates, et qui dépend de :

  • le wikicode;
  • les modèles auxquels il est fait référence directement ou indirectement;
  • les fonctions d'analyse syntaxique auxquelles il est fait référence directement ou indirectement;
  • les valeurs des variables auxquelles il est fait référence directement ou indirectement.

Puis ce wikicode expansé est converti en code HTML ; il est envoyé vers l'utilisateur, et contient des références au CSS, au JavaScript, et aux fichiers d'images. L'utilisateur peut voir ce résultat intermédiaire en appliquant l'option Code source de la page du navigateur. Le code HTML d'une page donnée est fonction des éléments suivants :

  • le wikicode expansé;
  • le mode : la lecture ou bien la modification (voir ci-dessous);
  • l'existence de pages liées en interne (affichées ou par un lien de modification)
  • l'habillage et les autres préférences utilisateur;
  • le nom d'utilisateur;
  • l'état de l'utilisateur (davantage de liens s'il s'agit d'un administrateur système, etc.);
  • l'espace de noms (définit le lien vers la page de discussion, ou dans le cas d'une page de discussion, la page qui lui est associée);
  • l'indication si la page est suivie par l'utilisateur (donne le lien de suivi ou de non-suivi);
  • indication si la page de discussion de l'utilisateur a été modifiée récemment (fournit un message).

Enfin le navigateur réalise le rendu du HTML en utilisant les fichiers référencés. Le résultat vu par l'utilisateur sur l'écran dépend :

  • du code HTML
  • des fichiers référencés par le code HTML, tels que les images incluses, les fichiers CSS du côté serveur et les fichiers JavaScript
  • du navigateur et de ses paramètres, y compris éventuellement un fichier CSS local, et la résolution de l'écran.

Si JavaScript répond à un événement tel qu'un clic de souris, la page affichée dépend également de ces événements. Ceci s'applique par exemple aux tables que vous pouvez trier.

Lorsque l'utilisateur sélectionne l'onglet de Modifier, le wikicode lui-même lui est envoyé, soit pour toute la page, soit pour une section donnée uniquement. Lorsque l'utilisateur appuie sur Show preview, sa nouvelle version du wikicode est envoyée au serveur, qui renvoie la nouvelle version du code Html, qui est rendu à nouveau et affiché au-dessus ou en-dessous de la nouvelle version du wikicode (renvoyée également par le serveur). Après avoir éventuellement fait plusieurs changements et aperçus, l'utilisateur appuie sur « Sauvegarder la page » et envoie sa version finale sur le serveur qui à son tour enregistre les modifications et retourne à nouveau le Html de la nouvelle version. Dans certains cas une conversion automatique du wikicode est appliquée également à cette étape.

Mise en cache

MediaWiki lui-même a été amélioré au niveau performance car il a un rôle central dans les sites Wikimedia, mais il fait également partie d'un écosystème plus vaste qui a influencé son architecture. L'infrastructure du système de cache de Wikimedia a imposé les limites de MediaWiki; les développeurs ont travaillé sur les problèmes, non pas en essayant de formater l'infrastructure du cache optimisée extensivement, mais en essayant plutôt de rendre MediaWiki plus flexible, de sorte qu'il puisse s'exécuter dans cette infrastructure sans en compromettre la performance ni les besoins du cache.

Sur les sites Wikimedia, la plupart des requêtes sont traitées par des proxy de cache inverse (Squids), et ne sont même jamais des serveurs d'application MediaWiki. Les squids contiennent les versions statiques des pages entières générées et servies pour des accès en lecture simple aux utilisateurs qui ne sont pas connectés au site. MediaWiki prend en charge nativement Squid et Varnish, et s'intègre à cette couche de mise en cache par exemple en leur demandant de supprimer une page du cache quand elle a été modifiée. Pour les utilisateurs connectés et les autres requêtes qui ne peuvent pas être traitées par Squids, celui-ci les redirige sur le serveur web (Apache).

Le second niveau de l'utilisation du cache apparaît quand MediaWiki génère le rendu et assemble la page à partir d'objets divers dont chacun peut déjà se trouver dans le cache afin de réduire le nombre d'appels à venir. De tels objets incluent l'interface de la page (barre latérale, menus, texte de l'interface utilisateur) et le propre contenu, analysé à partir du wikicode. L'objet cache en mémoire est présent dans MediaWiki depuis la première version 1.1 (2003), et il est particulièrement important pour éviter d'avoir à réanalyser syntaxiquement de grandes pages complexes.

Les données de la session de connexion peuvent également être stockées en mémoire cache, ce qui permet aux sessions de fonctionner de manière transparente sur plusieurs serveurs web de l'interface utilisateur dans une configuration avec partage de charge (Wikimedia dépend fortement de l'équilibrage de la charge et utilise LVS avec PyBal).

Depuis la version 1.16, MediaWiki utilise un cache d'objets dédié pour le texte traduit de l'interface utilisateur; celui-ci a été ajouté après avoir remarqué qu'une grande partie des objets mis en cache dans memcached était constituée des messages traduits de l'interface utilisateur dans la langue de celui-ci. Le système est basé sur la récupération rapide des messages individuels à partir de bases de données constantes (CDB), c'est à dire de fichiers à l'aide de paires clé-valeur. Les CDB minimisent la surcharge de mémoire et le temps de démarrage dans le cas typique; ils servent aussi pour le cache interwiki.

Le dernier niveau de cache est constitué du cache d' opcode PHP généralement activé pour accélérer les applications PHP. La compilation peut être un processus qui prend du temps; pour éviter de compiler les scripts en opcode à chaque fois qu'ils sont appelés, un accélérateur PHP peut être utilisé pour stocker le opcode compilé et l'exécuter directement sans compilation. MediaWiki va fonctionner simplement avec beaucoup d'accélérateurs tels que APC, l'accélérateur PHP...

En raison de son biais pour Wikimedia, MediaWiki est optimisé pour cette infrastructure de mise en cache complète, multi-couches et distribuée. Néanmoins, il prend également en charge de manière native des configurations alternatives pour les sites plus petits. Par exemple, il offre un système de mise en cache de fichiers simplifié optionnel qui stocke la sortie des pages entièrement rendues, comme le fait Squid. En outre, la couche de mise en cache abstraite d'objets MediaWiki lui permet de stocker les objets du cache dans plusieurs endroits, y compris le système de fichiers, la base de données ou le cache opcode.

ResourceLoader

Tout comme d'autres applications web, l'interface de MediaWiki est devenue plus interactive et plus dynamique au fil des années, grâce particulièrement à l'utilisation de JavaScript. Les efforts d'utilisabilité initiés en 2008, ainsi que la gestion avancée des médias (par exemple, l'édition en ligne de fichiers vidéo), appelé pour des améliorations spécifiques des performances de l'interface utilisateur.

Pour optimiser la distribution des ressources JavaScript et CSS, le module ResourceLoader a été développé. Démarré en 2009, il a été finalisé en 2011 et est devenu une fonctionnalité du noyau MediaWiki depuis la version 1.17. Le ResourceLoader charge les parties JavaScript et CSS à la demande, ce qui réduit la charge et le temps de l'analyse syntaxiques des fonctionnalités non utilisées, par exemple dans les anciens navigateurs. Il minimise également le code, regroupe les ressources pour économiser les requêtes et peut inclure des images et des URIs de données.

Langues

Page principale : Manual:Language

Contexte et justification

Une partie centrale de la contribution effective et de la diffusion de la connaissance libre à tous est de la fournir dans le plus grand nombre possible de langues. Wikipedia est disponible dans plus de 280 langues et les articles encyclopédiques en anglais représentent moins de 20 % de l'ensemble des articles. Because Wikipedia and its sister sites exist in so many languages, it is important not only to provide the content in the readers' native language, but also to provide a localised interface, and effective input and conversion tools, so that participants can contribute content.

Pour cette raison, la localisation et l'internationalisation (l10n et i18n) sont un composant central de MediaWiki. Le système i18n est omniprésent et affecte de nombreuses parties du logiciel; c'est aussi l'un des plus flexibles et les plus riches en fonctionnalités. La facilité du traducteur est habituellement préférée à celle du développeur, mais on s'accorde que le coût soit acceptable.

MediaWiki est actuellement traduit dans plus de 350 langues, y compris les non-latines et celles qui s'écrivent de la droite vers la gauche (right-to-left - RTL), avec différents niveaux de complétion. L'interface et le contenu peuvent être dans des langues différentes et mixer des directionnalités différentes.

Langue du contenu

MediaWiki utilisait initialement un encodage fonction de la langue, ce qui a produit un grand nombre de problèmes; par exemple, les écritures étrangères ne pouvaient pas être utilisées dans le titre des pages. UTF-8 a été choisi à la place. La prise en charge des ensembles de caractères différents de UTF-8 a été abandonnée en 2005, en même temps que la modification générale du schéma de la base de données dans MediaWiki 1.5 ; le contenu doit dorénavant être encodé en UTF-8.

Les caractères non disponibles sur le clavier de l'éditeur peuvent être personnalisés et insérés via le Edittools MediaWiki, qui est un message d'interface apparaîssant sous la fenêtre de modification; sa version JavaScript insère automatiquement le caractère cliqué dans la fenêtre d'édition. L'extension WikiEditor pour MediaWiki, développée dans le cadre d'un effort d'utilisabilité, fusionne les caractères spéciaux avec la barre d'outils de modification. Une autre extension, appelée UniversalLanguageSelector , fournit des méthodes d'entrée supplémentaires et des fonctionnalités de correspondance des clés pour les caractères non ASCII.

Les améliorations récentes et à venir incluent une meilleure prise en charge du texte RTL s'écrivant de droite à gauche, du texte bidirectionnel (LTR et RTL c'est à dire dans les deux sens, sur la même page) et UniversalLanguageSelector .

Langue de l’interface

Les messages d'interface ont été stockés dans des tableaux PHP de paires clé valeur depuis que le logiciel Phase III est créé. Chaque message est identifié par une clé unique, et reçoit des valeurs différentes en fonction de la langue. Les clés sont définies par les développeurs encouragés à utiliser des préfixes pour les extensions; par exemple les clés des messages pour l'extension UploadWizard commenceront avec mwe-upwiz-, où mwe représente MediaWiki extension.

Les messages MediaWiki peuvent contenir des paramètres fournis par le logiciel ce qui influencera souvent la grammaire du message. Afin de prendre en charge pratiquement n'importe quelle langue possible, le système de traduction de MediaWiki a été amélioré et complexifié au fil du temps pour s'adapter à leurs caractéristiques spécifiques et à leurs exceptions, souvent considérées comme des étranges par les anglophones.

Par exemple, les adjectifs sont des mots invariables en anglais, mais des langues telles que le français il faut que l'adjective s'accorde avec le nom, en genre et en nombre. Si le profil de l'utilisateur comporte des déclarations sur le genre, le sélecteur {{GENDER:}} peut être utilisé dans les messages d'interface pour les récupérer si nécessaire (plus d'informations...). Other switches include {{PLURAL:}}, for "simple" plurals and languages like Arabic with dual, trial or paucal numbers, and {{GRAMMAR:}}, providing grammatical transformation functions for languages like Finnish whose grammatical cases cause alterations or inflections.

La distinction du genre peut aussi être utilisée pour le nom des espaces de noms utilisateur qui dépendent du genre, de sorte que le titre et l'URL de la page se rapportent correctement à l'utilisateur. Standard MediaWiki namespaces' gender variants are defined via $namespaceGenderAliases in each language's MessagesXx.php, while $wgExtraGenderNamespaces can be used for wiki-specific namespaces. Depuis r107559, 13 langues utilisent cette fonctionnalité par défaut :

  • Arabic
  • Czech
  • German
  • Lower Sorbian
  • Spanish
  • Galician
  • Hebrew
  • Upper Sorbian
  • Polish
  • Brazilian Portuguese
  • Portuguese
  • Russian
  • Saterland Frisian

Internationaliser les messages

Voir aussi : Help:System message

Localised interface messages for MediaWiki reside in MessagesXx.php files, where Xx is the ISO-639 code of the language (e.g. MessagesFr.php for French); default messages are in English and stored in MessagesEn.php. MediaWiki extensions use a similar system, or host all localised messages in an [Extension-name].i18n.php file. En même temps que les traductions, les fichiers de messages comprennent également des informations qui dépendent de la langue telles que le format des dates.

Les traductions contributrices se faisaient en soumettant des patches PHP pour les fichiers MessagesXx.php. En décembre 2003, MediaWiki 1.1 a introduit les messages de base de données, un sous-ensemble de pages wiki dans l'espace de noms MediaWiki contenant les messages d'interface. Le contenu de la MediaWiki:[clé de message] de la page du wiki est le texte du message, et il remplace sa valeur dans le fichier PHP. Les versions traduites du message sont au MediaWiki:[code de langue]/[$2], e.g. MediaWiki:Rollbacklink/de.

Cette fonctionnalité a permis aux utilisateurs de traduire (et de personnaliser) les messages d'interface localement sur leur wiki, mais le processus ne met pas à jour les fichiers i18n livrés avec MediaWiki. En 2006, Niklas Laxström a créé un site web spécial et fortement piraté de MediaWiki (hébergé maintenant sur translatewiki.net) où les traducteurs peuvent facilement traduire les messages d'interface dans toutes les langues, simplement en éditant une page wiki. Les fichiers MessagesXx.php sont ensuite mis à jour dans le répertoire du code MediaWiki, d'où ils seront automatiquement récupérés par tout wiki. Sur les sites Wikimedia, les messages de base de données sont maintenant utilisés uniquement pour la personnalisation, et non plus pour la traduction. Les extensions MediaWiki et certains programmes associés tels que les robots, sont aussi traduits sur translatewiki.net.

Pour aider les traducteurs à comprendre le contexte et la signification d'un message d'interface, une bonne pratique dans MediaWiki est de fournir la documentation de chaque message. Cette documentation est stockée dans un fichier de message spécial, avec le code de langue qqq qui ne correspond pas à une langue réelle. La documentation de chaque message est ensuite affichée dans l'interface de traduction sur translatewiki.net. Another helpful tool is the qqx language code: when used with the &uselang parameter to display a wiki page (e.g. en.wikipedia.org/wiki/Special:RecentChanges?uselang=qqx), MediaWiki will display the message keys instead of their values in the user interface; this is very useful to identify which message to translate or change.

 
Graphe du repli des langues

Les utilisateurs enregistrés peuvent définir dans leurs préférences la langue de leur interface; cela se substitue à la langue par défaut de l'interface du site. MediaWiki also supports fallback languages: if a message isn't available in the chosen language, it will be displayed in the closest possible language, and not necessarily in English. Par exemple la langue de repli pour le breton est le français.

Utilisateurs

Users are represented in the code using instances from the User class, which encapsulates all of the user-specific settings (user id, name, rights, password, email address, etc.). Client classes use accessors to access these fields; they do all the work of determining whether the user is logged in, and whether the requested option can be satisfied from cookies or whether a database query is needed. La plupart des paramètres nécessaires pour générer les pages habituelles sont définis dans le cookie pour minimiser l'utilisation de la base de données.

MediaWiki provides a very granular permissions system, with basically a user permission for every possible action. For example, to perform the "Rollback" action (i.e. to "quickly rollback the edits of the last user who edited a particular page"), a user needs the rollback permission, included by default in MediaWiki's sysop user group. But it can also be added to other user groups, or have a dedicated user group only providing this permission (this is the case on the English Wikipedia, with the Rollbackers group). Customisation of user rights is done by editing the $wgGroupPermissions array in LocalSettings.php; for instance, $wgGroupPermissions['user']['movefile'] = true; allows all registered users to rename files. Un utilisateur peut appartenir à plusieurs groupes et bénéficier des droits supérieurs de chacun d'eux.

However, MediaWiki's user permissions system was really designed with Wikipedia in mind, i.e. a site whose content is accessible to all, and only certain actions are restricted to some users. MediaWiki lacks a unified, pervasive permissions concept; it doesn't provide traditional CMS features like restricting read or write access by namespace, category, etc. Seules quelques extensions MediaWiki fournissent de telles fonctionnalités jusqu'à un certain point.

Contenu

Structure du contenu

Le concept d'espaces de noms a été utilisé à l'époque UseModWiki de Wikipedia, où les pages de discussion étaient sous le tire [nom d'article]/Talk. Les espaces de noms ont été officiellement introduits dans le premier script PHP de Magnus Manske. Ils ont été réimplémentés à plusieurs reprises au fil des ans, mais ont conservé la même fonction : séparer différents types de contenu. Ils sont constitués d'un préfixe, séparé du titre de la page par un caractère deux-points (par exemple Talk: ou File: et Template:) ; l'espace de noms de contenu principal n'a pas de préfixe. Les utilisateurs Wikipédia les ont rapidement adoptés, et ils ont fourni à la communauté différents espaces d'évolution. Namespaces have proven to be an important feature of MediaWiki, as they create the necessary preconditions for a wiki's community and set up meta-level discussions, community processes, portals, user profiles, etc.

The default configuration for MediaWiki's main content namespace is to be flat (no subpages), because it's how Wikipedia works, but it is trivial to enable them. They are enabled in other namespaces (e.g. User:, where people can for instance work on draft articles) and display breadcrumbs.

Namespaces separate content by type; within a same namespace, pages can be organised by topic using categories, a pseudo-hierarchical organisation scheme introduced in MediaWiki 1.3.

Traitement du contenu : langage de balisage MediaWiki et analyseur syntaxique

The user-generated content stored by MediaWiki isn't in HTML, but in a markup language specific to MediaWiki, sometimes called "wikitext". It allows users to make formatting changes (e.g. bold, italic using quotes), add links (using square brackets), include templates, insert context-dependent content (like a date or signature), and make an incredible number of other magical things happen.

To display a page, this content needs to be parsed, assembled from all the external or dynamic pieces it calls, and converted to proper HTML. L'analyseur syntaxique est l'une des parties les plus essentielles de MediaWiki, ce qui en contrepartie rend difficile sa modification et son amélioration. Parce que des centaines de millions de pages wiki dans le monde dépendent de l'analyseur syntaxique pour continuer à produire le HTML de la même manière, il doit rester extrêmement stable.

Le langage de balisage n'avait pas été formellement spécifié depuis ses débuts; il a commencé en partant du balisage UseModWiki, puis s'est transformé et a évolué en fonction des besoins. For example, the usage of a ThreadMode format for discussions made Magnus Manske implement the 3 or 4 tildes (~~~~) as a shortcut to sign one's posts in unstructured text. Les tildes ont été choisis parce qu'ils ressemblaient à la signature manuscrite de son père.[2]

In the absence of a formal specification, the MediaWiki markup language has become a complex and idiosyncratic language, basically only compatible with MediaWiki's parser; it can't be represented as a formal grammar using BNF, EBNF or ANTLR syntaxes. The current parser's specification is jokingly referred to as "whatever the parser spits out from wikitext, plus a few hundred test cases".

Plusieurs tentatives sont été faites avec des analyseurs parallèles mis aucune n'est allée aussi loin. In 2004, an experimental tokeniser was written by Jens Frank to parse wikitext, and enabled on Wikipedia; it had to be disabled three days later, because of the poor performance of PHP array memory allocations. Depuis lors, la majeure partie de l'analyse utilise une énorme pile d'expressions régulières ainsi qu'une tonne de fonctions d'aide. The wiki markup, and all the special cases the parser needs to support, have also become considerably more complex, making future attempts even more difficult.

A notable improvement was Tim Starling's preprocessor rewrite in MediaWiki 1.12, whose main motivation was to improve the parsing performance on pages with complex templates. The preprocessor converts wikitext to an XML DOM tree representing parts of the document (template invocations, parser functions, tag hooks, section headings, and a few other structures), but can skip "dead branches" in template expansion, such as unfollowed #switch cases and unused defaults for template arguments. L'analyseur itère ensuite en parcourant la structure DOM et convertit son contenu en HTML.

Recent work on a visual editor for MediaWiki has made it necessary to improve the parsing process (and make it faster), so work has resumed on the parser and intermediate layers between MediaWiki markup and final HTML (see Future, below).

Mots magiques et modèles

MediaWiki offre les Mots magiques qui modifient le comportement général de la page ou qui incluent du contenu dynamique à l'intérieur. They consist of: behaviour switches like __NOTOC__ (to hide the automatic table of content) or __NOINDEX__ (to tell search engines not to index the page); variables like {{CURRENTTIME}} or {{SITENAME}}; and parser functions, i.e. magic words that can take parameters, like {{lc:[string]}} (to output [string] in lowercase). Les constructions comme {{GENDER:}}, {{PLURAL:}} et {{GRAMMAR:}}, utilisées pour traduire l'interface utilisateur, sont des fonctions de l'analyseur.

La manière la plus habituelle d'inclure du contenu venant d'autres pages, dans une page MediaWiki, est d'utiliser des modèles. Templates were really intended to be used to include the same content on different pages, e.g. navigation panels or maintenance banners on Wikipedia articles; having the ability to create partial page layouts and reuse them in thousands of articles with central maintenance made a huge impact on sites like Wikipedia.

However, templates have also been used (and abused) by users for a completely different purpose. MediaWiki 1.3 made it possible for templates to take parameters that change their output; the ability to add a default parameter (introduced in MediaWiki 1.6) enabled the construction of a functional programming language implemented on top of PHP, which was ultimately one of the most costly features in terms of performance.

Tim Starling then developed additional parser functions (the ParserFunctions extension), as a stopgap measure against insane constructs created by Wikipedia users with templates. This set of functions included logical structures like #if and #switch, and other functions like #expr (to evaluate mathematical expressions) and #time (for time formatting).

Soon enough, Wikipedia users started to create even more complex templates using the new functions, which considerably degraded the parsing performance on template-heavy pages. The new preprocessor introduced in MediaWiki 1.12 (a major architectural change) was implemented to partly remedy this issue. Later, MediaWiki developers discussed the possibility of using an actual scripting language to improve performance. Extension:Scribunto a été ajouté en février 2013.

Fichiers multimédia

Les utilisateurs téléversent les fichiers via la page Special:Upload; les administrateurs peuvent configurer les types de fichiers autorisés au téléversement via une liste blanche d'extension. Une fois téléversés, les fichiers sont rangés dans un répertoire du système de fichiers et les vignettes sont mises dans un répertoire dédié thumb.

Because of Wikimedia's educational mission, MediaWiki supports file types that may be uncommon in other web applications or CMSes, like SVG vector images, and multipage PDFs & DjVus. They are rendered as PNG files, and can be thumbnailed and displayed inline, as are more common image files like GIFs, JPGs and PNGs.

Lorsqu'un fichier est téléversé, il lui est attribué une page File: contenant les informations entrées par le téléchargeur; il s'agit d'un texte libre, qui comprend généralement des informations sur les droits d'auteur (auteur, licence) et des éléments décrivant ou classant le contenu du fichier (description, emplacement, date, catégories, etc.). While private wikis may not care much about this information, on media libraries like Wikimedia Commons they are critical to organise the collection and ensure the legality of sharing these files. On a reproché à la plupart de ces métadonnées de ne pas avoir été mises dans une structure interrogeable comme une table de base de données. Cela faciliterait considérablement la recherche, mais aussi l'attribution et la réutilisation par des tiers — par exemple, via l'API.

La plupart des sites Wikimedia permettent également de téléverser localement sur chaque wiki mais la communauté essaie de ranger les fichiers média sous licence libre dans la bibliothèque libre des médias de Wikimedia nommée Wikimedia Commons. Tout site Wikimedia peut afficher un fichier hébergé sur Commons comme si il était hébergé localement. Cette personnalisation évite d'avoir à téléverser un fichier sur chaque wiki afin de pouvoir l'utiliser.

As a consequence, MediaWiki natively supports foreign media repositories, i.e., the ability to access media files hosted on another wiki through its API and the ForeignAPIRepo system. Since version 1.16, any MediaWiki website can easily use files from Wikimedia Commons through the InstantCommons feature. Lorsque l'on utilise un dépôt externe, les vignettes sont stockées localement pour économiser sur la largeur de bande. Cependant, il n'est pas encore possible de téléverser sur un référentiel de médias externe à partir d'un autre wiki.

Personnalisation et extension de MediaWiki

Niveaux

L'architecture de MediaWiki offre différentes façons de personnaliser et d'étendre le logiciel. Cela peut être fait à différents niveaux d'accès :

  • System administrators can install extensions and skins, and configure the wiki's separate helper programs (e.g. for image thumbnailing and TeX rendering) and global settings (see Configuration above).
  • Les opérateurs système (sysops, appelés aussi quelques fois administrateurs) des wikis, , peuvent mettre à jour les gadgets du site, et les paramètres JavaScript et CSS.
  • Any registered user can customise their own experience and interface using their preferences (for existing settings, skins and gadgets) or make their own modifications (using their personal JS and CSS pages). External programs can also communicate with MediaWiki through its machine API, if it's enabled, basically making any feature and data accessible to the user.

JavaScript et CSS

MediaWiki can read and apply site-wide or skin-wide JavaScript and CSS using custom wiki pages; these pages are in the MediaWiki: namespace, and thus can only be edited by sysops; for example, JavaScript modifications from MediaWiki:Common.js apply to all skins, CSS from MediaWiki:Common.css applies to all skins, but MediaWiki:Vector.css only applies to users with the Vector skin.

Users can do the same types of changes, which will only apply to their own interface, by editing subpages of their user page (e.g. User:[Username]/common.js for JavaScript on all skins, User:[Username]/common.css for CSS on all skins, or User:[Username]/vector.css for CSS modifications that only apply to the Vector skin).

If the Gadgets extension is installed, sysops can also edit gadgets, i.e. snippets of JavaScript code providing features that can be turned on and off by users in their preferences. Upcoming developments on gadgets will make it possible to share gadgets across wikis, thus avoiding duplication.

This set of tools has had a huge impact and greatly increased the democratisation of MediaWiki's software development. Individual users are empowered to add features for themselves; power users can share them with others, both informally and through globally-configurable sysop-controlled systems. This framework is ideal for small, self-contained modifications, and presents a lower barrier of entry than heavier code modifications done through hooks and extensions.

Extensions et habillages

When JavaScript and CSS modifications are not enough, MediaWiki provides a system of hooks that let third-party developers run custom PHP code before, after, or instead of MediaWiki code for particular events. Les extensions MediaWiki utilisent les accroches pour s'insérer dans le code.

Before hooks existed in MediaWiki, adding custom PHP code meant modifying the core code, which was neither easy nor recommended. The first hooks were proposed and added in 2004 by Evan Prodromou; many more have been added over the years when needed. Par l'intermédiaire des accroches, il est même possible d'étendre le balisage des wikis MediaWiki avec des possibilités supplémentaires, en utilisant l'extension des balises.

The extension system isn't perfect: extension registration is based on code execution at startup, rather than cacheable data, which limits abstraction and optimisation and hurts MediaWiki's performance. But overall, the extension architecture is now a fairly flexible infrastructure that has helped make specialised code more modular, keeping the core software from expanding (too) much, and making it easier for third-party users to build custom functionality on top of MediaWiki.

Conversely, it's very difficult to write a new skin for MediaWiki without reinventing the wheel. In MediaWiki, skins are PHP classes each extending the parent Skin class; they contain functions that gather the information needed to generate the HTML. The long-lived "MonoBook" skin was difficult to customise because it contained a lot of browser-specific CSS to support old browsers; editing the template or CSS required many subsequent changes to reflect the change for all browsers and platforms.

API

The other main access point for MediaWiki, besides index.php, is api.php, used to access its machine-readable query API (Application Programming Interface).

Wikipedia users originally created "bots" that worked by screen scraping the HTML content served by MediaWiki; this method was very unreliable and broke many times. To improve this situation, developers introduced a read-only interface (located at query.php), which then evolved into a full-fledged read and write machine API providing direct, high-level access to the data contained in the MediaWiki database.

Les programmes client peuvent utiliser l'API pour se connecter, obtenir des données et publier des modifications. L'API prend en charge les clients JavaScript légers basés sur le web et les applications des utilisatuers finaux. Presque tout ce qui peut être fait via l'interface web peut être fait via l'API. Client libraries implementing the MediaWiki API are available in many languages, including Python and .NET.

Couches, domaines et modèles

Page principale : Architecture:MediaWiki

MediaWiki can be divided into around 12 technical layers , with each layer calling classes and code in the layer beneath it but not above it. Examples include the installer layer , entry point layer , wiring layer , and API layer . Code spanning all the layers can be grouped into around 21 domain modules , with examples including the navigation domain (skins), user management domain (create, rename, login), and internationalisation domain . Many software design patterns are used in MediaWiki, including the factory pattern , handler pattern , and command pattern .


Futur

What started as a summer project done by a single volunteer PHP developer has grown into MediaWiki, a mature, stable wiki engine powering a top-ten website with a ridiculously small operational infrastructure. This has been made possible by constant optimisation for performance, iterative architectural changes and a team of awesome developers.

The evolution of web technologies, and the growth of Wikipedia, call for ongoing improvements and new features, some of which require major changes to MediaWiki's architecture. This is, for example, the case for the ongoing visual editor project, which has prompted renewed work on the parser and on the wiki markup language, the DOM and final HTML conversion.

MediaWiki est un outil utilisé à des fins variées. Dans les projets Wikimedia, par exemple, il est utilisé pour créer et maintenir une encyclopédie (Wikipedia), pour alimenter une énorme bibliothèque multimédia (Wikimedia Commons) ou pour transcrire des textes de référence scannés (Wikisource); et autres. Dans d'autres contextes, MediaWiki est utilisé comme un CMS d'entreprise ou un dépôt de données, combiné quelques fois à un environnement sémantique. Ces utilisations particulières pour lesquelles il n'y a pas eu de planification vont probablement continuer à diriger les évolutions constantes de la structure interne du logiciel. En tant que tel, l'architecture de MediaWiki reste très vivante, tout comme l'immense communauté des utilisateurs qu'elle supporte.

Notes et références

  1. Les demandes de vues sont habituellement enjolivées en réécrivant l'URL, dans cet exemple, en w:Apple.
  2. https://twitter.com/MagnusManske/status/1083507467802365952

Lectures complémentaires

Voir aussi