Modul:Sandkasse/Poul G/I18n
Moduldokumentation[opret]
Hvis du ønsker en dokumentationsside for dette Scribuntomodul, så opret den her. Brugere kan eksperimentere i dette moduls undersider sandkasse (opret | kopiér) og testcases (opret). Tilføj venligst kategorier til /dok-undersiden. Undersider til dette modul. |
-- I18n deals with messages in order to make modules language-independent. A module should be able to
-- place messages in sub-modules named like Module:Modulename/i18n/fr for french messages.
local loaded = {} -- cache, filename to table or "not found"
-- helper to cache loadData
-- pagename: the page to load
-- returns a table or nil
local function load(pagename)
-- mw.log('load ' .. pagename)
local ret = loaded[pagename]
if ret == "not found" then
return nil
elseif ret == nil then -- first try
local status
status, ret = pcall(mw.loadData, pagename)
if not status then
loaded[pagename] = "not found"
return nil
end
loaded[pagename] = ret
-- mw.log(pagename.." loaded "..type(ret)..": "..mw.dumpObject(ret))
end
-- mw.log('load returns ' .. mw.dumpObject(ret))
return ret
end
-- helper to lookup a keyvalue
-- lst: the list of table to search; strings will trigger mw.loadData
-- key: the key to lookup
-- validate: function to filter found values; by default everything is accepted
-- nomatch: function to return a value if everyting else fails; by default nil
-- returns the first value acceptable by validate
local function lookup(lst,key,validate,nomatch)
-- sanatize parameters
lst = lst or {}
if type(key) == "number" then
key = tostring(key)
elseif type(key) ~= "string" then
return error("i18n.lookup(non string argument)",2)
elseif key == "" then
return error("i18n.lookup(empty string argument)",2)
end
if type(validate) ~= "function" then
validate = function(key, value) return true end
end
if type(nomatch) ~= "function" then
nomatch = function(key) return nil end
end
-- loop over lst; stop at first match
for n, tbl in pairs(lst) do
-- mw.log("work on (" .. n .. ") " .. mw.dumpObject(tbl))
if type(tbl) == "string" then
-- mw.log('load it')
tbl = load(tbl) -- will return a table or nil
lst[n] = tbl -- save for next lookup
-- mw.log('loaded '..tostring(tbl))
end
if type(tbl) == "table" and tbl[key] and validate(key, tbl[key]) then
return tbl[key]
end
end
return nomatch(key)
end
local I18n = {} -- table to export class with callable functions
function I18n.new(start)
local i18n, mt, lst = {}, {}, {} -- instance, its metatable, holder of searchlist
-- appends table or module-name to the search-list
i18n.append = function(tbl)
if type(tbl) == "table" then
lst[#lst+1] = tbl -- append to search-list
elseif type(tbl) == "string" then
if mw.ustring.sub(tbl,-1) ~= "/" then
tbl = tbl .. "/"
end
local lang = mw.language.getContentLanguage()
if lang then
lang = lang.code
else
lang = "en" -- use english as last default fallback
end
-- append the names of the modules to load; loading is done when actually needed
lst[#lst+1] = tbl .. "i18n/" .. lang
for _, fallbackLang in pairs(mw.language.getFallbacksFor(lang)) do
lst[#lst+1] = tbl .. "i18n/" .. fallbackLang
end
else
return error("invalid tbl-parameter for i18n.append, expected table or pagename, found "..type(tbl), 2)
end
return i18n -- allow chaining
end
-- wraps error message in error-class span
i18n.error = function(key)
local value
if type(key) == "string" and key ~= "" then
value = i18n[key] or "undefined error: " .. key
else
value = "error"
end
local elm = mw.html.create('span')
elm
:addClass('error')
:wikitext(value)
return tostring(elm)
end
mt.__call = function(tbl,...)
local args = {...}
return lookup(lst,args[1])
end
mt.__concat = function(a,b)
a.append(b)
return a
end
mt.__index = function(tbl,key)
return lookup(lst,key)
end
-- block updates
mt.__newindex = function(tbl,key,value)
return error("attempted modify of i18n["..key.."]", 2)
end
setmetatable(i18n,mt)
if start then
i18n.append(start)
end
return i18n
end
return I18n