Module:I18n
Appearance
i18n stands for internationalisation, because it is formed by i + 18 letters + n. This modules serves as the basis for the various localisation templates. Data submodules:
--[[
Backbone of various internationalisation templates.
--]]
local p = {}
local function normalize_args(frame)
return require('Module:Arguments').getArgs(frame, { trim = true, removeBlanks = true, parentOnly = true })
end
--[[
Returns the user's selected UI language if none was stated.
* `frame` (optional): Can be specified in order to avoid the module from retrieving it again.
* `stated_lang` (optional): Manually specified language.
--]]
local function get_lang(frame, spec_lang)
if not spec_lang or not mw.language.isSupportedLanguage(spec_lang) then
return (frame or mw.getCurrentFrame()):callParserFunction("int", "lang")
end
return spec_lang
end
--[[
Iterates until it finds a supported language.
* `start_lang`: The best language possible from which the fallback chain starts.
* `check`: The method called to check whether a language has support or not.
* `found`: The method called when a supported language is finally found.
--]]
local function fallback(start_lang, check, found)
-- Return error if there is not default and no English version.
if not check("en") and not check("default") and not check("message") and not check("item") then
return error("Fallback, no default option provided.")
end
-- Iterate through each language in the fallback list.
local lang_list = mw.language.getFallbacksFor(start_lang)
table.insert(lang_list, 1, start_lang)
table.insert(lang_list, "message")
table.insert(lang_list, "item")
table.insert(lang_list, "default")
for _, lang in ipairs(lang_list) do
if check(lang) then
return found(lang)
end
end
end
--[[
Returns the message in the most appropriate language.
* `data`: Data table of translations.
* `start_lang`: Language to translate to (either stated or user's default).
--]]
local function from_data(data, start_lang)
return fallback(
start_lang,
function (lang) return data[lang] end,
function (lang)
local value = data[lang]
-- The tilde works as a fallback-stopping nil value.
if value == "~" then
return nil, lang
end
-- Wikidata items.
if lang == "item" then
return (mw.wikibase.getLabelWithLang(value)) or value
end
-- Interface messages.
if lang == "message" then
return tostring(mw.message.new(value):inLanguage(start_lang))
end
-- Normal case scenario.
return value
end
)
end
-- Method called by {{int table}}.
function p.int_table(frame)
local args = normalize_args(frame)
local lang = get_lang(frame, args.lang)
args.lang = nil
return from_data(args, lang)
end
-- Method called by {{int page}}.
function p.int_page(frame)
local args = normalize_args(frame)
args.lang = get_lang(frame, args.lang)
-- Find base page.
local base = args.base
assert(base, "Autotranslate, base page not provided")
args.base = nil
-- If base page does not indicate namespace assume it is a template.
if not mw.ustring.find(base, ":") then
base = "Template:" .. base
end
-- Find language subpage.
local page = (fallback(
args.lang,
function(lang) return mw.title.new(base .. "/" .. lang).exists end,
function (lang) return base .. "/" .. lang end
-- Default page if provided or nil otherwise.
)) or args.default
-- Transclude with template arguments the same as the ones passed to {{autotranslate}} template.
-- TODO: Track whether these args are ever useful and remove if not.
return frame:expandTemplate { title = page, args = args }
end
-- Method called by {{int}}.
function p.int_word(frame)
local args = normalize_args(frame)
return from_data(
require("Module:i18n/data/" .. args[1]),
get_lang(frame, args.lang)
)
end
-- Method called by {{int langname}}.
function p.int_langname(frame)
local code = normalize_args(frame)[1]
local name = mw.language.fetchLanguageName(code, get_lang(frame))
return name == "" and code or name
end
return p