Multilingual Templates and Modules

Introduction
What is it? This project makes it possible for Lua modules to be used on multiple wikis, without any modifications. All text strings are parameterized so they can be translated and localized when calling the modules from templates (or in some cases translations are stored in Commons) and the Synchronizer tool is used for keeping modules synced across Wikimedia wikis.

Why is this needed? Because we do not have a single Wikipedia, we have 300+ separate Wikipedias and other wiki projects, and every time someone creates a good new template or Lua module, it gets copied and translated 300+ times. Every translator has to thoroughly understand MediaWiki markup, making copying a very tedious and error-prone process, partially because template authors often assume their templates will be used in just one language. Once copied, the original templates are often improved, and each copy has to be updated while maintaining all existing translations. The pure human expense of copying templates and modules is so high that most of them are either never copied or never updated, especially for the smaller wikis.

Is this the best approach? No, but it is the best approach with the current technology. A significant MediaWiki rewrite is required to make this possible on the system level. Multi-site templates has been requested from the start in 2001, but not much was done simply because this is a hard problem to solve. With this approach it is possible to create multilingual content now, and once MediaWiki supports it, we can easily migrate multilingual content to the new system without much work.

Example
Module:Excerpt and its partner Template:Excerpt can serve as an example of how to create a cross-wiki module and template:


 * 1) Module:Excerpt is copied to other wikis with exactly the same name and code. For example in the Spanish Wikipedia it's called Módulo:Excerpt and has exactly the same code. Keeping the same name is important because dependencies between modules would break otherwise (luckily, the automatic localization of the Module namespace causes no issues because "Module" is an alias for the Module namespace in all languages).
 * 2) Template:Excerpt, on the other hand, can have completely different names and code in each wiki. For example in the Spanish Wikipedia it's called Plantilla:Extracto. The template calls the module and in doing so it may rename (localize) parameters, set local defaults, and translate strings. For example, in the Spanish Wikipedia the wikitext of Plantilla:Extracto could be:
 * 3) * The first parameter  is localized to Spanish, since listas means lists in Spanish.
 * 4) * The second parameter  is localized to Spanish too, but also sets 1 as the default value.
 * 5) * The last parameter  controls the error message shown to the user by the module when the requested page is not found, and is here being translated to Spanish. In some cases, it's better to create a translation table in Commons and have the module get them from there (example). See below for more.
 * 6) The Synchronizer tool may then be used to keep the module in sync across all Wikimedia wikis:

Best practices
This section describes some of the current best practices while developing cross-wiki modules.

Initial comment
Each module should start with a comment that includes a link to the main version of the module and some kind of warning asking to contribute to the main version rather than the local one (example). This reduces forking and guides contributors to collaborate.

Sandbox
Each module should have a /sandbox subpage where to test out changes before deploying them on the main module and the other wikis.

Testcases
Each module should have a /testcases page with good unit tests to ensure high quality and stability of the shared module, see for example Module:No globals/testcases
 * Testcases should use Module:ScribuntoUnit
 * Testcases should run with both the main module and the sandbox versions, so that we can compare the results (see TNT or TableTools examples)
 * Testcases should have require('Module:no globals') to avoid accidentally using non-declared variable
 * Testcases should output their results both in testcases/doc and the main doc page of the module, to catch errors as early as possible

Documentation
Each module should have good quality documentation in the /doc page.
 * Document all public functions of the module.
 * Include a quality control section, listing the summary of the testcase runs for both the primary and the sandbox versions of the module. See Module:TNT for an example.

