Module:Authority control: Difference between revisions
Jump to navigation
Jump to search
m (1 revision imported) |
(what the actual fuck) |
||
Line 1: | Line 1: | ||
require('strict') | require('strict') | ||
local p = {} | local p = {} | ||
local arg = mw.getCurrentFrame().args.config | |||
local configfile = 'Module:Authority control/config' .. (arg and arg~='' and ('/' .. arg) or '') | |||
local config = mw.loadData(configfile) | |||
local title = mw.title.getCurrentTitle() | local title = mw.title.getCurrentTitle() | ||
local namespace = title.namespace | local namespace = title.namespace | ||
local testcases = | local testcases = title.subpageText == config.i18n.testcases | ||
local function needsAttention(sortkey) | |||
return '[[' .. config.i18n.category .. ':' .. config.i18n.attentioncat .. '|' .. sortkey .. title.text .. ']]' | |||
end | |||
local function addCat(cat,sortkey) | local function addCat(cat,sortkey) | ||
if cat and cat ~= '' and (namespace == 0 or namespace == 14 or testcases) then | if cat and cat ~= '' and (namespace == 0 or namespace == 14 or testcases) then | ||
local redlinkcat = '' | local redlinkcat = '' | ||
if testcases == false | if testcases == false then | ||
local success, exists = pcall(function() return mw.title.new(cat, 14).exists end) | |||
if success and not exists then | |||
redlinkcat = needsAttention('N') | |||
end | |||
end | end | ||
if sortkey then | if sortkey then | ||
cat = '[[ | cat = '[[' .. config.i18n.category .. ':'..cat..'|' .. sortkey .. title.text .. ']]' | ||
else | else | ||
cat = '[[ | cat = '[[' .. config.i18n.category .. ':'..cat..']]' | ||
end | end | ||
cat = cat .. redlinkcat | cat = cat .. redlinkcat | ||
Line 24: | Line 34: | ||
local function getCatForId(id,faulty) | local function getCatForId(id,faulty) | ||
local cat = | local cat = string.format( | ||
config.i18n.cat, | |||
(faulty and config.i18n.faulty..' ' or '') .. id | |||
) | |||
return addCat(cat) | return addCat(cat) | ||
end | end | ||
local function getIdsFromWikidata(qid,property) | 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 | |||
local ids = {} | local ids = {} | ||
if | if qid then | ||
for _, statement in ipairs(mw.wikibase.getBestStatements(qid,property)) do | |||
if statement.mainsnak.datavalue then | if statement.mainsnak.datavalue then | ||
local val = statement.mainsnak.datavalue.value | |||
if val then | |||
local namedas = getquals(statement,1810) or getquals(statement,742) or '' | |||
table.insert(ids,{id=val,name=namedas}) | |||
end | |||
end | end | ||
end | end | ||
Line 46: | Line 64: | ||
end | end | ||
local function | local _makelink = function(conf,val,nextid,qid) --validate values and create a link | ||
local function tooltip(text,label) | |||
if label and label~='' then | |||
return mw.getCurrentFrame():expandTemplate{title = "Tooltip", args = {text,label}} | |||
else | |||
return text | |||
end | |||
end | |||
local link | local link | ||
if nextid==1 then | if nextid==1 then | ||
Line 58: | Line 83: | ||
end | end | ||
local valid_value = false | local valid_value = false | ||
if conf. | if conf.customlink then -- use function to validate and generate link | ||
local label = nextid>1 and nextid | |||
link = link .. | local newlink= require(config.auxiliary)[conf.customlink](val.id,label) | ||
if newlink then | |||
link = link .. newlink | |||
valid_value = true | valid_value = true | ||
end | end | ||
else | else | ||
if conf.pattern then -- use pattern to determine validity if defined | if conf.pattern then -- use pattern to determine validity if defined | ||
valid_value = | valid_value = string.match(val.id,'^'..conf.pattern..'$') | ||
elseif conf.patterns then | elseif conf.patterns then | ||
for | for _,pattern in ipairs(conf.patterns) do | ||
valid_value = val:match( | valid_value = val.id:match('^'..pattern..'$') | ||
if valid_value then break end | if valid_value then break end | ||
end | end | ||
elseif conf.valid then -- otherwise use function to determine validity | elseif conf.valid then -- otherwise use function to determine validity | ||
valid_value = conf.valid(val) | valid_value = require(config.auxiliary)[conf.valid](val.id) | ||
else -- no validation possible | else -- no validation possible | ||
valid_value = val | valid_value = val.id | ||
end | end | ||
if valid_value then | if valid_value then | ||
local newlink | |||
if not | local label = conf.label | ||
if not label or nextid>1 then | |||
label = tostring(nextid) | |||
end | end | ||
if conf.link then | if conf.link then | ||
valid_value = valid_value:gsub('%%', '%%%%') | valid_value = valid_value:gsub('%%', '%%%%') | ||
newlink = '[' .. mw.ustring.gsub(conf.link,'%$1',valid_value) .. ' ' .. label .. ']' | |||
else | else | ||
newlink = valid_value | |||
end | end | ||
link = link .. '</span>' | link = link .. '<span class="uid">'..tooltip(newlink,val.name)..'</span>' | ||
end | end | ||
end | end | ||
Line 95: | Line 123: | ||
--local preview = require("Module:If preview") | --local preview = require("Module:If preview") | ||
local wdlink = qid and '[[:wikidata:' .. qid .. '#P' .. conf.property .. ']]' or '' | local wdlink = qid and '[[:wikidata:' .. qid .. '#P' .. conf.property .. ']]' or '' | ||
link = link .. '[[File: | 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 | if conf.errorcat then | ||
link = link .. addCat(conf.errorcat) | link = link .. addCat(conf.errorcat) | ||
Line 101: | Line 134: | ||
link = link .. getCatForId(conf.category or conf[1],true) | link = link .. getCatForId(conf.category or conf[1],true) | ||
end | end | ||
link = link .. addCat( | link = link .. addCat(config.i18n.allfaultycat,conf[1])-- .. preview._warning({'The '..conf[1]..' id '..val..' is not valid.'}) | ||
end | end | ||
return link | return link | ||
Line 110: | Line 143: | ||
--[[==========================================================================]] | --[[==========================================================================]] | ||
function p.authorityControl(frame) | function p.authorityControl(frame) | ||
local function resolveQID(qid) | local function resolveQID(qid) | ||
if qid then | if qid then | ||
qid = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '') | qid = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '') | ||
qid = | if mw.wikibase.isValidEntityId(qid) and mw.wikibase.entityExists(qid) then | ||
local sitelink = mw.wikibase.getSitelink(qid) | |||
if sitelink then | |||
return mw.wikibase.getEntityIdForTitle(sitelink) or mw.wikibase.getEntity(qid).id | |||
end | |||
return mw.wikibase.getEntity(qid).id | |||
end | |||
end | end | ||
end | end | ||
local conf = config.config | local conf = config.config | ||
local parentArgs = frame:getParent().args | local parentArgs = frame:getParent().args | ||
local auxCats = '' | local auxCats = '' | ||
local rct = | local rct = false -- boolean to track if there are any links to be returned | ||
local qid | local qid,topic | ||
local wikilink = function(qid,hideifequal) | |||
local label,sitelink = mw.wikibase.getLabel(qid),mw.wikibase.getSitelink(qid) | |||
if label then | |||
if sitelink then | |||
local target = mw.title.new(sitelink) | |||
if target==title or (target.isRedirect and target.redirectTarget==title) then -- do not link | |||
return label | |||
else -- make wikilink to article | |||
return '[[' .. sitelink .. '|' .. label .. ']]' | |||
end | |||
else | |||
return label | |||
end | |||
else | |||
auxCats = auxCats .. needsAttention('L') | |||
return qid | |||
end | |||
end | |||
if namespace == 0 then | if namespace == 0 then | ||
qid = mw.wikibase.getEntityIdForCurrentPage() | qid = mw.wikibase.getEntityIdForCurrentPage() | ||
end | end | ||
if | if qid then -- article is connected to Wikidata item | ||
qid = resolveQID(parentArgs | if parentArgs.qid and (resolveQID(parentArgs.qid) ~= qid) then -- non-matching qid parameter | ||
auxCats = auxCats .. needsAttention('D') | |||
end | |||
else -- page is not connected to any Wikidata item | |||
qid = resolveQID(parentArgs.qid) -- check qid parameter if no wikidata item is connected | |||
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 | |||
elseif parentArgs.qid and parentArgs.qid~='' then -- invalid qid has been supplied, add to tracking cat | |||
auxCats = auxCats .. needsAttention('Q') | |||
end | |||
end | end | ||
local qids = {} -- setup any additional QIDs | local qids = {} -- setup any additional QIDs | ||
if parentArgs.additional then | 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 | for _,v in ipairs(mw.text.split(parentArgs.additional,"%s*,%s*")) do | ||
table.insert(qids,v) | 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 | ||
local sections = {} | local sections = {} | ||
for _ | local localparams = false | ||
local numsections = 0 | |||
for _,_ in ipairs(config.sections) do numsections = numsections + 1 end | |||
for _ = 1,#qids+numsections do table.insert(sections,{}) end | |||
local qslink = '' -- setup link to add using QuickStatements | local qslink = '' -- setup link to add using QuickStatements | ||
-- check | -- check which identifiers to show/suppress in template | ||
local | local show = {} -- setup list | ||
local showall = true | |||
local function stripP(pid) | |||
if pid:match("^[Pp]%d+$") then | |||
pid = mw.ustring.gsub(pid,'[Pp]','') --strip P from property number | |||
end | |||
if pid:match("^%d+$") then | |||
return tonumber(pid) | |||
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 | |||
showall = false | |||
end | |||
end | |||
addshowlist(frame.args.show) -- check show= parameter on wrapper template | |||
addshowlist(parentArgs.show or parentArgs.country) -- check show parameter on article template | |||
if parentArgs.suppress then | if parentArgs.suppress then | ||
local suppresslist = mw.text.split(parentArgs.suppress,"%s*,%s*") -- split parameter by comma | local suppresslist = mw.text.split(parentArgs.suppress,"%s*,%s*") -- split parameter by comma | ||
for _,v in ipairs(suppresslist) do | for _,v in ipairs(suppresslist) do | ||
v = stripP(string.upper(v)) | |||
v = | if v then | ||
show[v] = false | |||
auxCats = auxCats .. '[[' .. config.i18n.category .. ':' .. config.i18n.suppressedcat .. ']]' | |||
else | else | ||
auxCats = auxCats .. needsAttention('P') | |||
end | end | ||
end | end | ||
end | end | ||
Line 173: | Line 298: | ||
for _, params in ipairs(conf) do | for _, params in ipairs(conf) do | ||
tval[params.property] = getIdsFromWikidata(qid, 'P' .. params.property) -- setup table for values with property number as key | tval[params.property] = getIdsFromWikidata(qid, 'P' .. params.property) -- setup table for values with property number as key | ||
if | local showb = true | ||
if | 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]] | local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]] | ||
if | if val and val~='' then -- add local parameter to list if not already in | ||
localparams = true | |||
local bnew = true | local bnew = true | ||
for _, w in pairs(tval[params.property]) do | for _, w in pairs(tval[params.property]) do | ||
if val == w then | if val == w.id then | ||
bnew = false | bnew = false | ||
end | end | ||
end | end | ||
if bnew then -- add new value to table | if bnew then -- add new value to table | ||
if qid then | if qid then | ||
qslink = qslink .. '%7C%7C' .. qid .. '%7CP' .. params.property .. '%7C%22' .. mw.uri.encode(val,"PATH") .. '%22%7CS143%7CQ328' | qslink = qslink .. '%7C%7C' .. qid .. '%7CP' .. params.property .. '%7C%22' .. mw.uri.encode(val,"PATH") .. '%22%7CS143%7CQ328' | ||
end | end | ||
table.insert(tval[params.property],val) | table.insert(tval[params.property],{id=val,name=''}) | ||
end | end | ||
end | end | ||
Line 216: | Line 332: | ||
end | end | ||
end | end | ||
if | if tval[params.property] ~= false and not suppress then | ||
local tlinks = {} -- setup table for links | local tlinks = {} -- setup table for links | ||
local nextIdVal = 1 | local nextIdVal = 1 | ||
local row = '' | local row = '' | ||
for _,val in ipairs(tval[params.property]) do | for _,val in ipairs(tval[params.property]) do | ||
local link = | local link = _makelink(params,val,nextIdVal,qid) | ||
row = row .. link | row = row .. link | ||
table.insert(tlinks,link) | table.insert(tlinks,link) | ||
Line 229: | Line 345: | ||
row = row .. '\n' | row = row .. '\n' | ||
table.insert(sections[addit or params.section],row) | table.insert(sections[addit or params.section],row) | ||
rct = | rct = true | ||
end | end | ||
end | end | ||
Line 245: | Line 361: | ||
makeSections(qid,false) | makeSections(qid,false) | ||
for c = 1,#qids do | for c = 1,#qids do | ||
makeSections(qids[c], | makeSections(qids[c],numsections+c) | ||
end | end | ||
--configure Navbox | --configure Navbox | ||
local outString = '' | local outString = '' | ||
if rct | if rct or localparams then -- there is at least one link to display | ||
local Navbox = require('Module:Navbox') | local Navbox = require('Module:Navbox') | ||
local sect,lastsect = 0,0 | local sect,lastsect = 0,0 | ||
Line 267: | Line 373: | ||
navboxclass = 'authority-control', | navboxclass = 'authority-control', | ||
bodyclass = 'hlist', | bodyclass = 'hlist', | ||
state = parentArgs.state or | state = parentArgs.state or config.i18n.autocollapse, | ||
navbar = 'off' | navbar = 'off' | ||
} | } | ||
for c=1, | for c=1,numsections+#qids do | ||
if #sections[c] ~= 0 then -- section is non-empty | if #sections[c] ~= 0 then -- section is non-empty | ||
sect = sect + 1 | sect = sect + 1 | ||
lastsect = c | lastsect = c | ||
local sectname | local sectname | ||
if c <= | if c <= numsections then -- regular section | ||
sectname = config. | sectname = config.sections[c].name | ||
else -- section from additional qid | else -- section from additional qid | ||
local qid = qids[c-numsections] | |||
sectname = wikilink(qid) .. pencil(qid) | |||
end | end | ||
navboxArgs['group' .. c] = sectname | navboxArgs['group' .. c] = sectname | ||
Line 284: | Line 391: | ||
end | end | ||
end | end | ||
local | if localparams then | ||
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 sect == 1 then -- special display when only one section | if topic then -- display in expanded form with topic | ||
if lastsect = | 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 | else -- section from additional qid | ||
navboxArgs['group' .. lastsect] = aclink .. ': ' .. navboxArgs['group' .. lastsect] | navboxArgs['group' .. lastsect] = config.i18n.aclink .. ': ' .. navboxArgs['group' .. lastsect] | ||
end | end | ||
else -- add title to navbox | else -- add title to navbox | ||
navboxArgs.title = aclink .. pencil(qid) | navboxArgs.title = config.i18n.aclink .. pencil(qid) | ||
end | end | ||
outString = Navbox._navbox(navboxArgs) | outString = Navbox._navbox(navboxArgs) | ||
end | end | ||
if parentArgs.state | if parentArgs.state | ||
and parentArgs.state~='' | |||
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 | end | ||
if testcases then | if testcases then | ||
auxCats = mw.ustring.gsub(auxCats, '(%[%[)( | auxCats = mw.ustring.gsub(auxCats, '(%[%[)(' .. config.i18n.category .. ')', '%1:%2') --for easier checking | ||
end | end | ||
Line 320: | Line 439: | ||
outString = outString..auxCats | outString = outString..auxCats | ||
if namespace ~= 0 then | if namespace ~= 0 then | ||
outString = mw.ustring.gsub(outString,'(%[%[)( | outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':' .. config.i18n.Articles .. ')([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4') | ||
outString = mw.ustring.gsub(outString,'(%[%[)( | outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':' .. config.i18n.All_articles .. ')([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4') | ||
end | end | ||
local check = require('Module:Check for unknown parameters')._check | local check = require('Module:Check for unknown parameters')._check | ||
Line 330: | Line 449: | ||
sortkey = title.fullText | sortkey = title.fullText | ||
end | end | ||
outString = outString .. check({ | |||
['unknown']='[[ | ['unknown'] = '[[' .. config.i18n.category .. ':' .. config.i18n.pageswithparams .. '|' .. sortkey .. ']]', | ||
['preview']=' | ['preview'] = config.i18n.previewwarning, 'show', 'country', 'suppress', 'additional', 'qid', 'state' | ||
}, parentArgs) | }, parentArgs) | ||
return outString | return outString | ||
end | end | ||
p.makelink = function(conf,val,nextid,qid) | |||
return _makelink(conf,val,nextid,qid) | |||
end | end | ||
return p | return p |
Latest revision as of 10:07, 10 December 2023
This Lua module is used on approximately 2,000,000 pages, or roughly 128041% of all pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing 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. |
Related pages |
---|
This module uses one or more Wikidata properties; see § Parameters for details.
Lua error in Module:Lua_banner at line 112: attempt to index field 'edit' (a nil value). This module contains the code of the {{Authority control}} and {{Pages with authority control identifiers}} templates.
Parameters, Wikidata properties, and tracking categories
Lua error at line 5: data for mw.loadData contains unsupported data type 'function'.
Additional tracking categories
This module also implements the following hidden tracking categories:
- Category:Pages with red-linked authority control categories (0) – error category to identify missing categories
- Category: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:Pages using authority control with parameters different on Wikidata (0) – determine/remove incorrect IDs & migrate to Wikidata
- Category:Pages using authority control with parameters all matching Wikidata (0) – template parameters may safely be removed
State parameter
- Category:AC using state parameter: collapsed (0)
- Category:AC using state parameter: expanded (0)
- Category:AC using state parameter: autocollapse (0)
- Category:AC using state parameter: other (0)
See also
- m:Interwiki map – definition of global custom interwiki prefixes
require('strict')
local p = {}
local arg = mw.getCurrentFrame().args.config
local configfile = 'Module:Authority control/config' .. (arg and arg~='' and ('/' .. arg) or '')
local config = mw.loadData(configfile)
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local testcases = title.subpageText == config.i18n.testcases
local function needsAttention(sortkey)
return '[[' .. config.i18n.category .. ':' .. config.i18n.attentioncat .. '|' .. sortkey .. title.text .. ']]'
end
local function addCat(cat,sortkey)
if cat and cat ~= '' and (namespace == 0 or namespace == 14 or testcases) then
local redlinkcat = ''
if testcases == false then
local success, exists = pcall(function() return mw.title.new(cat, 14).exists end)
if success and not exists then
redlinkcat = needsAttention('N')
end
end
if sortkey then
cat = '[[' .. config.i18n.category .. ':'..cat..'|' .. sortkey .. title.text .. ']]'
else
cat = '[[' .. config.i18n.category .. ':'..cat..']]'
end
cat = cat .. redlinkcat
return cat
else
return ''
end
end
local function getCatForId(id,faulty)
local cat = string.format(
config.i18n.cat,
(faulty and config.i18n.faulty..' ' or '') .. id
)
return addCat(cat)
end
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
local ids = {}
if qid then
for _, statement in ipairs(mw.wikibase.getBestStatements(qid,property)) do
if statement.mainsnak.datavalue then
local val = statement.mainsnak.datavalue.value
if val then
local namedas = getquals(statement,1810) or getquals(statement,742) or ''
table.insert(ids,{id=val,name=namedas})
end
end
end
end
return ids
end
local _makelink = function(conf,val,nextid,qid) --validate values and create a link
local function tooltip(text,label)
if label and label~='' then
return mw.getCurrentFrame():expandTemplate{title = "Tooltip", args = {text,label}}
else
return text
end
end
local link
if nextid==1 then
if conf.prefix then
link = '*' .. conf.prefix .. '\n**'
else
link = '*'
end
else
link = '\n**'
end
local valid_value = false
if conf.customlink then -- use function to validate and generate link
local label = nextid>1 and nextid
local newlink= require(config.auxiliary)[conf.customlink](val.id,label)
if newlink then
link = link .. newlink
valid_value = true
end
else
if conf.pattern then -- use pattern to determine validity if defined
valid_value = string.match(val.id,'^'..conf.pattern..'$')
elseif conf.patterns then
for _,pattern in ipairs(conf.patterns) do
valid_value = val.id:match('^'..pattern..'$')
if valid_value then break end
end
elseif conf.valid then -- otherwise use function to determine validity
valid_value = require(config.auxiliary)[conf.valid](val.id)
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
link = link .. '<span class="uid">'..tooltip(newlink,val.name)..'</span>'
end
end
if valid_value then
link = link .. getCatForId(conf.category or conf[1])
else
--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
return link
end
--[[==========================================================================]]
--[[ Main ]]
--[[==========================================================================]]
function p.authorityControl(frame)
local function resolveQID(qid)
if qid then
qid = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '')
if mw.wikibase.isValidEntityId(qid) and mw.wikibase.entityExists(qid) then
local sitelink = mw.wikibase.getSitelink(qid)
if sitelink then
return mw.wikibase.getEntityIdForTitle(sitelink) or mw.wikibase.getEntity(qid).id
end
return mw.wikibase.getEntity(qid).id
end
end
end
local conf = config.config
local parentArgs = frame:getParent().args
local auxCats = ''
local rct = false -- boolean to track if there are any links to be returned
local qid,topic
local wikilink = function(qid,hideifequal)
local label,sitelink = mw.wikibase.getLabel(qid),mw.wikibase.getSitelink(qid)
if label then
if sitelink then
local target = mw.title.new(sitelink)
if target==title or (target.isRedirect and target.redirectTarget==title) then -- do not link
return label
else -- make wikilink to article
return '[[' .. sitelink .. '|' .. label .. ']]'
end
else
return label
end
else
auxCats = auxCats .. needsAttention('L')
return qid
end
end
if namespace == 0 then
qid = mw.wikibase.getEntityIdForCurrentPage()
end
if qid then -- article is connected to Wikidata item
if parentArgs.qid and (resolveQID(parentArgs.qid) ~= qid) then -- non-matching qid parameter
auxCats = auxCats .. needsAttention('D')
end
else -- page is not connected to any Wikidata item
qid = resolveQID(parentArgs.qid) -- check qid parameter if no wikidata item is connected
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
elseif parentArgs.qid and parentArgs.qid~='' then -- invalid qid has been supplied, add to tracking cat
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
local sections = {}
local localparams = false
local numsections = 0
for _,_ in ipairs(config.sections) do numsections = numsections + 1 end
for _ = 1,#qids+numsections do table.insert(sections,{}) end
local qslink = '' -- setup link to add using QuickStatements
-- check which identifiers to show/suppress in template
local show = {} -- setup list
local showall = true
local function stripP(pid)
if pid:match("^[Pp]%d+$") then
pid = mw.ustring.gsub(pid,'[Pp]','') --strip P from property number
end
if pid:match("^%d+$") then
return tonumber(pid)
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
showall = false
end
end
addshowlist(frame.args.show) -- check show= parameter on wrapper template
addshowlist(parentArgs.show or parentArgs.country) -- check show parameter on article template
if parentArgs.suppress then
local suppresslist = mw.text.split(parentArgs.suppress,"%s*,%s*") -- split parameter by comma
for _,v in ipairs(suppresslist) do
v = stripP(string.upper(v))
if v then
show[v] = false
auxCats = auxCats .. '[[' .. config.i18n.category .. ':' .. config.i18n.suppressedcat .. ']]'
else
auxCats = auxCats .. needsAttention('P')
end
end
end
local function makeSections(qid,addit)
local tval = {}
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
local function pencil(qid)
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
makeSections(qid,false)
for c = 1,#qids do
makeSections(qids[c],numsections+c)
end
--configure Navbox
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
if localparams then
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
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
if parentArgs.state
and parentArgs.state~=''
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
--out
outString = outString..auxCats
if namespace ~= 0 then
outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':' .. config.i18n.Articles .. ')([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4')
outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':' .. config.i18n.All_articles .. ')([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4')
end
local check = require('Module:Check for unknown parameters')._check
local sortkey
if namespace == 0 then
sortkey = '*' .. title.text
else
sortkey = title.fullText
end
outString = outString .. check({
['unknown'] = '[[' .. config.i18n.category .. ':' .. config.i18n.pageswithparams .. '|' .. sortkey .. ']]',
['preview'] = config.i18n.previewwarning, 'show', 'country', 'suppress', 'additional', 'qid', 'state'
}, parentArgs)
return outString
end
p.makelink = function(conf,val,nextid,qid)
return _makelink(conf,val,nextid,qid)
end
return p