Taxonbar (edit • talk • history • links • /subpages • /doc • /doc edit • /sbox • /sbox diff • /test • Module:Taxonbar)

This module contains the code of {{Taxonbar}}. To use Taxonbar, follow instructions at Template:Taxonbar/doc.

Configuration

Parameters and databases are set by Module:Taxonbar/conf.

Taxon identifiers

Testcases

For testcases use: {{Taxonbar | from=QID}}

Purge server cache

Rhododendron maximum

Asclepias syriaca

Peach (Prunus persica)

Puma_(genus)

Dog (Canis lupus familiaris)

Eastern bluebird (Sialia sialis)

Honey bee (Apis)

Western honey bee (Apis mellifera)

Clipper butterfly (Parthenos sylvia)

Turkey tail (Trametes versicolor)

Button/portobello mushroom (Agaricus bisporus)


Module editing — to-do list

  • Improve documentation
  • Add parameters to remove individual identifiers from taxonbar. This could help the box from becoming two lines when one line is desired. Can be suppressed by setting equal to no (e.g. |eol=no). Should we suppress if set to blank (e.g. |eol=)?
  • Add support for parameters currently supported by {{Taxonbar}}. Someone want to double-check Module:Taxonbar/conf that we got them all?
  • Add documentation for grinurl=.
  • Continue to add support for new, useful parameters.
  • Add tracking for entries not on Wikidata? Suggest differences be resolved?
  • Program Module:Taxonbar to create it's own documentation table of parameters.
  • Program Module:Taxonbar to support disabled(hidden) databases which can shown when called.
  • Switch {{Taxonbar}} to Module:Taxonbar when it's ready and meets all needs.

See also


require('Module:No globals')

local conf = require( "Module:Taxonbar/conf" )

local function getIdsFromWikidata( item, property )
	local ids = {}
	if not item.claims[property] then
		return ids
	end
	for _, statement in pairs( item.claims[property] ) do
		if statement.mainsnak.datavalue then
			table.insert( ids, statement.mainsnak.datavalue.value )
		end
	end
	return ids
end

local function getLink( property, val )
	local link = ""
	if mw.ustring.find( val, '//' ) then
		link = val
	else
		if type(property) == 'number' then
			local entityObject = mw.wikibase.getEntityObject('P'..property)
			local dataType = entityObject.datatype
			if dataType == "external-id" then
				local formatterURL = entityObject:getBestStatements('P1630')[1]
				if formatterURL then link = formatterURL.mainsnak.datavalue.value end
			elseif dataType == "url" then
				local subjectItem = entityObject:getBestStatements('P1629')[1]
				if subjectItem then
					local officialWebsite = mw.wikibase.getEntityObject(subjectItem.mainsnak.datavalue.value.id):getBestStatements('P856')[1]
					if officialWebsite then	link = officialWebsite.mainsnak.datavalue.value end
				end
			elseif dataType == "string" then
				local formatterURL = entityObject:getBestStatements('P1630')[1]
				if formatterURL then
					link = formatterURL.mainsnak.datavalue.value
				else
					local subjectItem = entityObject:getBestStatements('P1629')[1]
					if subjectItem then
						local officialWebsite = mw.wikibase.getEntityObject(subjectItem.mainsnak.datavalue.value.id):getBestStatements('P856')[1]
						if officialWebsite then	link = officialWebsite.mainsnak.datavalue.value end
					end
				end
			end
		elseif type(property) == 'string' then
			link = property
		end
		link = mw.ustring.gsub(link, '$1', val)
	end
	link = mw.ustring.gsub(link, '^[Hh][Tt][Tt][Pp]([Ss]?)://', 'http%1://') -- fix wikidata URL
	val = mw.ustring.match(val, '([^=/]*)/?$') -- get display name from end of URL
	if mw.ustring.find( link, '//' ) then
		return '['..link..' '..val..']'
	elseif link == "" then
		return val
	else
		return '<span class="external">[['..link..'|'..val..']]</span>'
	end
end

local function createRow( id, label, rawValue, link, withUid )
	if link then
		local outStr = '*<span style="white-space:nowrap;">' .. label .. ' <span'
		if withUid then outStr = outStr..' class="uid"' end
		return outStr..'>' .. link .. '</span></span>\n'
	else
		return '* <span class="error">The identifier ' .. id .. ' ' .. rawValue .. ' is not valid.</span>\n'
	end
end

local function copyTable(inTable)
	if type(inTable) ~= 'table' then return inTable end
	local outTable = setmetatable({}, getmetatable(inTable))
	for key, value in pairs (inTable) do outTable[copyTable(key)] = copyTable(value) end
	return outTable
end

local p = {}

