Module:LangSwitch/sandbox

Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

Sandbox for Module:LangSwitch

Code

--[[
  __  __           _       _        _                      ____          _ _       _     
 |  \/  | ___   __| |_   _| | ___ _| |    __ _ _ __   __ _/ ___|_      _(_) |_ ___| |__  
 | |\/| |/ _ \ / _` | | | | |/ _ (_) |   / _` | '_ \ / _` \___ \ \ /\ / / | __/ __| '_ \ 
 | |  | | (_) | (_| | |_| | |  __/_| |__| (_| | | | | (_| |___) \ V  V /| | || (__| | | |
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)_____\__,_|_| |_|\__, |____/ \_/\_/ |_|\__\___|_| |_|
                                                     |___/                               
 Authors and maintainers:
* User:Zolo - original version in Module:Fallback
* User:Jarekt - perfomance improvement to avoid loading fallbacks when not needed
* User:Verdy_p - performance improvements, fix for 'default=*'
]]

-- add optional module 
-- used for debugging purposes as it detects cases of unintended global variables
require('strict')

local p = {}
local insert = table.insert
local concat = table.concat
local gmatch = string.gmatch
local getFallbacksFor = mw.language.getFallbacksFor
local getCurrentFrame = mw.getCurrentFrame
local isValidCode = mw.language.isValidCode

local createTag -- lazy loading of the module: only for the files that need it

--[[
Add invisible but machine readable labels to the files, which can be used to add titles to wikidata items
]]
local function add_labels(args)
	if not createTag then
		createTag = require('Module:TagQS').createTag -- lazy loading of the module: only for the files that need it
	end
	-- Add text of invisible tag brodcasted by the template which allows creation of QuickStatements command used to add this info to Wikidata
	local qsTable = {}
	for key, text in pairs(args) do 
		if type(key) == 'string' and key ~= 'add_labels' then
			for code in gmatch(key:lower(), '([%-0-9a-z]+)') do
				if isValidCode(code) then -- code has to be a valid language
					insert(qsTable, createTag('label', 'L' .. code, '"' .. text .. '"'))
				end
			end
		end
	end
	return concat(qsTable)
end

--[[
_langSwitch
 
This function is the core part of the LangSwitch template. 
 
Example usage from Lua:
  text = _langSwitch({en='text in english', pl='tekst po polsku'}, lang)
 
Parameters:
  args - table with translations by language
  lang - desired language (often user's native language)

Error Handling:
]]
function p._langSwitch(args, lang, quick, nocat) -- args: table of translations only
	assert(lang, 'LangSwitch Error: no lang')
	-- Return error if there is not 'default' and no 'en' version
	if not args.default and not args.en then
		local err = '<b class="error">LangSwitch Error: no default</b>'
		if nocat then
			return err
		else
			return err .. '[[Category:LangSwitch template without default version]]'
		end
	end
	-- To improve performance try quick switch, and load fallback chain only if needed. 
	-- In the vast majority of cases quick switch (not using any fallbacks) is sufficient.
	local value = args[lang]
	if value or quick then
		return value == '~' and '' or value
	end
	-- Get the list of acceptable languages (lang + those in lang's fallback chain) and check their content.
	local langList = getFallbacksFor(lang)
	-- table.insert(langList, 1, lang) -- not needed (already checked in the quick test above)
	for _, language in ipairs(langList) do
		if language ~= 'en' or lang:sub(1, 3) == 'en-' then
			value = args[language]
			if value then
				return value == '~' and '' or value
			end
		end
	end
	value = args.default and args.default or args.en
	return value == '~' and '' or value
end

--[[
langSwitch
 
This function is the core part of the LangSwitch template. 
 
Example Usage from a template:
  {{#invoke:fallback|langSwitch|en=text in english|pl=tekst po polsku|lang={{int:lang}} }}
 
Parameters:
  frame.args - table with translations by language
  frame.args.lang - desired language (often user's native language)
  frame.args.quick - if non-empty, disable the lookup for fallbacks
  frame.args.nocat - if non-empty, disable the tracking categorization if there's no 'default' or 'en' version

Error Handling:
]]
function p.langSwitch(frame) -- version to be used from wikitext
	local args = frame.args
	-- If no expected args provided, then check parent template/module args.
	if not(args.lang or args.en or args.default or args.quick or args.nocat) then
		args = getCurrentFrame():getParent().args
	end
	local lang = args.lang
	if not lang or lang == '' or not isValidCode(lang) then
		lang = frame:callParserFunction('Int', 'Lang') -- get user's chosen language 
	end
	lang = lang:lower()	
	-- add text of invisible tag brodcasted by the template which allows creation of QuickStatements command used to add this info to Wikidata
	local labels = ''
	if args.add_labels then
		labels = add_labels(args)
	end
	-- Fast lookup for most frequent simple cases (direct match, without composite keys or fallbacks)
	local value = args[lang]
	if value and value ~= '' then
		return value ~= '~' and value or ''
	end
	-- Allow input in format: {{LangSwitch|de=GrĂ¼n|es/it/pt=Verde|fr=Vert|en=Green |lang=en}}
	-- with multiple languages mapping to a single value.
	-- We need a new table as we cannot change the args table from the caller's or parent's frame.
	local args1, nocat, quick = {}, args.nocat and args.nocat ~= '', args.quick and args.quick ~= ''
	for key, value in pairs(args) do
		if value ~= '' and type(key) == 'string'
		and not(key == 'lang' or key == 'quick' or key == 'nocat') then
			for code in gmatch(key:lower(), '([%-0-9a-z]+)') do
				args1[code] = value
			end
		end
	end
	return p._langSwitch(args1, lang, quick, nocat)
end

return p
X