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 key = args[value .. '-section'] or sectionParameter
if key then
table.insert(partialTopics, value, key)
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"][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"
--[[ 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
addCategory(categoryDatabase['bad-topic'])
return ''
elseif section then
-- we have some partial sections, so we check whether this is one of them
if partialTopics[code] then
if yesno(partialTopics[code], false) then
-- not given any explicit detail about what applies to the contentious topic, so we specify nothing in particular
return '* <b><span style="text-decoration:underline;">Parts relate to</span> ' .. topicBlurb '</b>\n'
else
-- we are told exactly what parts of the article apply
return '* <b>' .. partialTopics[code] .. ' relate to ' .. topicBlurb '</b>\n'
end
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
--[[
Place into an 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>'
-- .. (section and (' Parts of this ' .. articleOrPage .. ' relate ') or (' This ' .. articleOrPage .. ' relates '))
if numberOfTopics == 1 then
if section then
for topic, part in pairs(partialTopics) do
-- there's only one item, so this one runs once
messageBody = messageBody .. ' Parts of this ' .. articleOrPage
.. (yesno(part, false) and '' or (' about <b>' .. part .. '</b>'))
.. ' relate to <b>'
.. frame:expandTemplate {
title = "Contentious topics/list",
args = { scope = topic }
}
.. '</b>, a contentious topic.'
end
else
messageBody = messageBody .. ' This ' .. articleOrPage ' relates to <b>'
.. frame:expandTemplate {
title = "Contentious topics/list",
args = { scope = completeTopics[1] }
}
.. '</b>, a contentious topic.</p>'
end
else
local numberofCompleteTopics = #completeTopics
if numberofCompleteTopics ~= 0 then
if numberofCompleteTopics > 1 then
-- there are multiple complete topics, so we make a bullet list
-- TODO THIS BIT
else
messageBody = messageBody .. '<p>The entire ' .. articleOrPage .. ' relates to <b>'
.. frame:expandTemplate{
title = "Contentious topics/list",
args = { scope = completeTopics[1] }
}
.. '</b>, a contentious topic. In addition, the following contentious topics apply to part of this ' .. articleOrPage .. '</p>'
end
end
-- THEN CHECK FOR PARTIAL TOPICS
-- LOOP FOR MULTIPLE TOPICS
end
--[[
if numberOfTopics > 1 then
messageBody = messageBody .. 'to the following contentious topics:\n'
for _, topic in ipairs(topics) do
messageBody = messageBody .. makeTopicBulletPoint(topic)
end
else
local topicBlurb = frame:expandTemplate{
title = "Contentious topics/list",
args = { scope=topics[1] } }
if topicBlurb ~= '' then
messageBody = messageBody .. 'to <b>'
.. topicBlurb
..
else
addCategory(categoryDatabase['bad-topic'])
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
messageBody = messageBody .. makeRestrictionBulletPoint(restriction)
addCategory(categoryDatabase[restriction])
end
if args.other then
messageBody = messageBody .. '* <b>' .. args.other .. '</b>\n'
addCategory(categoryDatabase["other"])
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 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 then
if args['placed-date'] then
messageBody = messageBody .. '<p>Restrictions placed: ' .. require('Module:Date')._Date(args['placed-date']):text() .. '</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
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