モジュール:Authority control

    提供:Wikiminati

    このモジュールについての説明文ページを モジュール:Authority control/doc に作成できます

    require('strict')
    local config = mw.loadData('Module:Authority control/config')
    local p = {}
    local title = mw.title.getCurrentTitle()
    local namespace = title.namespace
    local testcases = (string.sub(title.subpageText,1,9) == 'testcases')
    
    local function needsAttention(sortkey)
    	return '[[Category:Pages with authority control identifiers needing attention|' .. 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 and mw.title.new(cat, 14).exists == false then
    			redlinkcat = needsAttention('N')
    		end
    		if sortkey then
    			cat = '[[Category:'..cat..'|' .. sortkey .. title.text .. ']]'
    		else
    			cat = '[[Category:'..cat..']]'
    		end
    		cat = cat .. redlinkcat
    		return cat
    	else
    		return ''
    	end
    end
    
    local function getCatForId(id,faulty)
    	local cat = 'Articles with '
    	if faulty then cat = cat .. 'faulty ' end
    	cat = cat .. id .. ' identifiers'
    	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 ''
    		link = link .. '[[File:345-409 Ambox warning centered.svg|20px|frameless|link=' .. wdlink .. '|The ' .. conf[1] .. ' id ' .. val.id .. ' is not valid.]]'
    		if conf.errorcat then
    			link = link .. addCat(conf.errorcat)
    		else
    			link = link .. getCatForId(conf.category or conf[1],true)
    		end
    		link = link .. addCat('All articles with faulty authority control information',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
    				return qid
    			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
    	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 and (mw.ustring.lower(title.subpageText) == mw.ustring.lower(topic)) then -- suppress topic display if subpagename equals topic up to case change
    				topic = nil
    			end
    		elseif parentArgs.qid and parentArgs.qid~='' then -- invalid qid has been supplied, add to tracking cat
    			auxCats = auxCats .. needsAttention('Q')
    		end
    	end
    	if topic and mw.wikibase.getSitelink(qid) then -- make wikilink to article
    		topic = '[[' .. mw.wikibase.getSitelink(qid) .. '|' .. topic .. ']]'
    	end
    	local qids = {} -- setup any additional QIDs
    	if parentArgs.additional and parentArgs.additional ~= '' then
    		for _,v in ipairs(mw.text.split(parentArgs.additional,"%s*,%s*")) do
    			v = resolveQID(v)
    			if v == qid then -- duplicate of qid parameter
    				auxCats = auxCats .. needsAttention('R')
    			end
    			table.insert(qids,v)
    		end
    	end
    
    	local sections = {}
    	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
    			pid = tonumber(pid)
    		end
    		return pid
    	end
    	local function addshowlist(list)
    		if list and list ~= '' then
    			for _,v in ipairs(mw.text.split(string.lower(list),"%s*,%s*")) do
    				v = stripP(v)
    				if type(v) == 'string' then -- 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
    				else -- e.g. show=214 to show one particular property
    					show[v] = true
    				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))
    			show[v] = false
    			auxCats = auxCats .. '[[Category:Articles with suppressed authority control identifiers]]'
    		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
    					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 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 '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
    					sectname = mw.wikibase.getLabel(qids[c-numsections]) .. pencil(qids[c-numsections])
    				end
    				navboxArgs['group' .. c] = sectname
    				navboxArgs['list' .. c] = table.concat(sections[c])
    			end
    		end
    		local aclink = '[[Help:Authority control|Authority control]]'
    		if qslink ~= '' then
    			qslink = '<span class="qs autoconfirmed-show">&#32;[[File:Commons to Wikidata QuickStatements.svg|20px|link=https://quickstatements.toolforge.org/#/v1=' .. qslink .. '|Add values to Wikidata.]]</span>'
    		end
    		if topic then -- display in expanded form with topic
    			navboxArgs.title = aclink .. ' &ndash; ' .. topic .. pencil(qid) .. qslink
    		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] = aclink .. pencil(qid) .. qslink
    				else -- other regular section
    					navboxArgs['group' .. lastsect] = aclink .. ': ' .. config.sections[lastsect].name .. pencil(qid) .. qslink
    				end
    			else -- section from additional qid
    				navboxArgs['group' .. lastsect] = aclink .. ': ' .. navboxArgs['group' .. lastsect] .. qslink
    			end
    		else -- add title to navbox
    			navboxArgs.title = aclink .. pencil(qid) .. qslink
    		end
    		outString = Navbox._navbox(navboxArgs)
    	end
    
    	if parentArgs.state then
    		if (parentArgs.state ~= 'collapsed') and (parentArgs.state ~= 'expanded') and (parentArgs.state ~= 'autocollapse') then --invalid state parameter
    			auxCats = auxCats .. needsAttention('S')
    		end
    	end
    	if testcases then
    		auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking
    	end
    
    	--out
    	outString = outString..auxCats
    	if namespace ~= 0 then
    		outString = mw.ustring.gsub(outString,'(%[%[)(Category:Articles)([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4')
    		outString = mw.ustring.gsub(outString,'(%[%[)(Category: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
    	local tracking = check({
    		['unknown']='[[Category:Pages using authority control with parameters|' .. sortkey .. ']]',
    		['preview']='Page using [[Template:Authority control]] with "_VALUE_", please move this to Wikidata.',
    		'show', 'country', 'suppress', 'additional', 'qid', 'state'
    		}, parentArgs)
    	if namespace == 0 -- mainspace
    		or namespace == 14 -- category
    		or namespace == 2 -- user
    		or namespace == 118 then -- draft
    		outString = outString .. tracking
    	end
    	return outString
    end
    
    p.makelink = function(conf,val,nextid,qid)
    	return _makelink(conf,val,nextid,qid)
    end
    
    return p