Modèles et modules multilingues

This page is a translated version of the page Multilingual Templates and Modules and the translation is 100% complete.

Cette page explique comment créer des modules et des modèles globaux, interwiki et multilingues et comment les garder synchronisés sur les wikis Wikimedia.

L'outil Synchronizer est utilisé pour garder les modules à jour sur l'ensemble des wikis.

Pourquoi est-ce nécessaire ? Parce que nous n'avons pas qu'une seule Wikipedia, nous en avons plus de 300 différentes ainsi que d'autres projets de wiki, et chaque fois que quelqu'un crée un nouveau modèle ou un module Lua valable, il est copié et traduit plus de 300 fois. Chaque traducteur doit bien comprendre le balisage MediaWiki, ce qui fait de la copie un processus très fastidieux et sujet à erreurs, en partie parce que les auteurs des modèles supposent souvent que leurs modèles ne sont utilisés que dans une seule langue. Une fois copiés, les modèles originaux sont souvent améliorés, et chaque copie doit être mise à jour tout en conservant toutes les traductions existantes. Les frais purement humains pour copier les modèles et les modules sont si élevés que la plupart d'entre eux ne sont jamais copiés ni mis à jour, en particulier pour les petits wikis.

Est-ce que c'est la meilleure approche ? Non, mais c'est la meilleure approche avec la technologie actuelle. Une réécriture importante de MediaWiki est nécessaire pour que cela soit possible au niveau du système. Des modèles multi-sites ont été demandés dès le début en 2001, mais peu a été fait simplement parce que c'est un problème difficile à résoudre. Avec cette approche, il est possible de créer maintenant du contenu multilingue, et une fois que MediaWiki le supportera, nous pourrons facilement migrer le contenu multi-lingue vers le nouveau système sans beaucoup de travail.

Méthode générale

  • Un module global est un module Lua conçu pour être utilisé avec exactement le même code sur chaque wiki.
  • Pour devenir global, un module doit fournir les moyens aux wikis de traduire tout ce qu'ils ont besoin de localiser, sans avoir à toucher le code du module lui-même. Cette page décrit plusieurs techniques pour réaliser cela.
  • Une fois le module devenu global, l'outil Synchronizer peut être utilisé pour le garder à jour sur tous les wikis Wikimedia.
  • Pour obtenir un modèle global, il faut le transformer en module global.

Pratiques recommandées

Cette section décrit certaines des meilleures pratiques pour développer des modules globaux.

Nommage

Cette section peut être ignorée si les modules sont conçus pour être appelés uniquement à partir des modèles.

Les modules globaux destinés à être utilisés par d'autres modules doivent être nommés de la même manière sur tous les wikis afin d'éviter les ruptures de dépendance avec les autres modules globaux. Par exemple, si un module nommé A nécessite un module nommé B, mais que dans certains wikis le module B est nommé C, alors le module A ne fonctionnera pas dans ce wiki, à moins que le code source du module A ne soit modifié localement pour utiliser C au lieu de B, ce qui serait contraire à la mondialisation du module A.

Si une communauté locale n'accepte pas le nom global, ou si le renommage est trop problématique, alors une solution est de créer un module de redirection portant le nom global, qui renvoie simplement le nom du module local.

Heureusement, le fait que l'espace de noms du module soit nommé différemment dans chaque langue ne casse pas les dépendances, car Module est un alias pour l'espace de noms du module dans toutes les langues.

Module maître

Les modules globaux doivent choisir un wiki où les développements seront faits. Généralement, ce sera le wiki d'accueil du module, mais il peut bouger pour diverses raisons, par exemple si on veut augmenter les chances de recruter de nouveaux développeurs en centralisant le développement dans un wiki plus grand ou plus approprié.

Les modules globaux doivent commencer par un commentaire comportant un lien vers le module maître afin de réduire les chances d'avoir des fork et pour aider au recrutement de nouveaux développeurs (exemple).

Bac à sable

Les modules globaux doivent avoir une sous-page /sandbox où tester les modifications avant de les déployer sur le module maître et sur les autres wikis (exemple).

Cas d'utilisation

Les modules globaux doivent avoir une sous-page /testcases avec des tests unitaires réussis pour vérifier la haute qualité et la stabilité du module (exemple). Les cas d'utilisation doivent :

  • Utiliser Module:ScribuntoUnit
  • S'exécuter à la fois avec le module principal et les versions du bac à sable, afin que nous puissions comparer les résultats (exemple)
  • Utiliser require('strict') pour éviter d'utiliser accidentellement des variables non déclarées
  • sortir les résultats à la fois dans /testcases/doc et dans la page principale /doc du module, pour détecter les erreurs le plus tôt possible

