Jump to content

Module:Contentious topics talk banner

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by HouseBlaster (talk | contribs) at 01:31, 31 May 2025 (fix placed-date). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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)
    local seen = {}
    local topics = {}

    local function add(value)
        if value then
            value = mw.text.trim(value)
            if value ~= '' and not seen[value] then
                seen[value] = true
                table.insert(topics, value)
            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 topics
end

function p.main(frame)
    local args = require('Module:Arguments').getArgs(frame)
    local topics = collectTopics(args)
    local multipleTopics = #topics > 1
    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 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 messageBody
	local messageBox
	local categories = '' -- initialize categories
	
	--[[
	Parameter aliasing
	--]]
	if args.relatedcontent then 
		args.section = true
	end
	
	--[[
	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 addRestriction(restriction, bypassLookup)
        if yesno(args[restriction]) or bypassLookup then
            restrictionFlags[restriction] = true
        end
    end
    local function maybeAddRestriction(restriction) return addRestriction(restriction, false) end
	local function alwaysAddRestriction(restriction) return addRestriction(restriction, true) end
	
    -- Add the always-available restrictions
    for _, r in ipairs(standardSet) do
    	maybeAddRestriction(r)
    end

    -- Topic-based restrictions
    for _, topic in ipairs(topics) 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
    
    -- Add the protection level
    protectionLevel = subjectTitleObject.protectionLevels["edit"][1]
    if protectionLevel then
    	-- we have page protection
    	-- so we check if ECR is active, and if so only care about full protection
    	if restrictionFlags["ECR"] then
    		if protectionLevel == "full" then alwaysAddRestriction("full") end
    	else
    		alwaysAddRestriction(protectionLevel)
		end
    end
    
    --[[
    Clear duplicate restrictions (e.g. 0RR and 1RR; 1RR and 1RR-nocat, etc; consensus-required is stronger than BRD)
	--]]
    
    -- helper function which clears all revert rules, except for the given one
	local function clearOtherRevertRules(rr)
		restrictionFlags["0RR"] = nil
		restrictionFlags["0RR-nocat"] = nil
		restrictionFlags["1RR"] = nil
		restrictionFlags["1RR-nocat"] = nil
		restrictionFlags[rr] = true
	end
    
	-- then use the most applicable revert rule
	if restrictionFlags["0RR"] then
		clearOtherRevertRules("0RR")
	elseif restrictionFlags["0RR-nocat"] then
		clearOtherRevertRules("0RR-nocat")
	elseif restrictionFlags["1RR"] then
		clearOtherRevertRules("1RR")
	end
	-- if we make it to this point, 1RR-nocat is the only one potentially enabled
	-- so we don't need to disable the rest

	-- 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 or args.other1
    
    -- Determines whether we should use the string "article" or "page"
    local articleOrPage = currentTitleObject:inNamespaces(1) and "article" or "page"
	
	-- Makes a bullet point for a given contentious topic
    local function makeTopicBulletPoint(code)
    	topicBlurb = frame:expandTemplate{ title = "Contentious topics/list", args = { scope=code } }
    	if topicBlurb == '' then
    		return '' -- maybe throw an error?
    	else 
	        return '* <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
    
    -- Makes a bullet point for a custom, article-specific restriction
    local function makeOtherRestrictionBulletPoint(r)
    	if r and r ~= '' then
    		return '* <b>' .. r .. '</b>\n'
    	end
    end
	
	local function addCategory(cat)
		if cat then
			categories = categories .. '[[Category:' .. cat .. '|' .. currentTitleObject.text .. ']]'
		end
	end
	--[[
	Begin building the messageBody
	--]]
	
    messageBody = '<b>The [[Wikipedia:Contentious topics|contentious topics]] procedure applies to this '
        .. articleOrPage .. '.</b>'
        .. (yesno(args.section) and (' Parts of this ' .. articleOrPage .. ' relate ') or (' This ' .. articleOrPage .. ' relates '))

    if multipleTopics then
        messageBody = messageBody  .. 'to the following contentious topics:\n'
        for _, topic in ipairs(topics) do
            messageBody = messageBody .. makeTopicBulletPoint(topic)
        end
    else
        messageBody = messageBody .. 'to <b>'
            .. frame:expandTemplate{ title = "Contentious topics/list", args = { scope=topics[1] } }
            .. '</b>, a contentious topic.</p>'
    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
            messageBody = messageBody .. makeRestrictionBulletPoint(restriction)
            addCategory(categoryDatabase[restriction])
        end
    end
	
	messageBody = messageBody .. ' Editors are advised to familiarise themselves with the [[Wikipedia:Contentious topics|contentious topics procedures]] before editing this page.'
	
	if not yesno(args.brief) then
		messageBody = messageBody .. ' 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 yesno(args.section) then
		messageBody = messageBody .. '<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 and args['placed-date'] then
		messageBody = messageBody .. '<p>Restrictions placed: ' .. require('Module:Date')._Date(args['placed-date']):text() .. '</p>'
		addCategory('Wikipedia pages with contentious topic restrictions without a placed date')
	end

    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
    })
	
	--[[
	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