Module:Fallback

local p = {}

-- List the full fallback chain from a language to default (usually English) function p.fblist(lang) local fbtable = mw.language.getFallbacksFor(lang) table.insert(fbtable, 1, lang) --	Take a translation from "Mediawiki:/" namespace	or from a loaded i18 resource bundle in MediaWiki for its UI messages (also	used by the "" parser function), before using the	provided default value. Requires args.message = 'Message-ID', instead of	args.message = 'actual translated message'.	-- table.insert(fbtable, 'message') table.insert(fbtable, 'default') return fbtable end

--[==[ Return an error if there is not default and no English version, otherwise return the message in the most appropriate, plus the lang code as a second value. --]==] function p._langSwitch(args, lang) -- args: table of translations if not args.en and not args.default and not args.message and args.nocat ~= '1' then return error("langSwitch error: no default") end -- Get language (either stated one or user's default language). if not lang then return ' LangSwitch Error: no lang ' -- must become proper error end -- Get the list of acceptable language (lang + those in lang's fallback chain) and check their content. for _, code in ipairs(p.fblist(lang)) do		local msg = args[code] if msg then -- Trim the assigned message value before testing it. msg = msg:gsub('^%s*(.-)%s*$') if msg ~= '' then if code == 'message' then -- If this is an UI message. See mw:Manual:Messages API. msg = mw.message.new(args.message):inLanguage(lang) --[==[ If this message name does not exist, converting it to					a string would not return an actual message, but this name within curved angle brackets U+29FC/U+29FD '⧼/⧽', part of mathematical symbols). The UI message may also be					disabled administratively if it causes problems.					--]==]					if msg:exists and not msg:isDisabled then						--[==[FIXME: In which language is this message?						This may be in some fallback language and not lang.						Note that some UI messages may have placeholders like '%s'						but there's no way to replace them here by actual values.						--]==]						return tostring(msg), lang					end				elseif msg == '~' then					return nil, code				elseif msg ~= '' then					return msg, code				end			end		end	end	return nil end

--[==[ Version to be used from wikitext. --]==] function p.langSwitch(frame) local args = frame.args -- If no expected args provided than check parent template/module args. if not args.en and not args.default and not args.nocat then args = frame:getParent.args end local lang if args.lang and args.lang ~= '' then lang = args.lang args.lang = nil else -- Get user's chosen language. lang = frame:preprocess("") end --[==[	if args.zh ~=  and args['zh-hans'] ==  and args['zh-hant'] == '' then else end --]==]	local str, language = p._langSwitch(args, lang) return str -- Get the first value of the langSwitch, (the text) not the second (the language). end

function p.fallbackpage(base, lang, formatting) local languages = p.fblist(lang) for i, lng in ipairs(languages) do if mw.title.new(base .. '/' .. lng).exists then if formatting == 'table' then return {base .. '/' .. lng, lng} -- Returns name of the page + name of the language. else return base .. '/' .. lng -- Returns only the page. end end end return base end

--[==[ Logic for Template:Autotranslate. ]==] function p.autotranslate(frame) local args = frame.args if not args.lang or args.lang == '' then args.lang = frame:preprocess("") -- Get user's chosen language. end -- Find base page. local base = args.base if not base or base == '' then return ' Base page not provided for autotranslate ' end if string.sub(base, 2, 9) ~= 'emplate:' then base = 'Template:' .. base -- Base provided without 'Template:' part. end -- Find base template language subpage. local page = p.fallbackpage(base, args.lang) -- if (not page and base ~= args.base) then -- Try the original args.base string. This case is only needed if base is not in template namespace. page = p.fallbackpage(args.base, args.lang) end if not page then return string.format(' no fallback page found for autotranslate (base=%s, lang=%s) ', args.base, args.lang) end -- Repack args in a standard table. local newargs = {} for field, value in pairs(args) do		if field ~= 'base' then newargs[field] = value end end -- Transclude with template arguments the same as the ones passed to  template. return frame:expandTemplate{ title = page, args = newargs } end

--[==[ Translate data stored in a module. ]==] function p.translate(page, key, lang) if type(page) == 'string' then -- If the requested translation table is not yet loaded. page = require('Module:' .. page) end local val if page[key] then val = page[key] elseif page.keys and page.keys[key] then -- Key 'keys" is an index of all keys, including redirects, see Module:i18n/datatype.		val = page.keys[key]	end	if not val then		return '<' .. key .. '>'	end	return p._langSwitch(val, lang) end

function p.translatelua(frame) local lang = frame.args.lang local page = require('Module:' .. mw.text.trim(frame.args[1])) -- Page should only contain a simple of translations. if not lang or mw.text.trim(lang) == '' then lang = frame:preprocess("") end if frame.args[2] then page = page[mw.text.trim(frame.args[2])] end return p._langSwitch(page, lang) end

-- This test does not work ('Module:Fallback/tests/fallbacks' is missing) function p.runTests local toFallbackTest = require('Module:Fallback/tests/fallbacks') local result = true mw.log('Testing fallback chains') for i, t in ipairs(toFallbackTest) do		local fbtbl = table.concat(p.fblist(t.initial), ', ') local expected = table.concat(t.expected, ', ') local ret = (fbtbl == expected) mw.log(i, ret and 'passed' or 'FAILED', t.initial, (not ret) and ('FAILED\nis >>' .. fbtbl .. '<<\nbut should be >>' .. expected .. '<<\n') or '') result = result and ret end return result end

--[==[ List all input arguments of the template that calls "" ]==] function p.showTemplateArguments(frame) local str = '' for name, value in pairs( frame:getParent.args ) do		if str == '' then str = string.format('%s=%s', name, value)         -- argument #1 else str = string.format('%s, %s=%s', str, name, value) -- the rest end end return str end

return p