|
|
(5 intermediate revisions by 3 users not shown) |
Line 1: |
Line 1: |
| --[[ | | require('strict') |
| __ __ _ _ _ _ _ _ _ _ _
| | local p = {} |
| | \/ | ___ __| |_ _| | ___ _ / \ _ _| |_| |__ ___ _ __(_) |_ _ _ ___ ___ _ __ | |_ _ __ ___ | |
| | local configfile = 'Module:Authority control/config' -- default configuation module |
| | |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \| | | | __| '_ \ / _ \| '__| | __| | | | / __/ _ \| '_ \| __| '__/ _ \| |
| | local arg = mw.getCurrentFrame().args.config |
| | | | | (_) | (_| | |_| | | __/_ / ___ \ |_| | |_| | | | (_) | | | | |_| |_| | | (_| (_) | | | | |_| | | (_) | |
| | if arg and arg~='' then |
| |_| |_|\___/ \__,_|\__,_|_|\___(_)_/ \_\__,_|\__|_| |_|\___/|_| |_|\__|\__, | \___\___/|_| |_|\__|_| \___/|_|
| | configfile = 'Module:Authority control/config/' .. arg |
| |___/
| | end |
| This module is intended to be the engine behind "Template:Authority control".
| | local config |
| | if mw.title.new(configfile).exists then |
| | config = mw.loadData(configfile) |
| | else |
| | return error('Invalid configuration file',0) |
| | end |
| | local title = mw.title.getCurrentTitle() |
| | local namespace = title.namespace |
| | local testcases = title.subpageText == config.i18n.testcases |
|
| |
|
| Please do not modify this code without applying the changes first at "Module:Authority control/sandbox" and testing
| | local function needsAttention(sortkey) |
| at "Module:Authority control/testcases".
| | return '[[' .. config.i18n.category .. ':' .. config.i18n.attentioncat .. '|' .. sortkey .. title.text .. ']]' |
| | end |
|
| |
|
| Authors and maintainers:
| | local function addCat(cat,sortkey) |
| * User:Jarekt - original version
| | if cat and cat ~= '' and (namespace == 0 or namespace == 14 or testcases) then |
| | | local redlinkcat = '' |
| ]]
| | if testcases == false and mw.title.new(cat, 14).exists == false then |
| | | redlinkcat = needsAttention('N') |
| local properties = require('Module:Authority control/conf') | | end |
| local core = require('Module:Core')
| | if sortkey then |
| | | cat = '[[' .. config.i18n.category .. ':'..cat..'|' .. sortkey .. title.text .. ']]' |
| -- ==================================================
| | else |
| -- === Internal functions ===========================
| | cat = '[[' .. config.i18n.category .. ':'..cat..']]' |
| -- ==================================================
| |
| | |
| local function getSitelink(item, lang)
| |
| -- get item's siteling in specific language
| |
| local langList = mw.language.getFallbacksFor(lang)
| |
| table.insert(langList, 1, lang)
| |
| for _, language in ipairs(langList) do
| |
| local sitelink = mw.wikibase.sitelink( item, language .. 'wiki' ) | |
| if sitelink then | |
| return 'w:'.. language ..':'.. sitelink | |
| end | | end |
| | cat = cat .. redlinkcat |
| | return cat |
| | else |
| | return '' |
| end | | end |
| return nil
| |
| end | | end |
|
| |
|
| -- ==================================================
| | local function getCatForId(id,faulty) |
| local function getIdentifierNameLink( lang, item1, item2, label ) | | local cat = string.format( |
| -- Identifier names, like VIAF, LCCN, ISNI, need to be linked to the articles about them if possible
| | config.i18n.cat, |
| -- Alternativly they can be linked to the articles for institutions that issue them
| | (faulty and config.i18n.faulty..' ' or '') .. id |
| local id_name_URL = nil | | ) |
| -- 1) try wikipedia sitelink for the identifier in users language and in English | | return addCat(cat) |
| if item1 and item1 ~='' then
| | end |
| id_name_URL = getSitelink(item1, lang)
| | |
| | local function getIdsFromWikidata(qid,property) |
| | local function getquals(statement,qualid) |
| | if statement.qualifiers and statement.qualifiers['P'..qualid] then |
| | return mw.wikibase.renderSnak(statement.qualifiers['P'..qualid][1]) |
| | else |
| | return false |
| | end |
| end | | end |
| -- 2) try wikipedia sitelink for the issuedBy property in users language and in English | | local ids = {} |
| if id_name_URL==nil and item2 and item2 ~='' then -- if no link than | | if qid then |
| id_name_URL = getSitelink(item2, lang) | | for _, statement in ipairs(mw.wikibase.getBestStatements(qid,property)) do |
| end
| | if statement.mainsnak.datavalue then |
| -- 3) if still no links than link to wikidata
| | local val = statement.mainsnak.datavalue.value |
| if id_name_URL then
| | if val then |
| return string.format("[[%s|%s]]", id_name_URL, label) -- link to wikipedia
| | local namedas = getquals(statement,1810) or getquals(statement,742) or '' |
| else
| | table.insert(ids,{id=val,name=namedas}) |
| return string.format("[[d:%s|%s]]", item1, label) -- link to wikidata
| | end |
| | end |
| | end |
| end | | end |
| | return ids |
| end | | end |
|
| |
|
| -- ==================================================
| | local _makelink = function(conf,val,nextid,qid) --validate values and create a link |
| -- Create link to a single identifier
| | local function tooltip(text,label) |
| -- INPUTS:
| | if label and label~='' then |
| -- * val - value of the identifier
| | return mw.getCurrentFrame():expandTemplate{title = "Tooltip", args = {text,label}} |
| -- * URL_format - string used to create URL
| | else |
| -- * params - additional parameters related to this type of identifiers. Single item from "conf"
| | return text |
| -- * color - color of the link
| | end |
| local function getIdentifierValLink(val, URL_format, params, color) | |
| if not val or val=='' then
| |
| return '' | |
| end | | end |
| -- check if identifier is in the right format | | local link |
| local mismatchStr = '' | | if nextid==1 then |
| local val_ = val:gsub( ' ', '' ) -- remove spaces
| | if conf.prefix then |
| if (params.regexp and not val:match( params.regexp )) then
| | link = '*' .. conf.prefix .. '\n**' |
| mismatchStr = string.format("<span style=\"color:red\">[does not match %s pattern]</span>", params.regexp) | | else |
| elseif (params.verify) then -- check if special "Verify" function is present | | link = '*' |
| mismatchStr = params.verify(val_) -- add error message if any | | end |
| | else |
| | link = '\n**' |
| end | | end |
| -- identifier_value_URL | | local valid_value = false |
| local val_URL = URL_format:gsub('$1', val_)-- URL part of the link for the identifier value
| | if conf.customlink then -- use function to validate and generate link |
| if color~="blue" then
| | local label = nextid>1 and nextid |
| val = string.format('<span style=\"color:%s\">%s</span>', color, val)
| | local newlink= require(config.auxiliary)[conf.customlink](val.id,label) |
| end
| | if newlink then |
| return string.format("<span class=\"plainlinks\">[%s %s]</span>%s", val_URL, val, mismatchStr) -- link to the identifier's external website | | link = link .. newlink |
| end
| | valid_value = true |
| | | end |
| -- ==================================================
| | else |
| -- Convert between 2 formats of LCCN: "n/79/63767" -> "n79063767"
| | if conf.pattern then -- use pattern to determine validity if defined |
| -- "n/79/63767" format was used as input by {{Authority Control}} templates
| | valid_value = string.match(val.id,'^'..conf.pattern..'$') |
| -- "n79063767" format is used by wikidata
| | elseif conf.patterns then |
| local function fixLCCN(id)
| | for _,pattern in ipairs(conf.patterns) do |
| if id then
| | valid_value = val.id:match('^'..pattern..'$') |
| local a, b, c = string.match(id, "([%a%d]*)/([%a%d]*)/([%a%d]*)") | | if valid_value then break end |
| if c then | | end |
| local pad = 6 - string.len(c) | | elseif conf.valid then -- otherwise use function to determine validity |
| if pad > 0 then | | valid_value = require(config.auxiliary)[conf.valid](val.id) |
| c = string.rep("0", pad)..c | | else -- no validation possible |
| | valid_value = val.id |
| | end |
| | if valid_value then |
| | local newlink |
| | local label = conf.label |
| | if not label or nextid>1 then |
| | label = tostring(nextid) |
| | end |
| | if conf.link then |
| | valid_value = valid_value:gsub('%%', '%%%%') |
| | newlink = '[' .. mw.ustring.gsub(conf.link,'%$1',valid_value) .. ' ' .. label .. ']' |
| | else |
| | newlink = valid_value |
| end | | end |
| id = a..b..c | | link = link .. '<span class="uid">'..tooltip(newlink,val.name)..'</span>' |
| end | | end |
| end | | end |
| return id | | if valid_value then |
| end -- fixLCCN
| | link = link .. getCatForId(conf.category or conf[1]) |
| | |
| -- ==================================================
| |
| -- Verify last "check" digit is correct. ISNI and several other
| |
| -- identifiers use last digit as a verification digit
| |
| local function verifyLastDigit( id )
| |
| local total = 0
| |
| for i = 1, #id-1 do
| |
| local digit = id:byte( i ) - 48 --Get integer value
| |
| total = (total + digit) * 2
| |
| end
| |
|
| |
| --local remainder = total % 11
| |
| local lastDigit = tostring((12 - total % 11) % 11)
| |
| if lastDigit == '10' then
| |
| lastDigit = "X"
| |
| end
| |
|
| |
| if (lastDigit == string.sub( id, -1)) then
| |
| return ''
| |
| else | | else |
| return "<span style=\"color:red\">[last digit should be " .. lastDigit .. "]</span>" | | --local preview = require("Module:If preview") |
| | local wdlink = qid and '[[:wikidata:' .. qid .. '#P' .. conf.property .. ']]' or '' |
| | local tooltip = string.format( |
| | config.i18n.idnotvalid, |
| | conf[1], |
| | val.id |
| | ) |
| | link = link .. '[[File:' .. config.i18n.warningicon .. '|20px|frameless|link=' .. wdlink .. '|' .. tooltip .. '.]]' |
| | if conf.errorcat then |
| | link = link .. addCat(conf.errorcat) |
| | else |
| | link = link .. getCatForId(conf.category or conf[1],true) |
| | end |
| | link = link .. addCat(config.i18n.allfaultycat,conf[1])-- .. preview._warning({'The '..conf[1]..' id '..val..' is not valid.'}) |
| end | | end |
| | return link |
| end | | end |
|
| |
|
| -- ================================================== | | --[[==========================================================================]] |
| -- === Settings =====================================
| | --[[ Main ]] |
| -- ==================================================
| | --[[==========================================================================]] |
| -- In order to add a new identifier associated with Wikidata property do the following | | function p.authorityControl(frame) |
| -- 1) go to [[Template:Authority control/IdentifierList]] and verify that the property number is on the list, if not than edit the page to add it
| | local function resolveQID(qid) |
| -- 2) copy code generated at [[Template:Authority control/IdentifierList]] to protected [[Module:Authority control/conf]] | | if qid then |
| -- 3) add the property to the "conf" list below
| | qid = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '') |
| | | if mw.wikibase.isValidEntityId(qid) and mw.wikibase.entityExists(qid) then |
| -- load 'Module:Authority control/conf' which holds hardwired data derived from Wikidata's properties of
| | local sitelink = mw.wikibase.getSitelink(qid) |
| -- properties
| | if sitelink then |
| | | return mw.wikibase.getEntityIdForTitle(sitelink) or mw.wikibase.getEntity(qid).id |
| --conf holds list of identifiers to be displayed
| | end |
| local conf = {
| | return mw.wikibase.getEntity(qid).id |
| -- people
| | end |
| {label='VIAF' , property='P214' , lang='' , regexp='^%d+$' },
| | end |
| {label='ISNI' , property='P213' , lang='' , regexp='^%d%d%d%d %d%d%d%d %d%d%d%d %d%d%d[%dX]$', verify=verifyLastDigit },
| |
| {label='ORCID' , property='P496' , lang='' , regexp='^0000%-000[1-3]%-%d%d%d%d%-%d%d%d[%dX]$' },
| |
| {label='ULAN' , property='P245' , lang='' , regexp='^500%d%d%d%d%d%d$' }, -- 'Union List of Artist Names' by Getty Research Institute
| |
| {label='ResearcherID', property='P1053', lang='' , regexp='^[A-Z]{1,3}-\d{4}-(19|20)\d\d$' },
| |
| {label='LCCN' , property='P244' , lang='en', regexp='^[ns][broshj]?%d%d%d%d%d%d%d%d%d?%d?$' }, -- Library of Congress Authorities
| |
| {label='GND' , property='P227' , lang='de', regexp='^[%dX%-]+$'},
| |
| {label='SELIBR' , property='P906' , lang='se', regexp='^%d+$' }, -- National Library of Sweden
| |
| {label='SUDOC' , property='P269' , lang='fr', regexp='^%d%d%d%d%d%d%d%d[%dxX]$' },
| |
| {label='BNF' , property='P268' , lang='fr', regexp='^%d+%w?$' }, -- Bibliothèque nationale de France
| |
| {label='BPN' , property='P651' , lang='nl', regexp='^%d%d%d%d%d%d%d%d$' }, -- Biografisch Portaal number
| |
| {label='NAID' , property='P1225', lang='en', regexp='^%d+$' }, -- NARA ID (redirect for US National Archives Identifier (P1225))
| |
| {label='Museofile' , property='P539' , lang='fr', regexp='^M%d%d%d%d%-?%d?%d?$' }, --Ministry of Culture (France)
| |
| {label='NDL' , property='P349' , lang='ja', regexp='^0?%d%d%d%d%d%d%d%d$' }, -- National Diet Library (of Japan)
| |
| {label='NLA' , property='P409' , lang='en', regexp='^[1-9]%d*$' }, -- National Library of Australia
| |
| {label='BIBSYS' , property='P1015', lang='no', regexp='^%d+$' }, -- Norwegian information system BIBSYS
| |
| {label='HDS' , property='P902' , lang='de', regexp='^%d%d%d?%d?%d?%d?$' }, -- Historical Dictionary of Switzerland
| |
| {label='MusicBrainz' , property='P434' , lang='en', regexp='^[-%x]+$' },
| |
| {label='MGP' , property='P549' , lang='en', regexp='^%d%d?%d?%d?%d?%d?$' }, -- Mathematics Genealogy Project
| |
| {label='NCL' , property='P1048', lang='zh', regexp='^%d+$' }, --National Central Library (Taiwan)
| |
| {label='NKC' , property='P691' , lang='cs', regexp='^%l%l%l?%l?%d%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' }, --National Library of the Czech Republic | |
| {label='Léonore' , property='P640' , lang='fr', regexp='^[LHC%/%d]+$' },
| |
| {label='SBN' , property='P396' , lang='it'}, -- Istituto Centrale per il Catalogo Unico / National Library Service (SBN) of Italy
| |
| {label='RSL' , property='P947' , lang='ru', regexp='^%d%d%d%d%d%d%d%d%d$' }, --Russian State Library
| |
| {label='Botanist' , property='P428' , lang='en' },
| |
| {label='US Congress' , property='P1157', lang='en', regexp='^%u00[01]%d%d%d' },
| |
| {label='BNE' , property='P950' , lang='es', regexp='' }, --Biblioteca Nacional de España
| |
| {label='CALIS' , property='P270' , lang='zh'}, --China Academic Library and Information
| |
| {label='CiNii' , property='P271' , lang='jp', regexp='^DA%d%d%d%d%d%d%d[%dX]$' },
| |
| {label='TLS' , property='P1362', lang='de', regexp='' }, -- Theaterlexikon der Schweiz
| |
| {label='SIKART' , property='P781' , lang='de', regexp='^%d%d%d%d%d%d%d%d?%d?%d?$' }, -- Swiss
| |
| {label='NLP' , property='P1695', lang='pl', regexp='' }, -- National Library of Poland
| |
| {label='WGA' , property='P1882', lang='en', regexp='' }, -- Web Gallery of Art
| |
| {label='KulturNav' , property='P1248', lang='no', regexp='' },
| |
| {label='RKD' , property='P650' , lang='nl', regexp='^[1-9]%d%d?%d?%d?%d?$' }, --Netherlands Institute for Art History#Online artist pages
| |
| {label='autores.uy' , property='P2558', lang='es', regexp='^[1-9]%d?%d?%d?%d?$' }, --autores.uy
| |
| {label='J9U' , property='P8189', lang='he', regexp='' }, --National Library of Israel J9U ID
| |
| | |
| {label='FIDE' , property='P1440', lang='en', regexp='' }, -- FIDE database for chess players
| |
| {label='Chess Games' , property='P1665', lang='en', regexp='' }, -- Chess Games
| |
| | |
| {label='ISSN' , property='P236', lang='', regexp='' }, -- P1629: International Standard Serial Number
| |
| {label='OSM' , property='P402', lang='', regexp='' }, -- P1629: OpenStreetMap
| |
| {label='Joconde' , property='P347', lang='fr', regexp='' }, -- Joconde ID
| |
| {label='Rijksmonument',property='P359', lang='nl', regexp='' }, -- Rijksmonument ID
| |
| {label='IMO' , property='P458', lang='', regexp='' }, --IMO ship number
| |
| {label='BNCF' , property='P508', lang='it', regexp='' }, -- BNCF Thesaurus ID
| |
| {label='MMSI' , property='P587', lang='', regexp='' }, -- P1629: Maritime Mobile Service Identity
| |
| {label='Open Library', property='P648', lang='', regexp='' }, -- P1629: Open Library
| |
| {label='NRHP' , property='P649', lang='en', regexp='' }, -- NRHP reference number
| |
| {label='DBNL' , property='P723', lang='', regexp='' }, -- DBNL author ID
| |
| {label='UNESCO' , property='P757', lang='', regexp='' }, -- World Heritage Site ID
| |
| {label='BIC' , property='P808', lang='', regexp='' }, -- Bien de Interés Cultural (BIC) code
| |
| {label='LIR' , property='P886', lang='', regexp='' }, -- LIR
| |
| {label='BNR' , property='P1003', lang='ro', regexp='' }, -- NLR (Romania) ID
| |
| {label='Koninklijke' , property='P1006', lang='nl', regexp='' }, -- National Thesaurus for Author Names ID
| |
| {label='Louvre' , property='P9394', lang='', regexp='' }, -- Louvre ID
| |
|
| |
| {label='OCLC' , property='P243', lang='', regexp='' }, -- OCLC
| |
| {label='ISBN-13' , property='P212', lang='', regexp='' }, -- ISBN-13
| |
| {label='ISBN-10' , property='P957', lang='', regexp='' }, -- ISBN-10
| |
| {label='Historic England', property='P1216', lang='en', regexp='' }, -- National Heritage List for England number
| |
| | |
| {label='Oxford Dict.', property='P1415', lang='en', regexp='' }, -- Oxford Dictionary of National Biography ID
| |
| {label='kulturnoe-nasledie', property='P1483', lang='ru', regexp='' }, -- kulturnoe-nasledie.ru ID
| |
| {label='Catalunya' , property='P1600', lang='ca', regexp='' }, -- Inventari del Patrimoni Arquitectònic de Catalunya code
| |
| {label='COAM' , property='P2917', lang='es', regexp='' }, -- COAM structure ID
| |
| {label='SIMBAD' , property='P3083', lang='fr', regexp='' }, -- SIMBAD ID
| |
| {label='JCyL' , property='P3177', lang='es', regexp='' }, -- Patrimonio Web JCyL ID
| |
| {label='Zaragoza' , property='P3178', lang='es', regexp='' }, -- Zaragoza monument ID
| |
| {label='BDI' , property='P3318', lang='es', regexp='' }, -- Patrimonio Inmueble de Andalucía ID
| |
| {label='SIPCA' , property='P3580', lang='es', regexp='' }, -- SIPCA code
| |
| {label='DOCOMOMO' , property='P3758', lang='', regexp='' }, -- DOCOMOMO Ibérico ID
| |
| {label='Czech Monument', property='P4075', lang='cz', regexp='' }, -- Czech Monument Catalogue Number
| |
| {label='MEG' , property='P4157', lang='ch', regexp='' }, -- P1629: Musée d'ethnographie de Genève
| |
| {label='Enciclopédia Itaú Cultural' , property='P4399', lang='pt_br', regexp='' }, -- Enciclopédia Itaú Cultural ID
| |
| {label='Monumentos de São Paulo' , property='P4360', lang='pt_br', regexp='' }, -- Monumentos de São Paulo ID
| |
| {label='Infopatrimônio' , property='P4372', lang='pt_br', regexp='' }, -- Infopatrimônio ID
| |
| {label="Musée d'Orsay" , property='P4659', lang='fr' , regexp='' }, -- Musée d'Orsay artwork ID
| |
| {label='MuBE' , property='P4721', lang='pt_br', regexp='' }, -- MuBE Virtual ID
| |
| {label='Hispania Nostra' , property='P4868', lang='es' , regexp='' }, -- Hispania Nostra Red List ID
| |
| {label='NLK' , property='P5034', lang='ko' , regexp='' }, -- National Library of Korea ID
| |
| }
| |
| | |
| -- ==================================================
| |
| -- === External functions ===========================
| |
| -- ==================================================
| |
| local p = {}
| |
| | |
| function p.getAuthorityControlTag( lang )
| |
| -- get a localized interwiki link to article "Authority Control"
| |
| local field_name = "[[w:en:Help:Authority control|Authority control]]" -- hardwire the default
| |
| if lang~='en' then
| |
| field_name = core.getLabel("Q36524", lang) | |
| end | | end |
| return field_name | | local conf = config.config |
| end
| | local parentArgs = frame:getParent().args |
| | | local auxCats = '' |
| -- ================================================== | | local rct = false -- boolean to track if there are any links to be returned |
| function p._authorityControl(entity, args, lang, length) | | local qid,topic |
| -- INPUTS:
| | local wikilink = function(qid,hideifequal) |
| -- * entity - wikidata entity if already created or nil. If provided than you should still provide args.Wikidata
| | local label,sitelink = mw.wikibase.getLabel(qid),mw.wikibase.getSitelink(qid) |
| -- * args - structure with identifier fields: args.VIAF, args.LCCN, args.Wikidata, etc.
| | if label then |
| -- * lang - language code | | if sitelink then |
| -- * length - maximum length of the identifier array, or number of identifiers to display | | local target = mw.title.new(sitelink) |
| -- OUTPUTS:
| | if target==title or (target.isRedirect and target.redirectTarget==title) then -- do not link |
| -- * results - wikicode string equivalent to {{Authority control|...|bare=1 }} call
| | return label |
| -- * cats - wikicode with maintenance categories
| | else -- make wikilink to article |
| | | return '[[' .. sitelink .. '|' .. label .. ']]' |
| -- count custom parameters (not pulled from Wikidata)
| | end |
| local nCustomParam = 0
| | else |
| for _,params in ipairs( conf ) do
| | return label |
| if (args[params.label]~=nil) then
| | end |
| nCustomParam = nCustomParam + 1 | | else |
| | auxCats = auxCats .. needsAttention('L') |
| | return qid |
| end | | end |
| end | | end |
| | | if namespace == 0 then |
| -- Get entity - record of wikidata related to a single item
| | qid = mw.wikibase.getEntityIdForCurrentPage() |
| local q = args.wikidata
| |
| if not entity and q then
| |
| entity = mw.wikibase.getEntity(q) | |
| end | | end |
| | | if qid then -- article is connected to Wikidata item |
| -- Check if this is category item
| | if parentArgs.qid and (resolveQID(parentArgs.qid) ~= qid) then -- non-matching qid parameter |
| local cats = '' -- categories (mismatching and missing)
| | auxCats = auxCats .. needsAttention('D') |
| if entity and entity.claims and entity.claims.P31 then
| | end |
| for _, statement in pairs( entity.claims.P31) do
| | else -- page is not connected to any Wikidata item |
| if (statement.mainsnak.snaktype == "value") and (statement.mainsnak.datavalue.value.id == 'Q4167836') then -- P31 == Wikimedia category | | qid = resolveQID(parentArgs.qid) -- check qid parameter if no wikidata item is connected |
| cats = '[[Category:Wrong Wikidata ID in authority control data: category item]]'
| | if qid then -- qid parameter is valid, set topic to display |
| | topic = mw.wikibase.getLabel(qid) |
| | if topic then |
| | if mw.ustring.lower(title.subpageText) == mw.ustring.lower(topic) then -- suppress topic display if subpagename equals topic up to case change |
| | topic = nil |
| | end |
| | if topic and mw.wikibase.getSitelink(qid) then -- make wikilink to article |
| | topic = '[[' .. mw.wikibase.getSitelink(qid) .. '|' .. topic .. ']]' |
| | end |
| | else |
| | auxCats = auxCats .. needsAttention('L') |
| end | | end |
| if (statement.mainsnak.snaktype == "value") and (statement.mainsnak.datavalue.value.id == 'Q4167410') then -- P31 == Wikimedia disambiguation page | | elseif parentArgs.qid and parentArgs.qid~='' then -- invalid qid has been supplied, add to tracking cat |
| cats = '[[Category:Wrong Wikidata ID in authority control data: disambiguation item]]' | | auxCats = auxCats .. needsAttention('Q') |
| | end |
| | end |
| | local qids = {} -- setup any additional QIDs |
| | if parentArgs.additional=='auto' and qid then -- check P527 for parts to add additional qids |
| | local checkparts = function(property) |
| | local parts = mw.wikibase.getBestStatements(qid,property) |
| | if parts then |
| | for _,part in ipairs(parts) do |
| | if part.mainsnak.datavalue and part.mainsnak.datavalue.value.id then |
| | local resolvedqid = resolveQID(part.mainsnak.datavalue.value.id) |
| | if resolvedqid then |
| | table.insert(qids,resolvedqid) |
| | end end end end end |
| | for _,part in ipairs(config.auto_additional) do |
| | checkparts('P'..tostring(part)) |
| | end |
| | elseif parentArgs.additional and parentArgs.additional ~= '' then |
| | for _,v in ipairs(mw.text.split(parentArgs.additional,"%s*,%s*")) do |
| | v = resolveQID(v) |
| | if v then |
| | if v == qid then -- duplicate of qid parameter |
| | auxCats = auxCats .. needsAttention('R') |
| | end |
| | table.insert(qids,v) |
| | else -- invalid QID specified |
| | auxCats = auxCats .. needsAttention('A') |
| end | | end |
| end | | end |
| end | | end |
|
| |
|
| --compare provided arguments with Wikidata identifiers | | local sections = {} |
| local data = {} -- structure similar to "args" but filled with wikidata data | | local localparams = false |
| for _,params in ipairs( conf ) do | | local numsections = 0 |
| local label = string.lower(params.label)
| | for _,_ in ipairs(config.sections) do numsections = numsections + 1 end |
| data[label] = nil | | for _ = 1,#qids+numsections do table.insert(sections,{}) end |
| if entity and entity.claims and params.property and entity.claims[params.property] then -- if we have wikidata item and item has the property
| | local qslink = '' -- setup link to add using QuickStatements |
| -- capture all Wikidata values for the identifier | | |
| --for _, statement in pairs( entity.claims[params.property]) do
| | -- check which identifiers to show/suppress in template |
| for _, statement in pairs( entity:getBestStatements( params.property )) do | | local show = {} -- setup list |
| if (statement.mainsnak.snaktype == "value") then -- or if statement.mainsnak.datavalue then | | local showall = true |
| local v = statement.mainsnak.datavalue.value | | local function stripP(pid) |
| if data[label]==nil then | | if pid:match("^[Pp]%d+$") then |
| data[label] = v -- save the first value | | pid = mw.ustring.gsub(pid,'[Pp]','') --strip P from property number |
| end
| | end |
| if args[label] == v then -- match between template and wikidata identifiers
| | if pid:match("^%d+$") then |
| data[label] = '' -- ignore identifier from wikidata
| | return tonumber(pid) |
| break | | end |
| | end |
| | local function addshowlist(list) |
| | if list and list ~= '' then |
| | for _,v in ipairs(mw.text.split(string.lower(list),"%s*,%s*")) do |
| | local vprop = stripP(v) |
| | if vprop then -- e.g. show=P214 to show one particular property |
| | show[vprop] = true |
| | else -- e.g. show=arts to use whitelist |
| | if config.whitelists[v] then |
| | for _,w in ipairs(config.whitelists[v].properties) do |
| | show[w] = true |
| | end |
| end | | end |
| end | | end |
| end | | end |
| | showall = false |
| end | | end |
| end | | end |
| | | addshowlist(frame.args.show) -- check show= parameter on wrapper template |
| --Create string with all the identifiers listed | | addshowlist(parentArgs.show or parentArgs.country) -- check show parameter on article template |
| local results1 = {} -- high priority list
| | if parentArgs.suppress then |
| local results2 = {} -- low priority list | | local suppresslist = mw.text.split(parentArgs.suppress,"%s*,%s*") -- split parameter by comma |
| properties.P214.item = 'Q54919'; -- hardwire link to VIAF | | for _,v in ipairs(suppresslist) do |
| local today = '+' .. os.date('!%F') .. 'T00:00:00Z/11'
| | v = stripP(string.upper(v)) |
| local TransStr = 'https://quickstatements.toolforge.org/#/v1=%s|%s|%%22%s%%22|S143|Q565|S813|'.. today -- QuickStatementts URL
| | if v then |
| TransStr = '<span class=\"plainlinks\" title=\"Click (+) to copy to wikidata\">['.. TransStr .. ' (+)]</span>'
| | show[v] = false |
| for _,params in ipairs( conf ) do
| | auxCats = auxCats .. '[[' .. config.i18n.category .. ':' .. config.i18n.suppressedcat .. ']]' |
| local label = string.lower(params.label)
| |
| local val1 = args[label] -- identifier value provided to the template
| |
| local val2 = data[label] -- identifier value pulled from wikidata
| |
| if val1 or val2 then
| |
| local P = properties[params.property] -- properties of wikidata identifier propertyc | |
| -- name_link - link for the identifier name
| |
| local name_link = getIdentifierNameLink( lang, P.item, P.issuedBy, params.label )
| |
|
| |
| -- val_link - identifier value or values
| |
| local transfer = ''
| |
| local val3 = string.gsub(val1 or '', ' ', '' ) -- remove spaces
| |
| local val_link
| |
| if not val1 then | |
| val_link = getIdentifierValLink(val2, P.URL_format, params, 'blue') -- wikidata only no local identifier | |
| elseif val2=='' then
| |
| val_link = getIdentifierValLink(val1, P.URL_format, params, 'magenta') -- match was found | |
| elseif val2 then
| |
| val_link = getIdentifierValLink(val1, P.URL_format, params, 'darkgreen') .. "/"..getIdentifierValLink(val2, P.URL_format, params, 'blue')
| |
| cats = string.format("%s[[Category:Pages using authority control with identifiers mismatching Wikidata]]\n", cats)
| |
| transfer = string.format(TransStr, q, params.property, val3)
| |
| elseif not val2 and entity then
| |
| val_link = getIdentifierValLink(val1, P.URL_format, params, 'darkgreen')
| |
| cats = string.format("%s[[Category:Pages using authority control with identifiers missing from Wikidata]]\n", cats)
| |
| transfer = string.format(TransStr, q, params.property, val3)
| |
| else | | else |
| val_link = getIdentifierValLink(val1, P.URL_format, params, 'blue') -- local identifier and no wikidata q-code | | auxCats = auxCats .. needsAttention('P') |
| end
| |
| | |
| -- combine them all
| |
| local lineStr = string.format("\n*%s: <span class=\"uid\">%s</span>%s", name_link, val_link, transfer)
| |
| if (params.lang==lang) or (params.lang=='') then
| |
| table.insert(results1, lineStr) -- add to high priority list
| |
| else
| |
| table.insert(results2, lineStr) -- add to low priority list
| |
| end | | end |
| end | | end |
| end -- for all sources
| |
|
| |
| -- merge high and low priority lists, trim them if needed and convert to string
| |
| --table.insert(results1, "\n*End list 1") -- for debuging
| |
| --table.insert(results2, "\n*End list 2")
| |
| for _,v in pairs(results2) do table.insert(results1, v) end
| |
| local results = table.concat(results1, "", 1, math.min(#results1, length or #results1))
| |
|
| |
| -- Add Link to wikidata
| |
| if q then
| |
| results = string.format("\n*[[File:Wikidata-logo.svg|20px|wikidata:%s|link=wikidata:%s]]: [[d:%s|%s]]%s",q,q,q,q,results)
| |
| end | | end |
| | | |
| -- Add link to Worldcat | | local function makeSections(qid,addit) |
| if (args.worldcatid==nil and (args.lccn or data.lccn)) then
| | local tval = {} |
| args.worldcatid = 'lccn-' .. (args.lccn or data.lccn)
| | local function parameter_is_used(property) |
| | local used = false |
| | if property then |
| | if tval[property] then |
| | if tval[property][1] then |
| | used = true |
| | end |
| | elseif tval[property] == false then -- property has been manually suppressed |
| | used = true |
| | end |
| | end |
| | return used |
| | end |
| | for _, params in ipairs(conf) do |
| | tval[params.property] = getIdsFromWikidata(qid, 'P' .. params.property) -- setup table for values with property number as key |
| | local showb = true |
| | if (show[params.property] == nil) and (show[string.upper(params[1])] == nil ) then |
| | showb = showall -- if not specified then depends on showall |
| | elseif (show[params.property] == false) or (show[string.upper(params[1])] == false) then -- if either are false then id will be suppressed |
| | showb = false |
| | end |
| | if not showb then |
| | tval[params.property] = false -- indicates the identifier is suppressed |
| | elseif not addit then |
| | local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]] |
| | if val and val~='' then -- add local parameter to list if not already in |
| | localparams = true |
| | local bnew = true |
| | for _, w in pairs(tval[params.property]) do |
| | if val == w.id then |
| | bnew = false |
| | end |
| | end |
| | if bnew then -- add new value to table |
| | if qid then |
| | qslink = qslink .. '%7C%7C' .. qid .. '%7CP' .. params.property .. '%7C%22' .. mw.uri.encode(val,"PATH") .. '%22%7CS143%7CQ328' |
| | end |
| | table.insert(tval[params.property],{id=val,name=''}) |
| | end |
| | end |
| | end |
| | local suppress = false |
| | if params.suppressedbyproperty then |
| | for _,sc in ipairs(params.suppressedbyproperty) do |
| | if parameter_is_used(sc) then |
| | suppress = true |
| | end |
| | end |
| | end |
| | if tval[params.property] ~= false and not suppress then |
| | local tlinks = {} -- setup table for links |
| | local nextIdVal = 1 |
| | local row = '' |
| | for _,val in ipairs(tval[params.property]) do |
| | local link = _makelink(params,val,nextIdVal,qid) |
| | row = row .. link |
| | table.insert(tlinks,link) |
| | nextIdVal = nextIdVal + 1 |
| | end |
| | if nextIdVal>=2 then |
| | row = row .. '\n' |
| | table.insert(sections[addit or params.section],row) |
| | rct = true |
| | end |
| | end |
| | end |
| end | | end |
| if args.worldcatid then | | local function pencil(qid) |
| results = string.format("%s\n*<span class=\"uid\">[//www.worldcat.org/identities/%s WorldCat]</span>", results, args.worldcatid) | | if not qid then |
| | return '' |
| | end |
| | local args = { pid = 'identifiers' } -- #target the list of identifiers |
| | args.qid = qid |
| | return require('Module:EditAtWikidata')._showMessage(args) |
| end | | end |
|
| | |
| -- Add maintenance categories | | makeSections(qid,false) |
| if q == nil then | | for c = 1,#qids do |
| cats = string.format("%s[[Category:Pages using authority control without Wikidata link]]\n", cats) | | makeSections(qids[c],numsections+c) |
| end | | end |
| if nCustomParam>0 then | | |
| if cats=='' and entity ~= nil then | | --configure Navbox |
| cats = string.format("%s[[Category:Pages using authority control with all identifiers matching Wikidata]]\n", cats)
| | local outString = '' |
| | if rct or localparams then -- there is at least one link to display |
| | local Navbox = require('Module:Navbox') |
| | local sect,lastsect = 0,0 |
| | local navboxArgs = { |
| | name = 'Authority control', |
| | navboxclass = 'authority-control', |
| | bodyclass = 'hlist', |
| | state = parentArgs.state or config.i18n.autocollapse, |
| | navbar = 'off' |
| | } |
| | for c=1,numsections+#qids do |
| | if #sections[c] ~= 0 then -- section is non-empty |
| | sect = sect + 1 |
| | lastsect = c |
| | local sectname |
| | if c <= numsections then -- regular section |
| | sectname = config.sections[c].name |
| | else -- section from additional qid |
| | local qid = qids[c-numsections] |
| | sectname = wikilink(qid) .. pencil(qid) |
| | end |
| | navboxArgs['group' .. c] = sectname |
| | navboxArgs['list' .. c] = table.concat(sections[c]) |
| | end |
| end | | end |
| if string.find(results, "<span style=\"color:red\">") then | | if localparams then |
| cats = string.format("%s[[Category:Pages using authority control with badly formated identifier]]\n", cats)
| | lastsect = lastsect + 1 |
| | sect = sect + 1 |
| | navboxArgs['group' .. lastsect] = config.i18n.warning |
| | local warning = frame:expandTemplate{title = config.i18n.errortemplate, args = {config.i18n.localparams}} |
| | if qslink ~= '' then |
| | warning = warning .. ' ' .. config.i18n.movetowd .. '<span class="qs autoconfirmed-show"> [[File:Commons to Wikidata QuickStatements.svg|20px|link=https://quickstatements.toolforge.org/#/v1=' .. qslink .. '|' .. config.i18n.addtowd .. ']]</span>' |
| | elseif not qid then |
| | if namespace == 0 then |
| | warning = warning .. ' ' .. config.i18n.connecttowd |
| | elseif namespace==14 or namespace==2 or namespace==118 then |
| | warning = warning .. ' ' .. config.i18n.qidcode |
| | end |
| | end |
| | navboxArgs['list' .. lastsect] = warning |
| end | | end |
| | if topic then -- display in expanded form with topic |
| | navboxArgs.title = config.i18n.aclink .. ' – ' .. topic .. pencil(qid) |
| | elseif sect == 1 then -- special display when only one section |
| | if lastsect <= numsections then |
| | if config.sections[lastsect].hidelabelwhenalone then -- no special label when only general or other IDs are present |
| | navboxArgs['group' .. lastsect] = config.i18n.aclink .. pencil(qid) |
| | else -- other regular section |
| | navboxArgs['group' .. lastsect] = config.i18n.aclink .. ': ' .. navboxArgs['group' .. lastsect] .. pencil(qid) |
| | end |
| | else -- section from additional qid |
| | navboxArgs['group' .. lastsect] = config.i18n.aclink .. ': ' .. navboxArgs['group' .. lastsect] |
| | end |
| | else -- add title to navbox |
| | navboxArgs.title = config.i18n.aclink .. pencil(qid) |
| | end |
| | outString = Navbox._navbox(navboxArgs) |
| end | | end |
|
| |
|
| -- return results | | if parentArgs.state |
| if results~='' then -- if there are any results than wrap them in <div> tag
| | and parentArgs.state~='' |
| results = string.format('<div class="hlist">%s\n</div>', results) | | and parentArgs.state~=config.i18n.collapsed |
| | and parentArgs.state~=config.i18n.expanded |
| | and parentArgs.state~=config.i18n.autocollapse then --invalid state parameter |
| | auxCats = auxCats .. needsAttention('S') |
| | end |
| | if testcases then |
| | auxCats = mw.ustring.gsub(auxCats, '(%[%[)(' .. config.i18n.category .. ')', '%1:%2') --for easier checking |
| end | | end |
| return results, cats
| |
| end
| |
|
| |
|
| |
|
| -- =========================================================================== | | --out |
| -- === Version of the function to be called from template namespace
| | outString = outString..auxCats |
| -- ===========================================================================
| | if namespace ~= 0 then |
| function p.authorityControl(frame)
| | outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':' .. config.i18n.Articles .. ')([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4') |
| -- prepare arguments
| | outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':' .. config.i18n.All_articles .. ')([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4') |
| local args = core.getArgs(frame)
| |
| local bare = core.yesno(args.bare,false)
| |
|
| |
| -- Convert template arguments to the same format as used on wikidata
| |
| if args.bnf then
| |
| args.bnf = string.sub(args.bnf, 3) -- trim first 2 characters
| |
| end | | end |
| if args.isni then -- group in sets of 4 | | local check = require('Module:Check for unknown parameters')._check |
| args.isni = string.sub(args.isni, 1, 4).." "..string.sub(args.isni, 5, 8) | | local sortkey |
| .." "..string.sub(args.isni, 9,12).." "..string.sub(args.isni,13,16)
| | if namespace == 0 then |
| | sortkey = '*' .. title.text |
| | else |
| | sortkey = title.fullText |
| end | | end |
| if args.isbn then | | outString = outString .. check({ |
| local isbn = isbn.gsub( ' ', '' )
| | ['unknown'] = '[[' .. config.i18n.category .. ':' .. config.i18n.pageswithparams .. '|' .. sortkey .. ']]', |
| if #isbn==10 then | | ['preview'] = config.i18n.previewwarning, 'show', 'country', 'suppress', 'additional', 'qid', 'state' |
| args['isbn-10'] = args.isbn
| | }, parentArgs) |
| elseif #isbn==13 then
| | return outString |
| args['isbn-13'] = args.isbn
| | end |
| end
| |
| args.isbn = nil
| |
| end
| |
| args.gnd = args.gnd or args.pnd --redirect PND to GND
| |
| args.lccn = fixLCCN(args.lccn)
| |
| args.wikidata = args.wikidata or args.q or nil
| |
|
| |
| -- call the inner "core" function
| |
| local results, cats = p._authorityControl(nil, args, args.lang, args.length)
| |
| local namespace = mw.title.getCurrentTitle().namespace
| |
| local LUT = {[2]='user', [6]='file', [10]='template', [828]='module'}
| |
| if (LUT[namespace] or math.fmod(namespace,2)==1) then
| |
| -- lets not add categories to some namespaces, or talk pages and concentrate
| |
| -- on templates and categories instead
| |
| cats = ''
| |
| end
| |
| | |
| --package results as a infobox if not "bare"
| |
| if not bare then
| |
| -- Get field name for authority control
| |
| local field_name = p.getAuthorityControlTag(args.lang)
| |
|
| |
|
| -- build table
| | p.makelink = function(conf,val,nextid,qid) |
| results = string.format('<tr><td class="type fileinfo-paramfield">%s</td><td>\n%s\n</td></tr>', field_name, results)
| | return _makelink(conf,val,nextid,qid) |
| local dir = mw.language.new( args.lang ):getDir() -- get text direction
| |
| local style = 'class="toccolours mw-content-%s layouttemplate commons-file-information-table" style="width: 100%%;" dir="%s" lang="%s"'
| |
| style = string.format(style, dir, dir, args.lang)
| |
| results = string.format('<table %s>\n%s\n</table>\n', style, results)
| |
| else
| |
| results = string.format('\n%s\n', results)
| |
| end
| |
| return results..cats
| |
| end | | end |
|
| |
|
| return p | | return p |