Module:Contentious topics talk banner
Appearance
![]() | This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This template is within the jurisdiction of the Arbitration Committee, as one of its associated enforcement processes. Therefore, you must not make significant changes to the wording or functionality of this template without the Committee's consent. Thank you! |
![]() | This module depends on the following other modules: |
To learn about the template {{Contentious topics/talk notice}}, please see its documentation. This page documents the technical details of the module. There is probably little of interest here unless you are an arbitrator or clerk (or you are curious how things work under the hood!).
Usage
{{#invoke:Contentious topics talk banner|main}}
Technical details
This module is designed to be extensible without needing to edit the module code. Much of its data comes from the following JSON pages:
- Template:Contentious topics/Additional restrictions.json contains per-topic additional restrictions. The
topic-wide
restrictions apply whenever the corresponding CTOP code is given. Theadditional-available
restrictions can be passed as parameters (e.g.|ECR=yes
), and can be used either when a restriction is added to the topic's standard set or when it applies to all articles within a subtopic of the contentious topic designation. - Template:Contentious topics/Restrictions definition.json is the text of the bullet point indicating a restriction is active
- Template:Contentious topics/Standard set.json is a list of all standard set restrictions
- Template:Contentious topics/Category database.json is the name of the category added when a restriction is active (without the
Category:
prefix). The following codes have special meaning:- The
all
category activates for every page tagged with the contentious topic banner - The
bad-topic
category is used whenever a contentious topic code is not found at Template:Contentious topics/list - The
no-date
category is used when there are active, manually-placed restrictions but no|placed-date=
is specified - The
no-topic
category is used when no topics are specified - The
protection-error
category is used when|protection=yes
, but the page is not actually protected
- The
local p = {}
local TableTools = require('Module:TableTools')
local yesno = require('Module:Yesno')
-- Maps normalized topic names to sub-template names (special cases)
local topicMap = {
aa2 = 'Contentious topics/Armenia-Azerbaijan talk notice',
['a-a'] = 'Contentious topics/Armenia-Azerbaijan talk notice',
['a-i'] = 'Contentious topics/Arab-Israeli talk notice',
gmo = 'Contentious topics/gmo talk notice',
tt = 'Contentious topics/The Troubles talk notice'
}
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
-- Asking people to choose the top ten CTOP designations is reasonable
for i = 2, 10 do
add(args[i])
add(args['t' .. i])
add(args['topic' .. i])
end
return topics
end
local function makeBulletPoint(code, frame)
-- given a CTOP code, outputs a bullet point explaining the scope of the contentious topic designation
return '* <b>' .. frame:expandTemplate{ title = "Contentious topics/list", args = { scope=code } } .. '</b>\n'
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame)
local topics = collectTopics(args)
local multipleTopics = TableTools.length(topics) == 1
local restrictionsDatabase = mw.loadJsonData("Template:Contentious topics/Additional restrictions.json")
local restrictions = {}
local currentTitleObject = mw.title.getCurrentTitle()
local subjectTitleObject = currentTitleObject.subjectPageTitle
local messageBody
--== Generate the active restrictions==--
-- helper function which add restrictions if active
local function addRestriction(restriction)
if yesno(args[restriction]) then
table.insert(restrictions, restriction)
end
end
-- add the always available restrictions, if applicable
addRestriction("0RR")
addRestriction("1RR")
addRestriction("BRD")
addRestriction("consensus-required")
-- then check each topic...
for _, topic in ipairs(topics) do
local currentTopicWideRestrictions = restrictionsDatabase["topic-wide"][topic]
--... add anything applicable to the entire topic...
if currentTopicWideRestrictions then
TableTools.merge(currentTopicWideRestrictions, restrictions)
end
--...and add anything available to that topic in particular
local availableTopicRestrictions = restrictionsDatabase["additional-available"][topic]
if availableTopicRestrictions then
for __, availableRestriction in ipairs(availableTopicRestrictions) do
addRestriction(availableRestriction)
end
end
end
-- Finally, we automatically detect the protection level of the subject page
local protectionLevel = subjectTitleObject["protectionLevels"]["edit"]
if protectionLevel then
table.insert(restrictions, protectionLevel)
end
--== End generation of active restrictions ==--
-- is this page under any restrictions?
local underRestrictions = #restrictions == 0
-- gets either "article" or "page", as the case may be
local articleOrPage = frame:exapndTemplate{ template = 'Talkspace detect' , args = { main="article", default="page", other="page" } }
if underRestrictions then
-- we have some active restrictions
messageBody = '<strong style="text-transform: uppercase;">Warning: active arbitration remedies</strong><p>The [[Wikipedia:Contentious topics|contentious topics]] procedure applies to this '
.. articleOrPage .. '.' .. (yesno(args.section) and (' Parts of this ' .. articleOrPage .. ' relate ') or (' This ' .. articleOrPage .. ' relates '))
if multipleTopics then
messageBody = messageBody .. 'to the following contentious topics:</p>\n'
for _, topic in ipairs(topics) do
messageBody = messageBody .. makeBulletPoint(topic, frame)
end
else
messageBody = messageBody .. 'to <b>' ..
frame:expandTemplate{ title = "Contentious topics/list", args = { scope=topics[1] } } ..
'</b>, a contentious topic.'
end
else
end
local 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
}
)
return messageBox
end
--[[
-- Render special topics individually
for _, topic in ipairs(specialTopics) do
table.insert(output, frame:expandTemplate{
title = 'Template wrapper',
args = {['_template'] = topicMap[topic]}
})
end
-- Render all other topics combined using the base template
if #otherTopics > 0 then
local baseArgs = {
_template = 'Contentious topics/page restriction talk notice base',
topic = table.concat(otherTopics, ','),
protection = args.protection,
['0RR'] = args['0RR'],
['1RR'] = args['1RR'],
['consensus-required'] = args['consensus-required'],
BRD = args.BRD,
other = args.other,
['placed-date'] = args['placed-date'],
nocat = args.nocat,
small = args.small,
}
table.insert(output, frame:expandTemplate{
title = 'Template wrapper',
args = baseArgs
})
end
return table.concat(output, '\n')
end
--]]
return p