Localized user-readable strings
There're two ways to provide localized user-readable strings:


 * Template parameters - The module may expose user-readable strings to templates as normal parameters, so that templates may provide translations when calling the module. For example, a module may have a  parameter with a default value set to "Page not found", but if the module is called with the parameter set, the it naturally overrides the default. This method is often enough for simple cases with few messages.
 * Translation tables - The Module:No globals contained two English strings:  and , and both strings were followed by a parameter  . We created a new translation table at Commons:Data:I18n/No globals.tab with the two strings, giving each a unique ID (  and  ). The parameter placeholder for both strings had to be included into the string itself as a  . It is very important to store parameters as parts of the string because in many languages the parameter would have to be placed at a different position in the string according to the norms of the language. The Module:TNT was created specifically to solve that. Instead of storing text in English or in another human language in a module or a template, TNT allows them to be designed as language-neutral, and store multilingual text in the tabular data pages on Commons. This way your module or template will use those translated strings (messages). If the message has not yet been translated, will fall back to English (or other fallback language as defined by the language's fallback sequence). When someone updates the translation table, your page will automatically update (might take some time, or you can purge it), but no change in the template or module is needed on any of the wikis. This process is very similar to MediaWiki's localisation, and supports all standard localization conventions such as NaN undefineds and other parameters. For this specific example, we do not need to load TNT module unless there is an error, so we can do both calls on the same line to optimize performance. These were the two replacements made: For a simple example, see Data:I18n/Template:Graphs.tab - a table with two messages, each message having a single parameter. By convention, all translation pages should have  Data:I18n/...  prefix to separate them from other types of data.

Translating template parameters
Template parameters are usually stored as a JSON templatedata block inside the template's /doc subpage. This makes it convenient to translate, but when a new parameter is added to a global template, all /doc pages need to be updated in every language. Module:TNT helps with this by automatically generating the templatedata block from a table stored on Commons. Placing this line into every /doc subpage will use Data:Templatedata/Graph:Lines.tab table to generate all the needed templatedata information in every language. Even if the local community has not translated the full template documentation, they will be able to see all template parameters, centrally updated.

Done

 * Module:TNT
 * Module:No globals (translations) -- implemented, needs to be moved to communities
 * Module:TableTools
 * Module:Transcluder
 * Template:Shared Template Warning
 * Template:BCP47 – not very useful on monolingual wikis, although other global templates may use it; auto-update is quite useful on multilingual ones

Pages OK to use without synchronization
These templates and modules exist on most wikis, but contain too much language-specific customizations to benefit from this system. A shared module/template can rely on these in addition to any other shared module/templates. Any new wiki should copy and modify these templates by hand.


 * Template:Documentation -- most templates on most wikis use this template to show a documentation header on the template pages.
 * I'm not sure about this. All templates perform the same function, are equally structured and are equally used. All graphic changes can be made through CSS without touching the code itself. You can look at my solution to this: Module:Documentation/sandbox, Template:Documentation/sandbox. Iniquity (talk) 23:45, 28 May 2019 (UTC)
 * Module:Yesno -- what each language accepts as "yes" and "no" for template parameters
 * This shouldn't cause much trouble even synchronized, but may not be necessary. Viztor (talk) 23:16, 4 August 2019 (UTC)

In progress

 * Module:Arguments (Status: Unit test pending)
 * - while we can adapt it as is, we may also enhance it to allow parameter name translation table to come from Commons (many templates localize their parameters). --Yurik (talk) 19:06, 7 May 2019 (UTC)
 * --Obsuser (talk) 21:09, 11 July 2019 (UTC)
 * , the same version is used in a bunch of wikis. There is a kind of related patch at https://gerrit.wikimedia.org/r/#/c/mediawiki/extensions/Scribunto/+/158323/ . --Amir E. Aharoni &#123;{🌎🌍🌏}} 23:36, 24 January 2020 (UTC)
 * Module:Lua banner – ready, but not actually made global because its dependencies are not global yet, which would cause a mess
 * Viztor (talk) 23:39, 4 August 2019 (UTC)

Proposed

 * Module:Navbar
 * --Obsuser (talk) 21:09, 11 July 2019 (UTC)
 * --BoldLuis (talk) 13:44, 20 April 2021 (UTC)
 * Module:Infobox
 * - eventually yes, but I suspect infobox has some dependencies we need to solve first. --Yurik (talk) 19:06, 7 May 2019 (UTC)
 * - hard CSS dependencies. Missing navbar module can be handled with code. --Zache (talk) 02:01, 8 May 2019 (UTC)
 * --Obsuser (talk) 21:09, 11 July 2019 (UTC)
 * , of course. How can there even be any doubt. It's big and difficult, and local communities need to have the ability to override content and design in some places, but it's one of the most visible families of templates, and most of the functionality is the same in all wikis, even if the implementation and the content policies around using infoboxes may be different. For small wikis, the lack of infobox templates is one of the biggest pain points. --Amir E. Aharoni (talk) 10:33, 25 September 2019 (UTC)
 * -- Masumrezarock100 (talk) 11:20, 23 November 2019 (UTC)
 * and urgent. w:Module:Infobox depends on Module:Navbar--BoldLuis (talk) 13:18, 20 April 2021 (UTC)
 * Module:Location map
 * --Obsuser (talk) 21:09, 11 July 2019 (UTC)
 * Thousands of subpages with the name being the only parameter needed to be translated to different languages. -- 94rain  Talk  06:15, 6 August 2019 (UTC)
 * location map -template will be eventually deprecated as development is already moving to dynamic maps. --Zache (talk) 06:34, 23 August 2019 (UTC)
 * Module:String
 * - the _error function should be changed to accept (message_id, ...) (id + optional params). If not ignoring errors, use TNT to translate messages. --Yurik (talk)
 * --Obsuser (talk) 21:09, 11 July 2019 (UTC)
 * --Jarekt (talk) 03:58, 13 April 2020 (UTC)
 * d:Module:Databox
 * --Obsuser (talk) 21:09, 11 July 2019 (UTC)
 * Module:Navbox
 * --Obsuser (talk) 21:09, 11 July 2019 (UTC)
 * -- Masumrezarock100 (talk) 11:20, 23 November 2019 (UTC)
 * Module:Message box
 * --Obsuser (talk) 21:09, 11 July 2019 (UTC)
 * Module:ScribuntoUnit
 * can be easily supported, not much site-specific info. Viztor (talk) 00:32, 6 August 2019 (UTC)
 * --Jarekt (talk) 04:00, 13 April 2020 (UTC)
 * Template:Bot
 * It's one of the most commonly used templates in all fo Wikimedia's projects, perhaps the most used one. --Amir E. Aharoni (talk) 10:33, 25 September 2019 (UTC)
 * Template:Convert
 * It even has instructions for adapting to other languages. --Amir E. Aharoni (talk) 06:27, 26 September 2019 (UTC)
 * Module:InfoboxImage
 * Capankajsmilyo (talk) 01:06, 25 March 2020 (UTC)
 * Module:DateI18n
 * - This module localizes dates, is the latest incarnation of the code used for over a decade on majority of files on Commons. It is cloned to many other wikis. I recently rewrote it to use c:Data:DateI18n.tab and c:Data:I18n/MonthCases.tab to store data on language specific date formats. --Jarekt (talk) 03:58, 13 April 2020 (UTC)
 * Template:User link
 * Template:Tl
 * comment Suggest to migrate this to be a magic word, instead of copy-pasting everywhere. --Liuxinyu970226 (talk) 14:51, 30 April 2020 (UTC)
 * Module:Clickable button 2 and Template:Clickable button 2
 * , is used widely across multiple Wikis. And often this creates confusion as there is an unlinked version 1 as well and some templates use depreciated ui-button. A global version would provide constancy and use updated css class Vis M (talk) 19:53, 26 June 2021 (UTC)