Module:Core: Difference between revisions
From Neodyland Wiki
More actions
add getLabel function |
add parseStatements function |
||
| Line 23: | Line 23: | ||
local function normalize_input_args(input_args, output_args) | local function normalize_input_args(input_args, output_args) | ||
for name, value in pairs( input_args ) do | for name, value in pairs( input_args ) do | ||
value = | value = mw.text.trim(value) -- trim whitespaces from the beggining and the end of the string | ||
if value ~= '' then -- nuke empty strings | if value ~= '' then -- nuke empty strings | ||
if type(name)=='string' then | if type(name)=='string' then | ||
| Line 45: | Line 45: | ||
------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ||
-- code equivalent to https://commons.wikimedia.org/wiki/Template:LangSwitch | --[[ | ||
function core.langSwitch( | 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) | local langList = mw.language.getFallbacksFor(lang) | ||
table.insert(langList,1,lang) | table.insert(langList,1,lang) | ||
for i,language in ipairs(langList) do | for i,language in ipairs(langList) do | ||
if | if args[language] then | ||
return | return args[language] | ||
end | end | ||
end | end | ||
| Line 113: | Line 122: | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
function | --[[ | ||
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 | local label, link | ||
-- build language fallback list | -- build language fallback list | ||
local langList = mw.language.getFallbacksFor(userLang) | local langList = mw.language.getFallbacksFor(userLang) | ||
table.insert(langList, 1, 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 | for _, lang in ipairs(langList) do -- loop over language fallback list looking for label in the specific language | ||
label = mw.wikibase.getLabelByLang( | label = mw.wikibase.getLabelByLang(item, lang) | ||
if label then break end -- label found and we are done | if label then break end -- label found and we are done | ||
end | 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 | for _, lang in ipairs(langList) do -- loop over language fallback list looking for label in the specific language | ||
link = mw.wikibase.getSitelink( | link = mw.wikibase.getSitelink(item, lang .. 'wiki') | ||
if link then | if link then | ||
link = mw.ustring.format('w:%s:%s', lang, link) | link = mw.ustring.format('w:%s:%s', lang, link) | ||
break | break | ||
end | end | ||
end | end | ||
link | link = link or 'd:'..item -- fallback value | ||
label = label | -- 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 | end | ||
return core | return core | ||
Revision as of 04:33, 11 February 2021
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