Jump to content
Toggle menu
  • 8 articles
  • 75 files
  • 7 users
  • 37.8K edits
Neodyland Wiki
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 04:33, 11 February 2021 by commons>Jarekt (add parseStatements function)
Module documentation[ create · purge ]
This documentation is transcluded from Module:Core/doc.
--[[  
  __  __           _       _         ____               
 |  \/  | ___   __| |_   _| | ___ _ / ___|___  _ __ ___ 
 | |\/| |/ _ \ / _` | | | | |/ _ (_) |   / _ \| '__/ _ \
 | |  | | (_) | (_| | |_| | |  __/_| |__| (_) | | |  __/
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)\____\___/|_|  \___|
                                                        
This module is intended as collection of core functions shared among several Lua modules 
creating infobox templates on Commons. 

Authors and maintainers:
* User:Jarekt  
]]

local core = {}

------------------------------------------------------------------------------
-- Based on frame structure create "args" table with all the input parameters.
-- All inputs are not not case-sensitive and underscored are treated the same 
-- way as speces. Input values are trimmed and empty string are converted to 
-- nils. If "lang" is not provided than we substitute user's prefered language.
function core.getArgs(frame)
	local function normalize_input_args(input_args, output_args)
		for name, value in pairs( input_args ) do 
			value = mw.text.trim(value) -- trim whitespaces from the beggining and the end of the string
			if value ~= '' then -- nuke empty strings
				if type(name)=='string' then 
					name = string.gsub( string.lower(name), ' ', '_')
				end
				output_args[name] = value
			end
		end
		return output_args
	end
	local args = {}
	args = normalize_input_args(frame:getParent().args, args)
	args = normalize_input_args(frame.args, args)
	if (args.lang and mw.language.isSupportedLanguage(args.lang)) then 
		args.lang = string.lower(args.lang)
	else
		args.lang = frame:callParserFunction("int","lang")  -- get user's chosen language
	end
	return args
end

------------------------------------------------------------------------------
--[[
Simplified code equivalent to https://commons.wikimedia.org/wiki/Template:LangSwitch

Example usage:
  text = langSwitch({en='text in english', pl='tekst po polsku'}, lang)

Inputs:
  1: args - table with translations by language
  2: lang - desired language (often user's native language)
]]
function core.langSwitch(args, lang)
	local langList = mw.language.getFallbacksFor(lang)
	table.insert(langList,1,lang)
	for i,language in ipairs(langList) do
		if args[language] then
			return args[language]
		end
	end
end

------------------------------------------------------------------------------
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to Module:Yesno
function core.yesno(val, default)
	if type(val) == 'boolean' then
		return val
	elseif type(val) == 'number' then
		if val==1 then 
			return true
		elseif val==0 then
			return false
		end
	elseif type(val) == 'string' then
	    val = mw.ustring.lower(val)  -- put in lower case
	    if val == 'no'  or val == 'n' or val == 'false' or val == '0' then
	        return false
	    elseif val == 'yes' or val == 'y' or val == 'true'  or val == '1' then
	        return true
	    end
    end
    return default
end

------------------------------------------------------------------------------
-- read Commons Data:SOMENAME.tab dataset and look for message identified by a 
-- "key" in a language "lang". See editAtWikidata as an example.
function core.formatMessage(dataset, key, lang)
	for _, row in pairs(mw.ext.data.get(dataset, lang).data) do
		local id, msg = unpack(row)
		if id == key then
			return mw.message.newRawMessage(msg):plain()
		end
	end
	error('Invalid message key "' .. key .. '"')
end

-------------------------------------------------------------------------------
-- Assembles the "Edit at Wikidata" pen icon and returns it as wikitext string.
-- Dependencies: Data:I18n/EditAt.tab
-------------------------------------------------------------------------------
function core.editAtWikidata(entityID, propertyID, lang)
	local msg  = core.formatMessage('I18n/EditAt.tab', 'EditAtWikidata', lang)
	local link = 'https://www.wikidata.org/wiki/' .. entityID .. (propertyID == "" and "" or ("#" .. propertyID))
	return " [[File:OOjs UI icon edit-ltr-progressive.svg |frameless |text-top |10px |alt="..msg.."|link="..link.."|"..msg.."]]"
end

-------------------------------------------------------------------------------
-- Assembles the "Edit at SDC" pen icon and returns it as wikitext string.
-- Dependencies: Data:I18n/EditAt.tab
-------------------------------------------------------------------------------
function core.editAtSDC(propertyID, lang)
	local msg  = core.formatMessage('I18n/EditAt.tab', 'EditAtSDC', lang)
	local link =  mw.title.getCurrentTitle():fullUrl() .. (propertyID == "" and "" or ("#" .. propertyID))
	return " [[File:OOjs UI icon edit-ltr-progressive.svg |frameless |text-top |10px |alt="..msg.."|link="..link.."|"..msg.."]]"
end

-------------------------------------------------------------------------------
--[[
This function returns a label translated to desired language, created based on wikidata
Code equivalent to require("Module:Wikidata label")._getLabel

Inputs:
	1: item - wikidata's item's q-id or entity class
	2: userLang - desired language of the label
]]
function core.getLabel(item, userLang) 
	local label, link
	-- build language fallback list
	local langList = mw.language.getFallbacksFor(userLang)
	table.insert(langList, 1, userLang) 
	-- get label
	for _, lang in ipairs(langList) do  -- loop over language fallback list looking for label in the specific language
		label = mw.wikibase.getLabelByLang(item, lang)
		if label then break end                    -- label found and we are done
	end	
	label = label or item -- fallback value
	-- get link
	for _, lang in ipairs(langList) do  -- loop over language fallback list looking for label in the specific language
		link =  mw.wikibase.getSitelink(item, lang .. 'wiki')
		if link then
			link = mw.ustring.format('w:%s:%s', lang, link)
			break
		end
	end
	link = link or 'd:'..item -- fallback value
	-- look for description
	local desc = mw.wikibase.getDescription(item)
	if desc then  -- add description if we have one
		desc  = mw.text.nowiki(desc) -- add description as hover text
		label = '<span title="' .. desc .. '">' .. label .. '</span>'
	end
   return '[['..link..'|'..label..']]'
end

-------------------------------------------------------------------------------
--[[
Core component of many "get property value" functions
Example: (core.parse_statements(entity:getBestStatements( prop ), nil) or {nil})[1] would 
return the first best statement
Inputs:
 1: statements - can be provided by:
   * entity:getBestStatements( prop )
   * entity:getAllStatements( prop )
   * mw.wikibase.getBestStatements( item, prop )
   * mw.wikibase.getAllStatements( item, prop )
 2: lang - language code (like "en"), if provided than item IDs will be 
     changed to a label
Output:
 * table of strings or nil
]]
function core.parseStatements(statements, lang)
	local output = {}
	for _, statement in ipairs(statements) do
		if (statement.mainsnak.snaktype == "value") and (statement.rank ~= 'deprecated')  then
			local val = statement.mainsnak.datavalue.value
			if val.id then 
				val = val.id
				if lang ~= nil then
					val = core.getLabel(val, lang)
				end
			elseif val.text then
				val = val.text
			elseif val.amount then
				val = tonumber(val.amount)
			end
			table.insert(output, val)
		end
	end
	if #output==0 then return nil end
	return output
end

return core
Cookies help us deliver our services. By using our services, you agree to our use of cookies.