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.

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
Module:Synchronizer and its partner Template:Synchronize can serve as an example of how to create a cross-wiki module.


 * 1) Module:Synchronizer is copied to other wikis with exactly the same name and code. For example in the Spanish Wikipedia it's called Módulo:Synchronizer (the namespace gets automatically translated but this causes no issues) and has exactly the same code.
 * 2) Template:Synchronize, on the other hand, can be named differently (localized) in each wiki. For example in the Spanish Wikipedia it's called Plantilla:Sincronizar.
 * 3) Templates call the module and in doing so they may rename (localize) parameters, translate strings, and set their own defaults. For example, in the Spanish Wikipedia the wikitext of Plantilla:Sincronizar could be:
 * 4) * Since "página" means page in Spanish, we're effectively localizing the "page" parameter to Spanish.
 * 5) * Since the "text" parameter controls the text of the button inserted by the module, we're effectively translating it to Spanish.
 * 6) * We're also setting a default text to "esta página" (which literally means this page) when no page is specified.

Best practices
While not required, the following are usually a good idea:


 * Ensure proper testing. There could be millions of pages that rely on any given module, so we need to make sure the module is adequately tested before making any changes. For this example, I had to create Module:No_globals/testcases that verified that the module would raise expected errors when global variables were accessed without declaration, and do nothing otherwise. The testcases/doc (detailed) and the main doc (summary) pages were updated to show the results of the test runs.
 * Note that the testcases can work with both the main module and the sandbox module, so that we can compare the results.
 * Note that the testcases/doc and the main doc pages shows the results of both the sandbox and main modules. The summary test results must always be visible in order to catch errors as early as possible.
 * Create translation table from strings. The No globals module contained two English strings:  and , and both strings were followed by a parameter  . We created a new translation table Data:I18n/No_globals.tab on Commons 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.
 * Replace strings with calls to TNT module. Now we can use Module:TNT format function to convert  from the translation table into a localized string. Place   at the top of your module, and call   to get the localized text. 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:  Note that we first modified the Module:No globals/sandbox page to make sure our changes did not break any of the tests (see point #1).
 * 1) Lastly we need to indicate that this is a shared module by adding a   to the top of the doc page. The first parameter is the name of our template on mediawiki.org, and the second parameter indicates that this module has a translation table called Data:I18n/No_globals.tab on Commons. We also need to add Q63090714 as an additional instance-of for the Module:No globals wikidata entry (Q16748603).

Requirements for the Shared Modules

 * Sandbox: Each module must have a .../sandbox sub-page with a copy of the module code (the code might have a few changes compared to the main module page)
 * Testcases: Each module must have a .../testcases page with good unit tests to ensure high quality and stability of the shared module.
 * Testcases must use Module:ScribuntoUnit
 * Testcases must be able to run with both the module and module/sandbox versions (see TNT or TableTools examples)
 * Testcases should have require('Module:no globals') to avoid accidentally using non-declared variables
 * Documentation: Each module must have a good quality documentation in the /doc page:
 * The /doc page must start with.
 * If module has a translation table, add it as a second parameter in the warning, e.g.  would link to Data:I18n/Module:TNT.tab on Commons.
 * Add a quality control section at the top, listing the summary of the testcase runs for both the primary and the sandbox versions of the module. See Module:TNT for an example.
 * Document all public functions of the module.
 * Translations: module must not have any user-visible strings hard-coded in any human language. If it needs any user-visible strings, it must use the TNT module to convert a message ID with optional parameters to a string for the current language. See below for an example.

Requirements for the Shared Templates

 * Translations: template must not have any user-visible strings in any language. Instead, it should use TNT module to convert a message ID with optional parameters to a string for the current language. See below for an example.
 * Documentation: Each template must have a good quality documentation in the /doc page:
 * The /doc page must start with.
 * If template has a translation table, add it as a second parameter in the warning, e.g.  would link to Data:I18n/Template:XX.tab on Commons.
 * Template one-line description and parameters must be stored in a template parameter table, see Translating Template Parameters below.
 * Insert  at the end of the /doc page, where Template_Name would mean Data:Templatedata/Template_Name.tab on Commons.
 * If possible, create a /testcases subpage to run unit tests.

Translating user-readable strings
There is very little value in having non-translated user-readable strings copied as is. The TNT module 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 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.

Global Modules
Just like templates, modules should also use TNT module for localization:

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 sub-page 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.

Volunteers

 * Capankajsmilyo (talk) 18:24, 17 May 2019 (UTC)
 * Viztor (talk) 00:13, 5 August 2019 (UTC)

FAQ

 * Q) If templates and modules are centralized, what will be about translated templates and modules?
 * A) Each centralized module/template will have Template:Shared Template Warning placed at the top. In this mechanism, code and translation is separated to make the work easier for editors. Code is stored and reused from mediawiki.org and the translations are stored and used from commons Data. For example, code of Template:Shared Template Warning will be copied from Template:Shared Template Warning and the translations are managed at commons:Data:I18n/Shared Template Warning.tab


 * Q) We need a template and module which can accept Devanagari Number (१,२....), so this updation will provide sa.wiki this facility?
 * A) Only the compatible modules/templates are converted as centralized after aggressive test validations. So specific requirements of each wiki given utmost importance. Conversion of only Module:TNT, Module:No globals, Module:TableTools and Template:Shared Template Warning has been completed so far due to this. Rest are still in the process and will not be impacted till everything is set right.


 * Q) If some mistake occurred, who should be informed for correction?
 * A) In case of any mistake, you can simply leave a message on talk page or contact on the template/module talk page on mediawiki or can directly contact or me. The issue will be resolved.

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)