Module:Authority control: Difference between revisions
Jump to navigation
Jump to search
m (1 revision imported) |
m (1 revision imported: This: work pls) |
||
(2 intermediate revisions by one other user not shown) | |||
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) | local function needsAttention(sortkey) | ||
return '[[ | return '[[' .. config.i18n.category .. ':' .. config.i18n.attentioncat .. '|' .. sortkey .. title.text .. ']]' | ||
end | end | ||
Line 13: | Line 15: | ||
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 29: | 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 51: | 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 63: | 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 100: | 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 106: | 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 115: | 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 qid then -- article is connected to Wikidata item | |||
if qid then -- | if parentArgs.qid and (resolveQID(parentArgs.qid) ~= qid) then -- non-matching qid parameter | ||
if parentArgs.qid and (parentArgs.qid ~= qid) then -- non-matching qid parameter | |||
auxCats = auxCats .. needsAttention('D') | auxCats = auxCats .. needsAttention('D') | ||
end | end | ||
else -- page is not connected to any Wikidata item | else -- page is not connected to any Wikidata item | ||
qid = resolveQID(parentArgs.qid) -- | qid = resolveQID(parentArgs.qid) -- check qid parameter if no wikidata item is connected | ||
if parentArgs.qid and | 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') | auxCats = auxCats .. needsAttention('Q') | ||
end | end | ||
end | end | ||
local qids = {} -- setup any additional QIDs | local qids = {} -- setup any additional QIDs | ||
if parentArgs.additional and 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 = 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 | ||
Line 162: | Line 241: | ||
local show = {} -- setup list | local show = {} -- setup list | ||
local showall = true | 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) | local function addshowlist(list) | ||
if list and list ~= '' then | if list and list ~= '' then | ||
for _,v in ipairs(mw.text.split(string.lower(list),"%s*,%s*")) do | for _,v in ipairs(mw.text.split(string.lower(list),"%s*,%s*")) do | ||
if config.whitelists[v] then | 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 | ||
Line 179: | Line 271: | ||
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 215: | Line 304: | ||
showb = false | showb = false | ||
end | 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 | ||
Line 235: | Line 320: | ||
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 254: | Line 337: | ||
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 262: | 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 278: | 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 290: | 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 307: | 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 topic then -- display in expanded form with topic | if topic then -- display in expanded form with topic | ||
navboxArgs.title = aclink .. ' – ' .. topic .. pencil(qid) | navboxArgs.title = config.i18n.aclink .. ' – ' .. topic .. pencil(qid) | ||
elseif sect == 1 then -- special display when only one section | elseif sect == 1 then -- special display when only one section | ||
if lastsect = | 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 339: | 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 349: | 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) | |||
function | |||
end | end | ||
return p | return p |
Latest revision as of 18:16, 3 January 2024
File:Ambox warning orange.svg | This Lua module is used on approximately 2,110,000 pages, or roughly 392193% 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. |
{{#ifeq:Authority control|doc|{{#if:|Template:Pp}}|{{#switch:
{{#if: | | {{#ifeq:Module|Module | module | other }} }}| module =
{{#switch: protected
| pre-alpha | prealpha | pa = File:Ambox warning blue construction.svg | alpha | a = File:Alpha lowercase.svg | beta | b = File:Greek lc beta.svg | release | r | general | g = File:Green check.svg | protected | protect | p = [[File:{{#switch:Lua error in Module:Effective_protection_level at line 14: attempt to index local 'title' (a nil value).|autoconfirmed=Semi|extendedconfirmed=Extended|accountcreator|templateeditor=Template|#default=Full}}-protection-shackle.svg|40x40px|link=|alt=Protected]] | semiprotected | semiprotect | semi =File:Semi-protection-shackle.svg}} | {{#switch: protected
| pre-alpha | prealpha | pa = This module is rated as pre-alpha. It is unfinished, and may or may not be in active development. It should not be used from article namespace pages. Modules remain pre-alpha until the original editor (or someone who takes one over if it is abandoned for some time) is satisfied with the basic structure.{{#switch: Authority control|doc|sandbox= | {{#ifeq: | true | | }} }} | alpha | a = This module is rated as alpha. It is ready for third-party input, and may be used on a few pages to see if problems arise, but should be watched. Suggestions for new features or changes in their input and output mechanisms are welcome.{{#switch: Authority control|doc|sandbox= | {{#ifeq: | true | | }} }} | beta | b = This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected.{{#switch: Authority control|doc|sandbox= | {{#ifeq: | true | | }} }} | release | r | general | g = This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing.{{#switch: Authority control|doc|sandbox= | {{#ifeq: | true | | }} }} | protected | protect | p = 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.{{#switch: Authority control|doc|sandbox= | {{#ifeq: | true | | }} }} | semiprotected | semiprotect | semi = 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 semi-protected from editing.{{#switch: Authority control|doc|sandbox= | {{#ifeq: | true | | }} }} | #default = Template:Error}} |
| other | #default = Template:Error }}}}
Wikipedia:Authority control |
---|
Template {{#if:|
}}
{{{1}}} |
Module {{#if:|
}}
{{{1}}} |
Config {{#if:|
}}
{{{1}}} |
Auxiliary {{#if:|
}}
{{{1}}} |
Doc module {{#if:|
}}
{{{1}}} |
Category {{#if:|
}}
{{{1}}} |
Lua error in Module:Lua_banner at line 112: attempt to index field 'edit' (a nil value). This module contains the code for the {{Authority control}} template.
Please see Template:Authority control/doc.
{{#if:{{#ifeq:Authori|sandbox|1}}{{#ifeq:Authority control|doc|1}}|| }}
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