Module:Authority control
Appearance
![]() | This Lua module is used on 961,229 pages. To avoid large-scale disruption and unnecessary server load, any changes to this module should first be tested in its /sandbox or /testcases subpages. The tested changes can then be added to this page in one single edit. Please consider discussing any changes on the talk page before implementing them. |
![]() | 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 uses one or more Wikidata properties; see § Parameters for details.
![]() | This module depends on the following other modules: |
This module contains the code of the {{Authority control}} template. See its documentation.
Parameters, Wikidata properties, and tracking categories
Script error: The function "docConfTable" does not exist.
Additional tracking categories
This module also implements the following hidden tracking categories:
- Category:Pages with red-linked authority control categories (8) – error category to identify missing categories
- Category:Wikipedia articles with deprecated authority control identifiers (0) – fix/migrate/remove deprecated IDs
- Category:Wikipedia articles with suppressed authority control identifiers (0) – tracking only (no error)
- Category:Pages using authority control with parameters (0) – migrate IDs to Wikidata if possible (no error)
- Category:VIAF not on Wikidata (0)
- Category:VIAF different on Wikidata (0)
- Category:Wikipedia articles with WorldCat-LCCN identifiers (0)
- Category:Wikipedia articles with WorldCat-VIAF identifiers (3)
Number of identifiers
- Category:AC with 0 elements (3)
- Category:AC with 25 elements (0)
- Category:AC with 26 elements (0)
- Category:AC with 27 elements (0)
- Category:AC with 28 elements (0)
- Category:AC with 29 elements (0)
- Category:AC with 30 elements (0)
- Category:AC with 31 elements (0)
- Category:AC with 32 elements (0)
- Category:AC with 33 elements (0)
- Category:AC with 34 elements (0)
- Category:AC with 35 elements (0)
- Category:AC with 36 elements (0)
- Category:AC with 37 elements (0)
- Category:AC with 38 elements (0)
- Category:AC with 39 elements (0)
- Category:AC with 40 elements (0)
- Category:AC with 41 elements (0)
- Category:AC with 42 elements (0)
- Category:AC with 43 elements (0)
- Category:AC with 44 elements (0)
- Category:AC with 45 elements (0)
See also
- m:Interwiki map – definition of global custom interwiki prefixes
function getCatForId( id )
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
if namespace == 0 then
return '[[Category:Wikipedia articles with ' .. id .. ' identifiers]]'
elseif namespace == 2 and not title.isSubpage then
return '[[Category:User pages with ' .. id .. ' identifiers]]'
else
return '[[Category:Miscellaneous pages with ' .. id .. ' identifiers]]'
end
end
function viafLink( id )
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://viaf.org/viaf/' .. id .. ' ' .. id .. ']' .. getCatForId( 'VIAF' )
end
function bneLink( id )
return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id=' .. id .. ' ' .. id .. ']'
end
function uscongressLink( id )
return '[http://bioguide.congress.gov/scripts/biodisplay.pl?index=' .. id .. ' ' .. id .. ']'
end
function naraLink( id )
return '[http://research.archives.gov/person/' .. id .. ' ' .. id .. ']'
end
function botanistLink( id )
id2 = mw.ustring.gsub(id, '%s', function(s) return mw.uri.encode(s, 'PATH') end)
return '[http://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation=' .. id2 .. ' ' .. id .. ']'
end
function mgpLink( id )
-- TODO Implement some sanity checking regex
return '[http://www.genealogy.ams.org/id.php?id=' .. id .. ' ' .. id .. ']'
end
function rslLink( id )
-- TODO Implement some sanity checking regex
return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request=' .. id .. '&CON_LNG=ENG ' .. id .. ']'
end
function leonoreLink( id )
-- Identifiants allant de LH/1/1 à LH/2794/54 (légionnaires)
-- Identifiants allant de C/0/1 à C/0/84 (84 légionnaires célèbres)
-- Identifiants allant de 19800035/1/1 à 19800035/385/51670 (légionnaires décédés entre 1954 et 1977, et quelques dossiers de légionnaires décédés avant 1954)
if not string.match( id, '^LH/%d%d?%d?%d?/%d%d?%d?$' ) and
not string.match( id, '^C/0/%d%d?$' ) and
not string.match( id, '^19800035/%d%d?%d?%d?/%d%d?%d?%d?%d?$' ) then
return false
end
return '[http://www.culture.gouv.fr/public/mistral/leonore_fr?ACTION=CHERCHER&FIELD_1=COTE&VALUE_1=' .. id .. ' ' .. id .. ']'
end
function sbnLink( id )
if not string.match( id, '^IT\\ICCU\\%d%d%d%d%d%d%d%d%d%d$' ) and not string.match( id, '^IT\\ICCU\\%u%u[%d%u]%u\\%d%d%d%d%d%d$' ) then
return false
end
return '[http://opac.sbn.it/opacsbn/opac/iccu/scheda_authority.jsp?bid=' .. id .. ' ' .. id .. ']'
end
function nkcLink( id )
return '[http://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica=' .. id .. '&CON_LNG=ENG ' .. id .. ']'
end
function nclLink( id )
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence=' .. id .. '&CON_LNG=ENG ' .. id .. ']'
end
function ndlLink( id )
return '[http://id.ndl.go.jp/auth/ndlna/' .. id .. ' ' .. id .. ']'
end
function sudocLink( id )
if not string.match( id, '^%d%d%d%d%d%d%d%d[%dxX]$' ) then
return false
end
return '[http://www.idref.fr/' .. id .. ' ' .. id .. ']'
end
function hlsLink( id )
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://www.hls-dhs-dss.ch/textes/f/F' .. id .. '.php ' .. id .. ']'
end
function lirLink( id )
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://www.e-lir.ch/e-LIR___Lexicon.' .. id .. '.450.0.html ' .. id .. ']'
end
function lccnLink( id )
local parts = splitLccn( id )
if not parts then
return false
end
id = parts[1] .. parts[2] .. append( parts[3], '0', 6 )
return '[http://id.loc.gov/authorities/names/' .. id .. ' ' .. id .. ']' .. getCatForId( 'LCCN' )
end
function mbLink( id )
-- TODO Implement some sanity checking regex
return '[//musicbrainz.org/artist/' .. id .. ' ' .. id .. ']' .. getCatForId( 'MusicBrainz' )
end
function splitLccn( id )
if id:match( '^%l%l?%l?%d%d%d%d%d%d%d%d%d?%d?$' ) then
id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )
end
if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then
return mw.text.split( id, '/' )
end
return false
end
function append(str, c, length)
while str:len() < length do
str = c .. str
end
return str
end
function isniLink( id )
id = validateIsni( id )
if not id then
return false
end
return '[http://isni-url.oclc.nl/isni/' .. id .. ' ' .. id:sub( 1, 4 ) .. ' ' .. id:sub( 5, 8 ) .. ' ' .. id:sub( 9, 12 ) .. ' ' .. id:sub( 13, 16 ) .. ']' .. getCatForId( 'ISNI' )
end
--Validate ISNI (and ORCID) and retuns it as a 16 characters string or returns false if it's invalid
--See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
function validateIsni( id )
id = id:gsub( '[ %-]', '' ):upper()
if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
if getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
return false
end
return id
end
--Returns the ISNI check digit isni must be a string where the 15 first elements are digits
function getIsniCheckDigit( isni )
local total = 0
for i = 1, 15 do
local digit = isni:byte( i ) - 48 --Get integer value
total = (total + digit) * 2
end
local remainder = total % 11
local result = (12 - remainder) % 11
if result == 10 then
return "X"
end
return tostring( result )
end
function orcidLink( id )
id = validateIsni( id )
if not id then
return false
end
id = id:sub( 1, 4 ) .. '-' .. id:sub( 5, 8 ) .. '-' .. id:sub( 9, 12 ) .. '-' .. id:sub( 13, 16 )
return '[http://orcid.org/' .. id .. ' ' .. id .. ']' .. getCatForId( 'ORCID' )
end
function gndLink( id )
return '[http://d-nb.info/gnd/' .. id .. ' ' .. id .. ']' .. getCatForId( 'GND' )
end
function selibrLink( id )
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://libris.kb.se/auth/' .. id .. ' ' .. id .. ']' .. getCatForId( 'SELIBR' )
end
function bnfLink( id )
--Add cb prefix if it has been removed
if not string.match( id, '^cb.+$' ) then
id = 'cb' .. id
end
return '[http://catalogue.bnf.fr/ark:/12148/' .. id .. ' ' .. id .. '] [http://data.bnf.fr/ark:/12148/' .. id .. ' (data)]' .. getCatForId( 'BNF' )
end
function bpnLink( id )
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://www.biografischportaal.nl/persoon/' .. id .. ' ' .. id .. ']' .. getCatForId( 'BPN' )
end
function ridLink( id )
return '[http://www.researcherid.com/rid/' .. id .. ' ' .. id .. ']' .. getCatForId( 'RID' )
end
function bibsysLink( id )
return '[http://ask.bibsys.no/ask/action/result?cmd=&kilde=biblio&cql=bs.autid+%3D+' .. id .. '&feltselect=bs.autid ' .. id .. ']' .. getCatForId( 'BIBSYS' )
end
function ulanLink( id )
return '[http://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid=' .. id .. ' ' .. id .. ']' .. getCatForId( 'ULAN' )
end
function nlaLink( id )
return '[http://nla.gov.au/anbd.aut-an' .. id .. ' ' .. id .. ']' .. getCatForId( 'NLA' )
end
function getIdsFromWikidata( item, property )
local ids = {}
if not item.claims[property] then
return ids
end
for _, statement in pairs( item.claims[property] ) do
table.insert( ids, statement.mainsnak.datavalue.value )
end
return ids
end
function matchesWikidataRequirements( item, reqs )
for _, group in pairs( reqs ) do
local property = 'p' .. group[1]
local qid = group[2]
if item.claims[property] ~= nil then
for _, statement in pairs ( item.claims[property] ) do
if statement.mainsnak.datavalue ~= nil then
if statement.mainsnak.datavalue.value['numeric-id'] == qid then
return true
end
end
end
end
end
return false
end
function createRow( id, label, rawValue, link, withUid )
if link then
if withUid then
return '* ' .. label .. ' <span class="uid">' .. link .. '</span>\n'
else
return '* ' .. label .. ' ' .. link .. '\n'
end
else
return '* <span class="error">The ' .. id .. ' id ' .. rawValue .. ' is not valid.</span>[[Category:Wikipedia articles with faulty authority control identifiers (' .. id .. ')]]\n'
end
end
--In this order: name of the parameter, label, propertyId in Wikidata, formatting function
local conf = {
{ 'VIAF', '[[Virtual International Authority File|VIAF]]', 214, viafLink },
{ 'LCCN', '[[Library of Congress Control Number|LCCN]]', 244, lccnLink },
{ 'ISNI', '[[International Standard Name Identifier|ISNI]]', 213, isniLink },
{ 'ORCID', '[[ORCID]]', 496, orcidLink },
{ 'GND', '[[Integrated Authority File|GND]]', 227, gndLink },
{ 'SELIBR', '[[LIBRIS|SELIBR]]', 906, selibrLink },
{ 'SUDOC', '[[Système universitaire de documentation|SUDOC]]', 269, sudocLink },
{ 'BNF', '[[Bibliothèque nationale de France|BNF]]', 268, bnfLink },
{ 'BPN', '[[Biografisch Portaal|BPN]]', 651, bpnLink },
{ 'RID', '[[ResearcherID]]', 0, ridLink },
{ 'BIBSYS', '[[BIBSYS]]', 1015, bibsysLink },
{ 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, ulanLink },
{ 'HDS', '[[Historical Dictionary of Switzerland|HDS]]', 902, hlsLink },
{ 'LIR', '[[Historical Dictionary of Switzerland#Lexicon_Istoric_Retic|LIR]]', 886, lirLink },
{ 'MBA', '[[MusicBrainz]]', 434, mbLink },
{ 'MGP', '[[Mathematics Genealogy Project|MGP]]', 549, mgpLink },
{ 'NLA', '[[National Library of Australia|NLA]]', 409, nlaLink },
{ 'NDL', '[[National Diet Library|NDL]]', 349, ndlLink },
{ 'NCL', '[[National Central Library|NCL]]', 1048, nclLink },
{ 'NKC', '[[National Library of the Czech Republic|NKC]]', 691, nkcLink },
{ 'Léonore', '[[:fr:Base Léonore|Léonore]]', 640, leonoreLink },
{ 'SBN', '[[Istituto Centrale per il Catalogo Unico|ICCU]]', 396, sbnLink },
{ 'RLS', '[[Russian State Library|RLS]]', 947, rslLink },
{ 'Botanist', '[[Author citation (botany)|Botanist]]', 428, botanistLink },
{ 'NARA', '[[National Archives and Records Administration|NARA]]', 1222, naraLink },
{ 'USCongress', '[[Biographical Directory of the United States Congress|US Congress]]', 1157, uscongressLink },
{ 'BNE', '[[Biblioteca Nacional de España|BNE]]', 950, bneLink },
}
-- Check that the Wikidata item has this property-->value before adding it
local reqs = {}
reqs['MBA'] = {
{ 106, 177220 }, -- occupation -> singer
{ 31, 177220 }, -- instance of -> singer
{ 106, 13385019 }, -- occupation -> rapper
{ 31, 13385019 }, -- instance of -> rapper
{ 106, 639669 }, -- occupation -> musician
{ 31, 639669 }, -- instance of -> musician
{ 106, 36834 }, -- occupation -> composer
{ 31, 36834 }, -- instance of -> composer
{ 106, 488205 }, -- occupation -> singer-songwriter
{ 31, 488205 }, -- instance of -> singer-songwriter
{ 106, 183945 }, -- occupation -> record producer
{ 31, 183945 }, -- instance of -> record producer
{ 106, 10816969 }, -- occupation -> club DJ
{ 31, 10816969 }, -- instance of -> club DJ
{ 106, 130857 }, -- occupation -> DJ
{ 31, 130857 }, -- instance of -> DJ
{ 106, 158852 }, -- occupation -> conductor
{ 31, 158852 }, -- instance of -> conductor
{ 31, 215380 }, -- instance of -> band
{ 31, 5741069 }, -- instance of -> rock band
}
local p = {}
function p.authorityControl( frame )
local parentArgs = {}
--Create rows
local elements = {}
--Wikidata fallback if requested
local item = mw.wikibase.getEntity()
if item ~= nil and item.claims ~= nil then
for _, params in pairs( conf ) do
if params[3] ~= 0 then
local val = parentArgs[params[1]]
if not val or val == '' then
local canUseWikidata = nil
if reqs[params[1]] ~= nil then
canUseWikidata = matchesWikidataRequirements( item, reqs[params[1]] )
else
canUseWikidata = true
end
if canUseWikidata then
local wikidataIds = getIdsFromWikidata( item, 'p' .. params[3] )
if wikidataIds[1] then
parentArgs[params[1]] = wikidataIds[1]
end
end
end
end
end
end
--Worldcat
if parentArgs['WORLDCATID'] and parentArgs['WORLDCATID'] ~= '' then
table.insert( elements, createRow( 'WORLDCATID', '', parentArgs['WORLDCATID'], '[http://www.worldcat.org/identities/' .. parentArgs['WORLDCATID'] .. ' WorldCat]', false ) ) --Validation?
elseif parentArgs['LCCN'] and parentArgs['LCCN'] ~= '' then
local lccnParts = splitLccn( parentArgs['LCCN'] )
if lccnParts then
table.insert( elements, createRow( 'LCCN', '', parentArgs['LCCN'], '[http://www.worldcat.org/identities/lccn-' .. lccnParts[1] .. lccnParts[2] .. '-' .. lccnParts[3] .. ' WorldCat]', false ) )
end
end
--Configured rows
for k, params in pairs( conf ) do
local val = parentArgs[params[1]]
if val and val ~= '' then
table.insert( elements, createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) )
end
end
local Navbox = require('Module:Navbox')
return Navbox._navbox( {
name = 'Authority control',
bodyclass = 'hlist',
group1 = '[[Authority control]]',
list1 = table.concat( elements )
} )
end
return p