function p.authorityControlTaxon( frame )
	local parentArgs = copyTable(frame:getParent().args)
	local stringArgs = false
	local fromForCount, firstRow, rowCount = 1, 0, 0
	--Cleanup args
	for k, v in pairs( frame:getParent().args ) do
		if type(k) == 'string' then
			--make args case insensitive
			local lowerk = mw.ustring.lower(k)
			if not parentArgs[lowerk] or parentArgs[lowerk] == '' then
				parentArgs[lowerk] = v
				parentArgs[k] = nil
			end
			--remap abc to abc1
			if not mw.ustring.find(lowerk,"%d$") then --if no number at end of param
				if not parentArgs[lowerk..'1'] or parentArgs[lowerk..'1'] == '' then
					parentArgs[lowerk..'1'] = v
					parentArgs[lowerk] = nil
				end
			end
			if v and v ~= '' then
				--find highest from param
				if mw.ustring.sub(lowerk,1,4) == "from" then
					local fromNumber = tonumber(mw.ustring.sub(lowerk,5,-1))
					if fromNumber and fromNumber >= fromForCount then fromForCount = fromNumber end
				elseif mw.ustring.sub(lowerk,1,3) == "for" then
					local forNumber = tonumber(mw.ustring.sub(lowerk,4,-1))
					if forNumber and forNumber >= fromForCount then fromForCount = forNumber end
				elseif mw.ustring.lower(v) ~= 'no' and lowerk ~= 'for' then
					stringArgs = true
				end
			end
		end
	end

	--Setup navbox
	local navboxParams = {
		name  = 'Taxonbar',
		bodyclass = 'hlist',
		listclass = '',
		groupstyle = 'text-align: left;',
	}

	for f = 1,fromForCount,1
	do
		local elements, title = {}, {}
		--cleanup parameters
		if parentArgs['from'..f] == '' then parentArgs['from'..f] = nil end
		if parentArgs['for'..f] == '' then parentArgs['for'..f] = nil end
		--remap aliases
		for _, a in pairs( conf.aliases ) do
			local alias, name = mw.ustring.lower(a[1]), mw.ustring.lower(a[2])
			if parentArgs[alias..f] and not parentArgs[name..f] then
				parentArgs[name..f] = parentArgs[alias..f]
				parentArgs[alias..f] = nil
			end
		end
		--Fetch Wikidata item
		local item = mw.wikibase.getEntity(parentArgs['from'..f])
		local label = item and item:getLabel()
		if label and label ~= '' then
			title = mw.title.new(label)
			if not title then title = mw.title.getCurrentTitle() end
		else
			title = mw.title.getCurrentTitle()
		end
		
		if (not parentArgs['wikidata'..f] or parentArgs['wikidata'..f] == '') and (title.namespace == 0) then
			if parentArgs['from'..f] then parentArgs['wikidata'..f] = parentArgs['from'..f] elseif item then parentArgs['wikidata'..f] = item.id end
		end
		if title.namespace == 0 or stringArgs then --Only in the main namespace or if there are manual overrides
			local sourcesFound = false
			for _, params in pairs( conf.databases ) do
				params[1] = mw.ustring.lower(params[1])
				--Wikidata fallback if requested
				if (item ~= nil and item.claims ~= nil) and params[3] ~= 0 and (not parentArgs[params[1]..f] or parentArgs[params[1]..f] == '') then
					local wikidataIds = getIdsFromWikidata( item, 'P' .. params[3] )
					if wikidataIds[1] then
						parentArgs[params[1]..f] = wikidataIds[1]
					end
				end
				local val = parentArgs[params[1]..f]
				if val and val ~= '' and mw.ustring.lower(val) ~= 'no' and params[3] ~= 0 then
					table.insert( elements, createRow( params[1], params[2] .. ':', val, getLink( params[3], val ), true ) )
					if params[1] ~= 'wikidata' then sourcesFound = true end
				end
			end
			
			--Generate navbox title
			
			if sourcesFound then
				rowCount = rowCount + 1
				if firstRow == 0 then firstRow = f end
				if parentArgs['for'..f] and parentArgs['for'..f] ~= '' then
					navboxParams['group'..f] = "''" .. parentArgs['for'..f] .. "''"
				else
					navboxParams['group'..f] = ""
				end
				navboxParams['list'..f] = table.concat( elements )
			end
		end
	end
	
	if rowCount > 0 then
		local Navbox = require('Module:Navbox')
		if rowCount > 1 then
			navboxParams['title'] = "[[Help:Taxon identifiers|Taxon identifiers]]"
			--add missing names
			for f = 1,fromForCount,1
			do
				if navboxParams['group'..f] == "" then
					navboxParams['group'..f] = "''" .. mw.wikibase.getEntity(parentArgs['wikidata'..f]):getLabel().."''"
				end
			end
			if rowCount > 2 then
				navboxParams['navbar'] = 'plain'
			else
				navboxParams['state'] = 'off'
				navboxParams['navbar'] = 'off'
			end
		else
			navboxParams['group'..firstRow] = '[[Help:Taxon identifiers|Taxon identifiers]]<br />' .. navboxParams['group'..firstRow]
		end
		return Navbox._navbox(navboxParams)
	else
		return ""
	end
end

return p