Documentation

Les modules globaux doivent avoir une sous-page /doc avec la documentation de toutes les fonctions publiques du module (exemple) et une section avec les cas de test à la fois pour les versions primaires et le bac à sable du module (exemple).

Configuration

Les modules globaux qui nécessitent une configuration doivent avoir un sous-module séparé /config pour empêcher les wikis locaux de modifier le code source pour configurer le module (exemple).

Synchronisation

Dès qu'un module est capable d'être copié sans modification sur d'autres wikis, l'outil Synchronizer peut être utilisé pour le copier et le maintenir synchronisé sur tous les wikis Wikimedia.

Compatibilité arrière

Les modules globaux doivent généralement maintenir le développement rétrocompatible, car les changements qui ne sont pas rétrocompatibles nécessitent souvent des mises à jour manuelles dans chaque wiki, modèle ou module utilisant le module.

Internationalisation des paramètres des modèles

Les modules globaux peuvent avoir leurs paramètres localisés par les appelants du modèle. Par exemple, considérez le module suivant qui génère simplement le texte donné (ou « Example » si aucun n'est donné) :

local p = {}

function p.main(frame)
 	 local args = frame.args
 	 local text = args['text'] or 'Example'
 	 return text
end

return p

Puis un modèle espagnol localiserait le module ainsi :

{{#invoke:Example|main
| text = {{{texto|Ejemplo}}}
}}

Notez que le modèle ne localise pas seulement le nom du paramètre « texte » (texto en espagnol) mais aussi le texte par défaut « Exemple » (Ejemplo en espagnol).

Voir Plantilla:Extracto pour un cas réel de modèle qui localise un module global avec cette technique. Voir aussi Template:Excerpt pour un cas où un module global est localisé pour la Wikipédia anglophone, démontrant que l'internationalisation n'est pas toujours la même chose qu'une traduction.

Traduction des chaînes lisibles par l'utilisateur

De nombreux modules doivent produire des chaînes lisibles par l'utilisateur, telles que les messages d'erreur et les éléments d'interface (comme les boutons). Le codage en dur du texte de ces chaînes oblige les autres wikis à modifier le code afin de les localiser, empêchant la globalisation. Pour éviter cela, les développeurs doivent fournir des moyens de localiser les chaînes lisibles par l'utilisateur sans avoir à modifier le code lui-même. Cette section explique plusieurs manières de faire cela.

Paramètres des modèles

Les chaînes lisibles par l'utilisateur peuvent être localisées au travers des paramètres du modèle lors de l'appel du module. Cette approche est pratique quand :

  • Le texte est susceptible de varier à chaque appel du modèle
  • Le texte est susceptible d'être modifié par les utilisateurs lors de l'appel du modèle
  • Le texte est susceptible de contenir un mot magique, un appel de modèle, une fonction d'analyse syntaxique ou un autre élément wiki

Exemple de module utilisant cette approche :

local p = {}

function p.main(frame)
 	 local args = frame.args
 	 local text = args['text'] or 'Example'
 	 return text
end

return p

De cette manière, chaque modèle peut modifier le texte lors de l'appel du module, ainsi :

{{#invoke:Example|main
| text = Ejemplo
}}

Notez que dans cet exemple, si un modèle appelle le module sans spécifier le paramètre text, alors le texte anglais 'Example' codé en dur sera utilisé. Ceci n'est pas nécessaire. Les modules peuvent exiger que les appelants des modèles définissent le paramètre text en générant une erreur s'il n'existe pas. Cependant, il est souvent plus sympathique d'avoir une solution de repli.

Fichier de configuration

Une autre façon de localiser les chaînes lisibles par l'utilisateur est de le faire via une sous-page séparée de /config. Cette approche est pratique lorsque :

  • Le module est destiné à être appelé par de nombreux modèles par wiki, permettant ainsi la localisation de se faire une seule fois et d'être ensuite réutilisée
  • Il y a beaucoup de messages à localiser, donc il est plus facile de les avoir tous ensemble à un même endroit
  • Nous avons déjà besoin d'un fichier /config pour d'autres raisons, alors nous pourrions aussi bien l'utiliser aussi pour la localisation

Exemple de module utilisant cette approche :

local config = require('Module:Example/config')

local p = {}

function p.main(frame)
 	 local text = config.text or 'Example'
 	 return text
end

return p

Les wikis pourraient alors créer des fichiers dans /config ainsi :

return {
 	 text = 'Ejemplo'
}

Tables de traduction

Une autre façon de traduire les chaînes lisibles par l'utilisateur est de passer par une table de traduction centrale sur Commons. Cette approche est pratique quand :

  • Les chaînes doivent changer en fonction de la langue préférée de l'utilisateur, plutôt que de la langue du wiki ou celle de la page.
  • Nous voulons centraliser les efforts de traduction sur une page unique.

Module:TNT a été créé spécifiquement pour obtenir les chaînes des tables de traduction. Exemple de module utilisant TNT :

local TNT = require('Module:TNT')

local p = {}

function p.main(frame)
 	 local text = TNT.format('I18n/Example', 'text')
 	 return text
end

return p

Voir Data:I18n/Template:Graphs.tab pour un exemple simple mais réel d'une table de traduction avec deux messages, chacun ayant un seul paramètre. Il est important de stocker les paramètres comme des parties de chaînes parce que dans de nombreuses langues, le paramètre doit être placé à une position différente dans la chaîne selon les normes du langage.

Les tables de traduction doivent commencer par le préfixe Data:I18n/... pour les séparer des autres types de données de table. Si un message n'a pas encore été localisé, TNT reviendra à l'anglais (ou sur une autre langue de repli tel que défini pour la séquence de repli de la langue). TNT prend également en charge toutes les conventions de localisation standard telles que {{PLURAL|...}} et d'autres paramètres .

Un inconvénient de cette approche est qu'elle nécessite l'installation et la configuration de Extension:JsonConfig , ce qui n'a peut-être pas été fait sur les wikis non Wikimedia, limitant ainsi la possibilité de réutiliser ces modules sur les Wikipedia tierces.

Messages MediaWiki

Dans certains cas, MediaWiki lui-même (ou une extension) peut avoir les messages dont nous avons besoin, déjà traduits. Par exemple, si nous avons besoin de la chaîne « Nouvelle page » nous pouvons utiliser MediaWiki:Newpage, comme ceci :

local p = {}

function p.main(frame)
 	 local msg = mw.message.new('newpage')
 	 local text = msg:plain()
 	 return text
end

return p

Voir Special:AllMessages pour la liste de tous les messages disponibles.

Le tout ensemble

En fonction des cas, toutes les méthodes ci-dessus peuvent être combinées. Par exemple, les messages MediaWiki peuvent être utilisés lorsqu'ils sont disponibles, et sivce n'est pas le cas, une table de traduction ou un fichier de configuration est consulté, et si aucune localisation n'y est trouvée, alors un texte anglais codé dur est utilisé, à moins qu'un paramètre de modèle ne l'annule.

La combinaison de plusieurs méthodes peut être efficace, mais les avantages doivent être pondérés au vu des inconvénients de la complexité accrue, qui peuvent entraîner une perte de performances et des bogues, ainsi que des difficultés accrues dans le maintien du code et le recrutement de nouveaux développeurs.

Template data

Les paramètres du modèle sont généralement stockés sous forme de bloc JSON de templatedata dans la sous-page de /doc du modèle. Cela rend la traduction pratique, mais lorsqu'un nouveau paramètre est ajouté à un modèle global, toutes les pages /doc doivent être mises à jour dans chaque langue. Module:TNT aide à faire cela en générant automatiquement le bloc des templatedata à partir d'une table stockée sur Commons. En plaçant la ligne suivante dans chaque sous-page de /doc on utilise la table Data:Templatedata/Graph:Lines.tab pour générer toutes les informations Templatedata nécessaires pour chaque langue. Même si la communauté locale n'a pas traduit la documentation complète du modèle, elle pourra voir tous les paramètres du modèle, mis à jour de manière centralisée.

{{#invoke:TNT|doc|Graph:Lines}}

Voir aussi

  • Proposition de la liste des souhaits 2019 (40 votes)
  • T122086 - RFC à propos du partage des modèles et des modules entre les wikis - manuel simple (idée originale pour ce robot)
  • T121470 - Dépôt global central pour le ticket des modèles, des modules Lua et des gadgets (principal ticket pour tout ce qui peut être partagé sur le site)
  • T41610 - Scribunto doit prendre en charge l'appel aux modules globaux
  • Modèles globaux, propositions de spécifications, version courte - proposition pour mettre en œuvre une idée similaire de manière globale, sans avoir besoin d'outils spéciaux, et avec un soutien complet dans le noyau et les extensions de MediaWiki