Module:Sandbox/MJL/ACRedirect

Source: Wikipedia, the free encyclopedia.
--Just smashing things together
require('strict');

local p = {};

local ac = require('Module:Authority control');

local rt = require('Module:Redirect template');

local function renderMainTable()
	local tbl = mw.html.create('table')
		:addClass('nowraplinks')
		:addClass('hlist')

	tbl:css('border-spacing', 0)
	if border == 'subgroup' or border == 'none' then
		tbl
			:addClass('navbox-subgroup')
			:cssText(args.bodystyle)
			:cssText(args.style)
	else  -- regular navbox - bodystyle and style will be applied to the wrapper table
		tbl
			:addClass('navbox-inner')
			:css('background', 'transparent')
			:css('color', 'inherit')
	end
	tbl:cssText(args.innerstyle)

	renderTitleRow(tbl)
	renderAboveRow(tbl)
	for i, listnum in ipairs(listnums) do
		renderListRow(tbl, i, listnum)
	end
	renderBelowRow(tbl)

	return tbl
end

function p.newTable(navboxArgs)
	listnums = {}

	for k, _ in pairs(args) do
		if type(k) == 'string' then
			local listnum = k:match('^list(%d+)$')
			if listnum then table.insert(listnums, tonumber(listnum)) end
		end
	end
	table.sort(listnums)

	border = mw.text.trim(args.border or args[1] or '')
	if border == 'child' then
		border = 'subgroup'
	end

	-- render the main body of the navbox
	local tbl = renderMainTable()

	-- render the appropriate wrapper around the navbox, depending on the border param
	local res = mw.html.create()
	if border == 'none' then
		local nav = res:tag('div')
			:attr('role', 'navigation')
			:node(tbl)
		-- aria-labelledby title, otherwise above, otherwise lone group
		if args.title or args.above or (args.group1 and not args.group2) then
			nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))
		else
			nav:attr('aria-label', 'Navbox')
		end
	elseif border == 'subgroup' then
		-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
		-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
		-- padding being applied, and at the end add a <div> to balance out the parent's </div>
		res
			:wikitext('</div>')
			:node(tbl)
			:wikitext('<div>')
	else
		local nav = res:tag('div')
			:attr('role', 'navigation')
			:addClass('navbox')
			:addClass(args.navboxclass)
			:cssText(args.bodystyle)
			:cssText(args.style)
			:css('padding', '3px')
			:node(tbl)
		-- aria-labelledby title, otherwise above, otherwise lone group
		if args.title or args.above or (args.group1 and not args.group2) then
			nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))
		else
			nav:attr('aria-label', 'Navbox')
		end
	end

	if (args.nocat or 'false'):lower() == 'false' then
		renderTrackingCategories(res)
	end
	return striped(tostring(res))
end

