mic_none

Module:Contentious topics talk banner/sandbox Source: en.wikipedia.org/wiki/Module:Contentious_topics_talk_banner/sandbox

local p = {}
local TableTools = require('Module:TableTools')
local yesno = require('Module:Yesno')
local setToList = require('Module:Set to list')
local restrictionsDatabase = mw.loadJsonData("Template:Contentious topics/Additional restrictions.json")
local restrictionsDefinition = mw.loadJsonData("Template:Contentious topics/Restrictions definition.json")
local standardSet = mw.loadJsonData("Template:Contentious topics/Standard set.json")
local categoryDatabase = mw.loadJsonData("Template:Contentious topics/Category database.json")

local function collectTopics(args, sectionParameter)
    local seen = {}
    local completeTopics = {}
	local partialTopics = {}
	
    local function add(value)
        if value then
            value = mw.text.trim(value)
            if value ~= '' and not seen[value] then
            	local applicableSection = args[value .. '-section'] or sectionParameter
            	if key then
            		partialTopics[value] = applicableSection
            	else
            		table.insert(completeTopics, value)
            	end
            	seen[value] = true
            end
        end
    end

    -- Primary topic params
    add(args.topic)
    add(args.t)
    add(args[1])

    -- Additional topics via numbered forms
    for i = 2, 10 do
        add(args[i])
        add(args['t' .. i])
        add(args['topic' .. i])
    end
	
    return completeTopics, partialTopics
end

