Module:Wikidata label

Jump to navigation Jump to search

Documentation[edit source]

The module provides functions to fetch from wikidata labels, aliases or sitelinks for specific item in specific language. Each function can be called both from Lua and from Wikitext templates. Used by {{Label}} template.

getLabel[edit source]

This function returns a label translated to desired language and linking to desired project, created based on wikidata

Call from template

{{#invoke:Wikidata label|getLabel |item=<''item ID''> |lang=<''language''> |link=<''link type''> |capitalization=,''capitalization style''> }}

Calls from Lua

require('Module:Wikidata label')._getLabel( item, [lang] , [link_type] , [capitalization] )

Inputs
Name Function Default
item Wikidata item ID number in form "Q" + item number.
Also works with Wikidata properties if you use "P"+number.
(required field)
lang Language code (only needs to be provided if the language displayed is to be fixed and independent of the user’s preferences). {{int:lang}}
link link type:
wikipedia will try to link to Wikipedia (does not work for properties)
wikidata to Wikidata
commons to Commons (does not work for properties)
- means no link.
The code will try first the link of your choice then if not possible it will fallback and try linking to Wikipedia, and if that is not possible than to Wikidata.
wikipedia
capitalization can be:
uc: upper case
lc: lower case
ucfirst: upper case for the first letter
lcfirst: lower case for the first letter
none: to leave it as is
none

sitelinks[edit source]

This function returns a list of sitelinks for a single project organized by language

Call from template

{{#invoke:Wikidata label|sitelinks |item=<''item ID''> |project=<''project''> }}

Calls from Lua

require('Module:Wikidata label')._sitelinks( item, project )

Inputs
Name Function
item Wikidata item ID number in form "Q" + item number or entity class
project "wikipedia" (or "wiki"), "wikisource", "wikiquote", "wikibooks", "wikinews", "wikiversity", "wikivoyage", "wiktionary", etc.
Output
  • for sitelinks a comma separated list
  • for _sitelinks a lua table


aliases[edit source]

This function returns a list of aliases for a single language

Call from template

{{#invoke:Wikidata label|aliases |item=<''item ID''> |lang=<''language''> }}

Calls from Lua

require('Module:Wikidata label')._aliases( item, lang )

Inputs
Name Function
item Wikidata item ID number in form "Q" + item number or entity class
lang Language code
Output
  • for aliases a comma separated list
  • for _aliases a lua table

External links[edit source]

 

--[[  
  __  __           _       _      __        ___ _    _     _       _          _       _          _ 
 |  \/  | ___   __| |_   _| | ___ \ \      / (_) | _(_) __| | __ _| |_ __ _  | | __ _| |__   ___| |
 | |\/| |/ _ \ / _` | | | | |/ _ (_) \ /\ / /| | |/ / |/ _` |/ _` | __/ _` | | |/ _` | '_ \ / _ \ |
 | |  | | (_) | (_| | |_| | |  __/_ \ V  V / | |   <| | (_| | (_| | || (_| | | | (_| | |_) |  __/ |
 |_|  |_|\___/ \__,_|\__,_|_|\___(_) \_/\_/  |_|_|\_\_|\__,_|\__,_|\__\__,_| |_|\__,_|_.__/ \___|_|
                                                                                                   
This module is intended to be the engine behind "Template:Label".
Thic module was copied from Commons please ask for changes there.

Please do not modify this code without applying the changes first at "Module:Wikidata label/sandbox" and testing 
at "Module:Wikidata label/testcases".

Authors and maintainers:
* User:Jarekt - original version 

Dependencies:
* Module:Yesno - used only if "show_id" parameter present
]]

-- use different sitelink call depending if you already have an entity or not
local function getSitelink(item, entity, lang)
	if entity then -- if we have entity than use it
		return entity:getSitelink(lang .. 'wiki') 
	else -- if no entity than use different function
		return mw.wikibase.sitelink( item, lang .. 'wiki' )
	end
end

local p = {}

--[[
_getLabel

This function returns a label translated to desired language, created based on wikidata

Inputs:
	1: item - wikidata's item's q-code or entity class
	2: lang - desired language of the label
	3: link_type - link style. Possible values: "wikipedia", "Wikidata", "Commons", or "-" (no link)
	4: capitalization - can be "uc" (upper case), "lc" (lower case), "ucfirst" (upper case for the first letter), 
			"lcfirst" (lower case for the first letter)
 
Error Handling:
	Bad q-code will result in displayed error
]]
function p._getLabel(item, lang, link_type, capitalization, show_id)
	local entity, s, link, label, language

	-- clean up the input parameters
	if type(item)~='string' then -- "item" is not a q-code
		entity = item            -- "item" must be the entity
		item   = entity.id       -- look-up q-code
	elseif tonumber(item) then   -- if it is just the number than add "Q" in front
		item = 'Q'..item
	end
	item = string.gsub( string.upper(item), 'PROPERTY:P', 'P') -- make all the properties the same and capitalize
	
	-- build language fallback list
	lang = string.lower(lang) or 'en'
	local langList = mw.language.getFallbacksFor(lang)
	table.insert(langList, 1, lang)
	
	-- get label (visible part of the link)
	for _, language in ipairs(langList) do  -- loop over language fallback list looking for label in the specific language
		if entity then
			label = entity:getLabel(language)
		else
			label = mw.wikibase.getLabelByLang(item, language)
		end
		if label then break end                    -- label found and we are done
	end
	if not label then                              -- no labels found, so just show the q-code
		label = item
	elseif show_id then           -- add id
		local yesno = require('Module:Yesno')
		show_id = yesno(show_id,false)
		if show_id then 
			local id = mw.getCurrentFrame():preprocess( "{{int:parentheses|" .. item .."}}")
			local wordsep  = mw.message.new( "Word-separator" ):inLanguage(lang):plain()
			label = label .. wordsep .. "<small>" .. id .. "</small>"
		end
	end
	
	-- change capitalization of the label
	if capitalization=='ucfirst' then
		label = mw.language.new(lang):ucfirst(label)
	elseif capitalization=='lcfirst' then
		label = mw.language.new(lang):lcfirst(label)
	elseif capitalization=='uc' then
		label = mw.language.new(lang):uc(label)
	elseif capitalization=='lc' then
		label = mw.language.new(lang):lc(label)
	end

	-- create URL part of the link
	link_type = string.lower(link_type or '')
	local dLink = 'd:'..item; -- create fallback wikidata link
	if string.sub(item, 1, 1) == 'P' then
		dLink = 'd:Property:'.. item
	end
	if link_type=='-' then -- allow different link formats
		link = ''            -- no link
	elseif link_type=='wikidata' then
		link = dLink         -- link to wikidata
	elseif link_type=='wikidata talk' and string.sub(item, 1, 1)=='P' then
		link = 'd:Property talk:'.. item        -- link to wikidata property talk page
	elseif link_type=='wikidata talk' then
		link = 'd:Talk:'..item         -- link to wikidata talk page
	elseif link_type=='commons' or link_type=='commonscat' then
		-- For link_type=='commons' we try the following links (in that order): 
		--   1) sitelink to commons 
		--   2) "Commons Category" P373 property 
		--   3) "Commons Gallery"  P935 property
		-- Since most pages have a sitelink to commons we never have to call expensive mw.wikibase.getEntity
		-- For link_type=='commonscat' we try to maximize chances of commons link beeing a category, so we 
		--       try the following links (in that order): 
		--   1) sitelink to commons, which is kept if it points to a category
		--   2) "Commons Category" P373 property 
		--   3) sitelink to commons (which does not point to a category)
		--   4) "Commons Gallery"  P935 property
		-- Since most pages have a sitelink to commons we never have to call expensive mw.wikibase.getEntity
		local sLink = getSitelink(item, entity, 'commons')  -- look for sitelink to commons
		if sLink then 
			sLink = 'c:'..sLink
			if (link_type=='commons') or (link_type=='commonscat' and string.find( sLink, 'Category:')) then
				link = sLink
			end
		end
		if not link then -- try linking to P373 category
			-- this is potentially memory expensive operation
			entity = entity or mw.wikibase.getEntity(item); 
			assert(entity, "Item ID " .. item .. " is not valid")
			s = entity:getBestStatements( 'P373' )
			if s[1] and s[1].mainsnak.datavalue.value then 
				 link = 'c:Category:' .. s[1].mainsnak.datavalue.value
			end
		end
		link = link or sLink
		if not link then -- try linking to P935 gallery
			-- there is no need for mw.wikibase.getEntity(item) call since at this point it was already loded
			s = entity:getBestStatements( 'P935' )
			if s[1] and s[1].mainsnak.datavalue.value then 
				 link = s[1].mainsnak.datavalue.value
			end
		end
	end
	if not link then-- apply default "Wikipedia" link type
		for _, language in ipairs(langList) do 
			local sitelink = getSitelink(item, entity, language)
			if sitelink then 
				link = mw.ustring.format('w:%s:%s', language, sitelink)
				break 
			end
		end
	end
	link = link or dLink  -- no wiki sitelink, so link to wikidata
	
	-- return the results
	if link~='' then
		return mw.ustring.format('[[%s|%s]]', link, label) -- return link
	else
		return label -- return just a label
	end
end

--[[
getLabel
 
This function returns a label translated to desired language, created based on wikidata

Usage:
{{#invoke:Wikidata label|getLabel|item=Q...|lang=..|link_style=..|capitalization=..}}

Parameters
	1: wikidata's item's q-code (required)
	2: language (optional; default {{int:lang}} )
	3: link_style: "wikipedia" (default), "Wikidata", "Commons", or "-" (no link)
	4: capitalization - can be "uc", "lc", "ucfirst", "lcfirst"

Error Handling:
	Bad q-code will result in displayed error
]]
function p.getLabel(frame)
	local args = frame.args
	if not (args.lang and mw.language.isSupportedLanguage(args.lang)) then 
		args.lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language 
	end
	if (not args.link) or (mw.text.trim(args.link) == "") then
		args.link = "wikipedia"
	end
	if (not args.capitalization) or (mw.text.trim(args.capitalization) == "") then
		args.capitalization = "none"
	end
	args.item = mw.text.trim(args.item or '')
	return p._getLabel(args.item, args.lang, args.link, args.capitalization, args.show_id)
end

--[[
_sitelinks

This function returns a table of sitelinks for a single project organized by language

Inputs:
	1: item - wikidata's item's q-code or entity class
	2: project - "wikipedia", "wikisource", "wikiquote", "wikibooks", "wikinews", "wikiversity", 
			"wikivoyage", "wiktionary", "commons", "mediawiki", "wikispecies", "wikidata",  etc.

Output:
	Table with language fields
]]
function p._sitelinks( item, project )
	local entity, sitelink
	-- get entity
	if type(item)=='string' then -- "item" is a q-code
		entity = mw.wikibase.getEntity(item); 
	else
		entity = item            -- "item" is the entity
		item   = entity.id       -- look-up q-code
	end
	
	-- get project code
	local LUT = {wikipedia='wiki', commons='commonswiki', mediawiki='mediawikiwiki', wikispecies='specieswiki', wikidata='wikidatawiki'}
	project = string.lower(project)
	if LUT[project] then -- correct the project name
		project=LUT[project]
	end
	local n = string.len(project);
	local s ={}
	if entity and entity.sitelinks then 					  -- See if entity exists, and that it has sitelinks
		for _, sitelink in pairs(entity.sitelinks) do 				-- loop over all sitelinks
		  local site = sitelink.site
			local lang = mw.ustring.sub( site, 1, mw.ustring.len(site) - n  )  -- language part of the siteID
			local proj = mw.ustring.sub( site, mw.ustring.len(site) - n + 1 )  -- project part of the siteID
			if proj == project then -- proj matches desired "project"
				s[lang] = sitelink.title
			end
		end
	end
	return s
end

--[[
sitelinks

This function returns a comma separated list of sitelinks for a single project organized by language
Its main purpose is to help with testing of _sitelinks function.

Usage:
{{#invoke:Wikidata label|sitelinks|item=Q...|project=..}}

Inputs:
	1: item - wikidata's item's q-code or entity class
	2: project - "wikipedia" (or "wiki"), "wikisource", "wikiquote", "wikibooks", "wikinews", "wikiversity", "wikivoyage", "wiktionary", etc.

Output:
	comma separated list
]]
function p.sitelinks(frame)
	local sitelinks = p._sitelinks(frame.args.item, frame.args.project)
	local s = {}
	for i, j in pairs(sitelinks) do
		table.insert(s, i .. ':' .. j)
	end
	return table.concat(s, ', ')	
end

--[[
_aliases

This function returns a table of aliases for a single language

Inputs:
	1: item - wikidata's item's q-code or entity class
	2: lang - language code, like 'en' or 'de'

Output:
	Table of aliases
]]
function p._aliases( item, lang )
	local entity
	if type(item)=='string' then -- "item" is a q-code
		entity = mw.wikibase.getEntity(item); 
	else
		entity = item            -- "item" is the entity
		item   = entity.id       -- look-up q-code
	end
	local s = {}
	if entity and entity.aliases then						-- See if there is an entity and that is has aliases
		if entity.aliases[lang] then						-- See if it has English Aliases
			for i, j in pairs(entity.aliases[lang]) do		-- Make a loop around the English aliases
				table.insert(s, j.value)					-- Create a table of English aliases
			end
		end
	end
	return s
end

--[[
aliases

This function returns a comma separated list of aliases for a single language
Its main purpose is to help with testing of _aliases function.

Usage:
{{#invoke:Wikidata label|aliases|item=Q...|lang=..}}

Inputs:
	1: item - wikidata's item's q-code or entity class
	2: lang - language code, like 'en' or 'de'

Output:
	Comma separated list of aliases
]]
function p.aliases(frame)
	return table.concat(p._aliases(frame.args.item, frame.args.lang), ', ')	
end

return p