function p.main(frame)
	local resolveEntity = require( 'Module:ResolveEntityId' )
	local parentArgs = frame:getParent().args --WD IDs added here later
	local iParentArgs = 0 --count original/manual parent args only later
	local worldcatCat = ''
	local multipleIdCat = ''
	local suppressedIdCat = ''
	local deprecatedIdCat = ''
	local differentOnWDCat = ''
	local sameOnWDCat = ''
	
	--Redirect aliases to proper parameter names
	for _, a in pairs( ac.aliases ) do
		local alias, param = a[1], a[2]
		if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then
			parentArgs[param] = parentArgs[alias]
		end
	end
	
	--Redirect deprecated parameters to proper parameter names, and assign tracking cat
	for _, d in pairs( ac.deprecated ) do
		local dep, param = d[1], d[2]
		if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then
			parentArgs[param] = parentArgs[dep]
			if namespace == 0 then
				deprecatedIdCat = '[[Category:Wikipedia articles with deprecated authority control identifiers|'..dep..']]'
			end
		end
	end
	
	--Use QID= parameter for testing/example purposes only
	local itemId = nil
	if namespace ~= 0 then
		local qid = parentArgs['qid'] or parentArgs['QID']
		if qid then
			itemId = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '')
			itemId = resolveEntity._id(itemId) --nil if unresolvable
		end
	else
		itemId = mw.wikibase.getEntityIdForCurrentPage()
	end
	
	--Wikidata fallback if available
	if itemId then
		local iMatches = 0
		for _, params in ipairs( ac.conf ) do
			if params[2] > 0 then
				local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
				if val == nil or val == '' then
					local wikidataIds = ac.getIdsFromWikidata( itemId, 'P'..params[2] )
					if wikidataIds[1] then
						if val == '' and (namespace == 0 or testcases) then
							suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|'..params[1]..']]'
						else
							parentArgs[params[1]] = wikidataIds[1] --add ID from WD
						end
					end
				else
					iParentArgs = iParentArgs + 1
					local wikidataIds = ac.getIdsFromWikidata( itemId, 'P'..params[2] )
					if wikidataIds[1] and differentOnWDCat == '' then
						local bMatch = false
						for _, wd in pairs( wikidataIds ) do
							if val == wd then
								iMatches = iMatches + 1
								bMatch = true
							end
						end
						if bMatch == false then
							differentOnWDCat = '[[Category:Pages using authority control with parameters different on Wikidata|'..params[1]..']]'
		end	end	end	end	end
		if iMatches > 0 and iMatches == iParentArgs then
			sameOnWDCat = '[[Category:Pages using authority control with parameters all matching Wikidata]]'
		end
	end
	--Configured rows
	local rct = 0
	local sectionOrder = {'General','National libraries','Art galleries and museums',
						  'Art research institutes','Biographical dictionaries','Scientific databases',
						  'Other'}
	local sections = {
		['General'] = {},
		['National libraries'] = {},
		['Art galleries and museums'] = {},
		['Art research institutes'] = {},
		['Biographical dictionaries'] = {},
		['Scientific databases'] = {},
		['Other'] = {}
	}
	-- Don't show NLP is PLWABN is present, since they both go to the National Library of Poland
	-- and the library has deprecated NLP IDs in favor of PLWABN IDs
	if parentArgs.PLWABN or parentArgs.plwabn then
		parentArgs.NLP = ''
		parentArgs.nlp = ''
	end
	for _, params in ipairs( ac.conf ) do
		local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
		local tval, tlinks = {}, {} --init tables
		if val and val ~= '' and type(params[3]) == 'function' then
			table.insert( tval, val )
			if params.prefix then 
				table.insert( tlinks, params[3]( val, '1' ) )
			else
				table.insert( tlinks, params[3]( val ) )
			end
		end
		--collect other unique vals (IDs) from WD, if present
		if itemId and tval[1] then
			local nextIdVal = 2
			local wikidataIds = ac.getIdsFromWikidata( itemId, 'P'..params[2] )
			for _, v in pairs( wikidataIds ) do
				local bnew = true
				for _, w in pairs( tval ) do
					if v == w then bnew = false end
				end
				if bnew then
					table.insert( tval, v )
					table.insert( tlinks, params[3]( v, tostring(nextIdVal) ) )
					nextIdVal = nextIdVal + 1
				end
			end
		end
		--assemble
		if tval[1] then
			table.insert( sections[params[4]], ac.createRow( params[1], tval, nil, tlinks, true, params.category, params.prefix) )
			rct = rct + 1
			if tval[2] then
				multipleIdCat = ac.getCatForId( 'multiple' )
			end
		end
	
	end
	
	--WorldCat
	local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
	if worldcatId and worldcatId ~= '' then --if WORLDCATID present & unsuppressed
		table.insert( sections['General'], ac.createRow( 'WORLDCATID', worldcatId, '[https://www.worldcat.org/identities/'..mw.uri.encode(worldcatId, 'PATH')..' WorldCat]', nil, false ) ) --Validation?
		worldcatCat = ac.getCatForId( 'WORLDCATID' )
		rct = rct + 1
	elseif worldcatId == nil then --if WORLDCATID absent but unsuppressed
		local viafId = parentArgs['viaf'] or parentArgs['VIAF']
		local lccnId = parentArgs['lccn'] or parentArgs['LCCN']
		if viafId and viafId ~= '' and ac.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validated
			table.insert( sections['General'], ac.createRow( 'VIAF', viafId, '[https://www.worldcat.org/identities/containsVIAFID/'..viafId..' WorldCat (via VIAF)]', nil, false ) )
			if namespace == 0 then 
				worldcatCat = '[[Category:Wikipedia articles with WorldCat-VIAF identifiers]]'
			end
			rct = rct + 1
		elseif lccnId and lccnId ~= '' and ac.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
			local lccnParts = ac.splitLccn( lccnId )
			if lccnParts and lccnParts[1] ~= 'sh' then
				local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]
				table.insert( sections['General'], ac.createRow( 'LCCN', lccnId, '[https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' WorldCat (via Library of Congress)]', nil, false ) )
				if namespace == 0 then
					worldcatCat = '[[Category:Wikipedia articles with WorldCat-LCCN identifiers]]'
				end
			end
			rct = rct + 1
		end
	elseif worldcatId == '' then --if WORLDCATID suppressed
		suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|WORLDCATID]]'
	end
	local pencil = frame:expandTemplate{ title = 'EditAtWikidata', args = args};
	local titleAC = '<b>[[Help:Authority control|Authority control]]'..'<span style="font-weight:normal;">:</span>'..pencil..'</b>';
	local namespaceCategories = rt.namespaceCategories;
	local args = require('Module:Arguments').getArgs(frame, {wrappers = 'Template:Redirect template', valueFunc = valueFunc});
	local namespace = mw.title.getCurrentTitle().namespace;

	--- XXX: this is a HORRIBLE HACK. kill it with fire as soon as https://bugzilla.wikimedia.org/show_bug.cgi?id=12974 is fixed
	local beCompatibleWithBug12974 = args.info and (args.info:find('^[:;#*]', 1) == 1 or args.info:find('{|', 1, true) == 1) and '\n' or ' '
	
	local content = string.format('\n<div class="rcat authority-control">\n*%s%s\n</div>',
		titleAC,
		p.newTable()
	)
	
	for k,v in pairs(namespaceCategories) do
		if args[k .. ' category'] then
			if type(v[1]) == 'function' and v[1](namespace) or v[1] == namespace then
				content = content .. string.format('[[Category:%s]]', args[k .. ' category'])
			elseif args['other category'] then
				content = content .. string.format('[[Category:%s]]', args['other category'])
			else
				content = content .. frame:expandTemplate{title = 'Incorrect redirect template', args = {v[2]}}
			end
		end
	end
	return content
end
--	rt.main(frame)
--end