function p.main(frame)
    local args = require('Module:Arguments').getArgs(frame)
    local sectionParameter = yesno(args.section) or yesno(args.relatedcontent) -- whether we are a section
    local completeTopics, partialTopics = collectTopics(args, sectionParameter)
    local restrictions = {} -- A list of which restrictions are enabled for easier iteration
    local restrictionFlags = {} -- Track which restrictions are enabled, as a set
    local currentTitleObject = mw.title.getCurrentTitle()
    local subjectTitleObject = currentTitleObject.subjectPageTitle
    local section = sectionParameter or #partialTopics > 0 -- whether any topics apply to parts of the article
    local underRestrictions -- a boolean for whether there are any active restrictions
    local articleOrPage -- the string "article" (if a mainspace page) or "page" (if not)
    local protectionLevel -- the edit protection level
    local numberOfTopics -- positive int which represents the number of topics
    local messageBody -- the text within the message box
	local messageBox -- the message box itself
	local categories = '' -- initialize categories
	local manualRestrictions = false -- have we set any restrictions via |parameters?
	
	--[[
	This area sets active restrictions
	The end goal is to get the restrictions variable into a nice, neat, sorted list of which restrictions are active
	This is a somewhat intense process
	--]]
	
    -- Helpers to add a restriction if it's active and hasn't been added yet
	local function maybeAddRestriction(restriction)
		if yesno(args[restriction]) then
			restrictionFlags[restriction] = true
			manualRestrictions = true
		end
	end
	
	local function alwaysAddRestriction(restriction)
		restrictionFlags[restriction] = true
	end
	
	-- Helper to add a category
	local function addCategory(cat)
		if cat then
			categories = categories .. '[[Category:' .. cat .. '|' .. currentTitleObject.text .. ']]'
		end
	end
	
    -- Add the always-available restrictions
    for _, r in ipairs(standardSet) do
    	maybeAddRestriction(r)
    end

    -- Topic-based restrictions
    for _, topic in ipairs (completeTopics) do
    	local topicWide = restrictionsDatabase["topic-wide"][topic]
        if topicWide then
            for _, restriction in ipairs(topicWide) do
                alwaysAddRestriction(restriction)
            end
        end
        local additional = restrictionsDatabase["additional-available"][topic]
        if additional then
        	for _, restriction in ipairs(additional) do
        		maybeAddRestriction(restriction)
        	end
        end
    end
    
    for topic, scope in pairs(partialTopics) do
        local additional = restrictionsDatabase["additional-available"][topic]
        if additional then
            for _, restriction in ipairs(additional) do
                maybeAddRestriction(restriction)
            end
        end
        local always = restrictionsDatabase["topic-wide"][topic]
        if always then 
        	for _, restriction in ipairs(always) do
        		maybeAddRestriction(restriction)
        	end
    	end
    end
    
    -- Add the protection level
    if yesno(args.protection, true) or yesno(args.aeprotection, true) then
    	protectionLevel = subjectTitleObject.protectionLevels["edit"][1]
		if protectionLevel then
			-- we have a |protection=foo parameter, and the page is protected
			if restrictionFlags["ECR"] then
				-- handle ECR with protection correctly
    			if protectionLevel == "full" then alwaysAddRestriction("full") end
    		else
    			-- no ECR, so just add the protection as normal
    			alwaysAddRestriction(protectionLevel)
			end
			manualRestrictions = true
		else
			-- we have a |protection=foo parameter, but the page is *not* protected
			addCategory(categoryDatabase['protection-error'])
		end
    end
    
    --[[
    Clear duplicate restrictions (e.g. 0RR and 1RR; consensus-required is stronger than BRD)
	--]]
    
	-- if 0RR, then clear 1RR
	if restrictionFlags["0RR"] then
		restrictionFlags["1RR"] = nil
	end

	-- clear BRD if consensus-required is enabled
	if restrictionFlags["consensus-required"] then
		restrictionFlags["BRD"] = nil
	end
	
	-- and finally, convert our set to a list to make it easy to work with
	
    restrictions = setToList(restrictionFlags)
    
	--[[
	Restrictions are now all set. Here, we add additional helper functions and variables necessary for generating the banner
	--]]
	
    -- Check whether any of the added restrictions are enabled
    underRestrictions = #restrictions > 0 or args.other
    
    -- total number of topics applicable
    numberOfTopics = #partialTopics + #completeTopics
    
    -- Determines whether we should use the string "article" or "page"
    local articleOrPage = currentTitleObject:inNamespaces(1) and "article" or "page"
	
	local function addToMessage(s)
		messageBody = messageBody .. s
	end
	
	local function getTopicBlurb(code)
		return frame:expandTemplate{
			title = "Contentious topics/list",
			args = { scope = code }
		}
	end
	
	-- Makes a bullet point for a given contentious topic
	-- the scope is either a string representing the exact scope of the topic
	-- and is nil if it applies to the entire page or unspecified parts of the page
    local function makeTopicBulletPoint(code, scope)
    	topicBlurb = getTopicBlurb(code)
    	if topicBlurb == '' then
    		addCategory(categoryDatabase['bad-topic'])
    	elseif scope then
    		-- scope is not nil, so we write that into the bullet point
    		addToMessage('* <b>' .. topicBlurb .. '</b>, specifically the parts about ' .. scope .. '\n')
	    else
	    	-- scope is nil, so we have nothing to add
	    	addToMessage('* <b>' .. topicBlurb .. '</b>\n')
	    end
    end
    
	-- Makes a restriction bullet point
    local function makeRestrictionBulletPoint(code)
        local def = restrictionsDefinition[code]
        return def and ('* <b>' .. def .. '</b>\n') or ''
    end
	
	--[[
	Error categories
	--]]
	
	-- No contentious topic codes
	if numberOfTopics == 0 then
		addCategory(categoryDatabase['no-topic'])
	end
	
	--[[
	Begin building the messageBody
	--]]
	
    messageBody = '<b>The [[Wikipedia:Contentious topics|contentious topics]] procedure applies to this ' .. articleOrPage .. '.</b>'
       
	-- if there's only one topic, we make a short blurb
	if numberOfTopics == 1 then
		if section then
			for topic, part in pairs(partialTopics) do
				-- there's only one item, so this one runs once
				addToMessage( ' Parts of this '  .. articleOrPage
				.. (yesno(part, false) and '' or (' about <b>' .. part .. '</b>'))
				.. ' relate to <b>'
				.. getTopicBlurb(topic)
				.. '</b>, a contentious topic.')
			end
		else
			addToMessage(' This ' .. articleOrPage .. ' relates to <b>'
			.. getTopicBlurb(completeTopics[1])
			.. '</b>, a contentious topic.</p>'
			)
		end
	else
		local numberOfCompleteTopics = #completeTopics
		if numberOfCompleteTopics ~= 0 then
			addToMessage('<p>The entire ' .. articleOrPage .. ' relates to ')
			if numberOfCompleteTopics > 1 then
				addToMessage('the following contentious topics:</p>\n')
				for _, topic in ipairs(completeTopics) do
					makeTopicBulletPoint(topic, nil)
				end
			else
				addToMessage('<b>' .. getTopicBlurb(completeTopics[1]) .. '</b>, a contentious topic.</p>')
			end
		end
		local numberOfPartialTopics = TableTools.size(partialTopics)
		if numberOfPartialTopics ~= 0 then
			addToMessage('<p>')
			if numberOfCompleteTopics ~= 0 then
				addToMessage('Additionally, parts ')
			else
				addToMessage('Parts ')
			end
			addToMessage('of this ' .. articleOrPage .. ' relate to ')
			if numberOfPartialTopics > 1 then
				addToMessage('the following contentious topics:\n')
				for topic, scope in pairs(partialTopics) do
					if yesno(scope, false) then
						-- the scope parameter is something like 'yes', which we can treat as nil
						makeTopicBulletPoint(topic, nil)
					else
						makeTopicBulletPoint(topic, scope)
					end
				end
			else
				-- There's only one topic and scope, so this loop only runs once
				for topic, scope in pairs(partialTopics) do
					addToMessage(getTopicBlurb(topic))
					if yesno(scope, nil) == nil then
						-- the scope is not a boolean value, so we have a free-text explanation of the applicable parts
						addToMessage(', in particular the parts about ' .. scope)
					else
						addToMessage('.')
					end
				end
			end
		end
	end
	
    if underRestrictions then
        messageBody = '<p style="margin-top:0"><strong style="text-transform: uppercase;">Warning: active arbitration remedies</strong></p>'
            .. messageBody
            .. '<p style="text-decoration:underline; text-align:center; font-size:120%;">The following restrictions apply to everyone editing this ' .. articleOrPage .. ':</p>\n'
        for _, restriction in ipairs(restrictions) do
            addToMessage(makeRestrictionBulletPoint(restriction))
            addCategory(categoryDatabase[restriction])
        end
        if args.other then
        	addToMessage('* <b>' .. args.other .. '</b>\n')
        	addCategory(categoryDatabase["other"])
        end
    end
	
	addToMessage(' Editors are advised to familiarise themselves with the [[Wikipedia:Contentious topics|contentious topics procedures]] before editing this page.')
	
	if not yesno(args.brief) then
		addToMessage(' Editors who repeatedly or seriously fail to adhere to the [[WP:Five pillars|purpose of Wikipedia]], '
		.. 'any expected [[WP:Etiquette|standards of behaviour]], '
        .. 'or any [[WP:List of policies|normal editorial process]] may be blocked or restricted by an administrator.')
	end
	
	if section then
		addToMessage('<p>If it is unclear which parts of the page are related to this contentious topic, '
		.. 'the content in question should be marked within the wiki text by an invisible comment. '
        .. 'If no comment is present, please ask an administrator for assistance. If in doubt it is better to assume that the content is covered.</p>')
	end

	if underRestrictions then
		if args['placed-date'] then
			addToMessage('<p>Restrictions placed: ' .. require('Module:Format time')._main(args['placed-date']) .. '</p>')
		elseif manualRestrictions then
			addCategory(categoryDatabase['no-date'])
		end
	end
	
	-- Now build the messageBox
	
    messageBox = require('Module:Message box').main("tmbox", {
        ["type"] = underRestrictions and "delete" or "content",
        ["small"] = yesno(args.small),
        ["image"] = "[[File:Commons-emblem-"
            .. (underRestrictions and "hand" or "issue")
            .. ".svg|"
            .. (yesno(args.small) and "30" or "40")
            .. "px]]",
        ["text"] = messageBody
    })
	
	-- If ECR is enabled, prepend the ECR warning
	if restrictionFlags["ECR"] then
		messageBox = frame:expandTemplate{ 
			title = "Template:Contentious topics/talk notice/ECR warning", 
			args = { section = section and "yes" or "", small = args.small}} 
		.. messageBox
		
		-- Hard code for [[WP:BER]]
		if TableTools.inArray(completeTopics, "a-i") then
			messageBox = messageBox .. "<p class='PIA-flag' style='display:none; visibility:hidden;'>This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.</p>"
			addCategory("Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict")
		end
	end
	
	--[[
	Categories!!!
	We set the restriction categories back in the if underRestrictions loop
	to avoid looping through the restrictions twice. So we only need to do some cleanup and handle nocat
	
	Because nocat is only for the ultra-rare case of demonstration,
	manually clearing the categories is more efficient
	--]]
	
	if yesno(args.nocat) then
		categories = ''
	else
		addCategory(categoryDatabase["all"])
	end
	
    return messageBox .. categories
end

return p