Module:Wikidata label

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua
CodeDiscussionEditHistoryNo test API DocumentationSubpagesLinksTestsResultsSandbox All modules

This module returns a link to the Wikipedia article in a chosen language from a Wikidata entity ID. The text of the link will be the Wikidata label in that language.

For the use in wikitext, see {{Label}}.

Documentation

_getLabel

_getLabel( item, [ lang] , [ link_type] , [ capitalization ] )

You must provide item that must be a valid Wikidata entity Q-code. An example of Q-code is Q47674.

As default is assumed the user language, or lang if specified. An example of language is en.

As default the links points to Wikipedia. To change the project, change link_type. Accepted values: wikidata, commons or - for no links.

Examples

In order to have this label in a variable:

Universe

This is the source code:

require wikidata_label = require('Module:Wikidata label')._getLabel

local label = wikidata_label('Q1')

Code

--[[  
  __  __           _       _      __        ___ _    _     _       _          _       _          _ 
 |  \/  | ___   __| |_   _| | ___ \ \      / (_) | _(_) __| | __ _| |_ __ _  | | __ _| |__   ___| |
 | |\/| |/ _ \ / _` | | | | |/ _ (_) \ /\ / /| | |/ / |/ _` |/ _` | __/ _` | | |/ _` | '_ \ / _ \ |
 | |  | | (_) | (_| | |_| | |  __/_ \ V  V / | |   <| | (_| | (_| | || (_| | | | (_| | |_) |  __/ |
 |_|  |_|\___/ \__,_|\__,_|_|\___(_) \_/\_/  |_|_|\_\_|\__,_|\__,_|\__\__,_| |_|\__,_|_.__/ \___|_|
                                                                                                   
This module is intended to be the engine behind "Template:Label".

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 
]]

-- 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)
	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
	end
	
	-- 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
	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.upper(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=='commons' then
		link = getSitelink(item, entity, 'commons')  -- look for sitelink to commons
		if link then 
			link = 'c:'..link
		else -- try linking to P373 category
			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
		if not link then -- try linking to P935 gallery
			s = entity:getBestStatements( 'P935' )
			if s[1] 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 entity then label = label .. '_'	end -- this line is uncommented if it is needed for debugging
	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)
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