Module:Core
Lua
Code​Discussion​Edit​History​Links​Link count​Subpages:​Documentation​Tests​Results​Sandbox​Live codeAll modules
This module is rated as ready for general use. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing.
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing.
This module is intended as collection of core functions shared among several Lua modules creating infobox templates on Commons. It is used by
Please do not modify or add to without discussing it first.
Translations of "edit at Wikidata" and "edit at SDC" from Data:I18n/EditAt.tab
Code
--[[ __ __ _ _ ____ | \/ | ___ __| |_ _| | ___ _ / ___|___ _ __ ___ | |\/| |/ _ \ / _` | | | | |/ _ (_) | / _ \| '__/ _ \ | | | | (_) | (_| | |_| | | __/_| |__| (_) | | | __/ |_| |_|\___/ \__,_|\__,_|_|\___(_)\____\___/|_| \___| Core is a meta-module that consists of common and useful Lua functions that can be used in many Lua scripts. It was writen as a core of several Lua modules for creating file infobox templates on Commons. Many of the functionsare bare-bones versions of full functions found in other modules.
Authors and maintainers:* User:Jarekt ]]
local core = {}​
------------------------------------------------------------------------------​--[[​Based on frame structure create "args" table with all the input parameters: * table keys - equivalent to template parameters are converted to lower case so they will not be case-sensitive. Also underscored are treated the same way as speces. * table values - input values are trimmed (whitespaces removed from the beggining and the end) and empty string are converted to nils. If "lang" is not provided than we substitute user's prefered language.
This function collects inputs from both frame and frame's parent. See https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#frame:getParent .If both structures have the same field than value from "frame" takes priority.
Inputs: 1) frame - frame objects see below for details https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#frame-object​
See also: Module:Arguments on enWiki - which is much larger single purpose module]]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) Outputs: 1: label - returned label 2: lang - language of the label (langSwitchWithLang only)]]function core​.​langSwitchWithLang​(​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], language end endend
function core.langSwitch(args, lang) local label, lang = core​.​langSwitchWithLang​(​args​, lang) return label​end​
------------------------------------------------------------------------------​--[[​display a language followed by a message. Like "English: Hello" with extensive HTML markingCode equivalent to https://commons.wikimedia.org/wiki/Template:Description Inputs: 1) text_lang - language code for the above text, also used as a name of the CSS formating class 2) text - description text to display 3) args - additional optional arguments. Numbers in perenthesis are parameter numbers in the original template. * hover - (3) hover aka mouseover aka tooltip text * lang_tag - (4) standard code for lang tag in HTML (optional, default is same as text_lang) * ext - (5) extension text shown after the language name before colon (optional, default is empty) * inline - Optional, default is false. When set to true, forces the template to be displayed inline, so that it does not break the current paragraph (that makes possible to put several descriptions side by side on a single line) ]]function core​.​langWrapper​(​text_lang​, text, args) local dir, space, colon, lang_name, hover local inline = core​.​yesno​(​args​.​inline​, false) and 'inline' or nil if mw​.​language​.​isKnownLanguageTag​(​text_lang​) then -- supported language local langObj = mw.language.new( text_lang ) dir = langObj:getDir() -- text direction space = mw.message.new( "Word-separator" ):​inLanguage​(​text_lang​):​plain​() colon = mw.message.new( "Colon" ):​inLanguage​(​text_lang​):​plain​() hover = mw​.​language​.​fetchLanguageName​( text_lang, args.user_lang or 'en') lang_name = mw​.​language​.​fetchLanguageName​( text_lang, text_lang) lang_name = langObj​:​ucfirst​(​lang_name​) else -- unsuported language local RTL_LUT = {['fa-af']=1, prd=1, ydd=1} dir = (​RTL_LUT​[​text_lang​]​==​1 or text_lang:gsub('-arab', '')~=text_lang) and 'rtl' or 'ltr' space = ' ' colon = ':' hover = args.hover lang_name = text_lang or 'Unknown' end lang_name = args.lang_name or lang_name-- user provided args.lang_name takes presedent lang_name = '<b>' .. lang_name .. (args.ext or '') .. colon .. '</b>' -- create HTML local ltag = mw​.​html​.​create​(​'span'​) -- bold language name string :addClass('language') -- class: "language" :addClass(text_lang) -- class: "en", "de" etc. :attr('title', hover) -- add hover aka mouseover aka tooltip text :wikitext(lang_name) local dtag = mw.html.create('div') :​addClass​(​'description'​) -- div.description is tracked by mw:Extension:CommonsMetadata :​addClass​(​'mw-content-'​..​dir​) -- mw-content-rtl and mw-content-ltr are defined in mediawiki-code (https://gerrit.wikimedia.org/r/c/mediawiki/core/+/208332) :addClass(text_lang) -- not sure where "en", "de" etc. are defined :attr('dir', dir) :attr('lang', text_lang) :css('display', inline) :wikitext(tostring(ltag) .. space .. text) return tostring​(​dtag​)​end​
------------------------------------------------------------------------------​--[[​Function allowing for consistent treatment of boolean-like wikitext input.Inputs: 1) val - value to be evaluated, outputs as a function of values: true : true (boolean), 1 (number), or strings: "yes", "y", "true", "1" false : false (boolean), 0 (number), or strings: "no", "n", "false", "0" 2) default - value to return otherwiseSee Also: It works similarly to Module:Yesno​]]​function core.yesno(val, default) if type(val) == 'boolean' then return val elseif type(val) == 'number' then val = tostring(val) end if type(val) == 'string' then local LUT = { yes=true , y=true , ['true'] =true , t=true , ['1']=true , on =true, no =false, n=false, ['false']=false, f=false, ['0']=false, off=false } val = LUT​[​mw​.​ustring​.​lower​(​val​)] -- put in lower case if (val~=nil) then return val 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 for an example. It uses​https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.ext.data​
Inputs: 1) dataset - name of commons page in "data" namespace. for example "I18n/EditAt.tab" for c:Data:I18n/EditAt.tab 2) key - which message to pull 3) lang - desired language of the messageOutput: message as a string]]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 with a link to Wikidata page or specific property and returns it as wikitext string.Inputs: 1) entityID - wikidata entity object for a given page (output of wikibase.getEntity( id )) 2) propertyID - string like 'P31' so the link will point to that specific property. Use "" to link to the whole page. 3) lang - language of the "Edit at Wikidata" message​Dependencies: Data:I18n/EditAt.tab​See Also: en:Module:EditAtWikidata​]]​-------------------------------------------------------------------------------​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 "&nbsp;[[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 with a link to a property in SDC part of the current file page, and returns it as wikitext string.Inputs: 2) propertyID - string like 'P31' so the link will point to that specific property. Use 'ooui-php-4' to link to the label section. 3) lang - language of the "Edit at Wikidata" message​Dependencies: Data:I18n/EditAt.tab​See Also: en:Module:EditAtWikidata​]]​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 "&nbsp;[[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 wikidataCode 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" functionsExample: (core.parse_statements(entity:getBestStatements( prop ), nil) or {nil})[1] would return the first best statementInputs: 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 labelOutput: * 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 outputend
return core
Last edited on 8 March 2021, at 04:29
Wikimedia Commons
Files are available under licenses specified on their description page. All structured data from the file namespace is available under the Creative Commons CC0 License; all unstructured text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and the Privacy Policy.
Privacy policy
Terms of Use
Desktop
HomeRandom Nearby Log in Settings DonateAbout Wikimedia CommonsDisclaimers
LanguageWatchEdit