Module:Contentious topics/talk notice/sandbox: Difference between revisions

Content deleted Content added
refactor
test
(8 intermediate revisions by 2 users not shown)
Line 4:
local yesno = require('Module:Yesno')
local checkForUnknownParameters = require('Module:Check for unknown parameters')._check
local messageBoxModule = require('Module:Message box')
local categoryDatabase = mw.loadJsonData("Template:Contentious topics/Category database.json")
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 subtopics = mw.loadJsonData("Template:Contentious topics/Subtopics.json")
local function callFromListTemplate(code, arg)
local topicAliases = mw.loadJsonData("Template:Contentious topics/Aliases.json")
return mw.getCurrentFrame():expandTemplate{
title = "Contentious topics/list/sandbox", -- REMOVE /sandbox when publishing
args = { [arg] = code }
}
end
 
local function collectTopics(args, sectionParameter)
local seen = {}
local completeTopics = {}
local partialTopics = {}
local ECR = {}
local i = 2 -- initialize index
local keepGoing = true -- whether to keep checking for more CTOPs
local function addaddECR(value, scope)
if TableTools.inArray(restrictionsDatabase['topic-wide'][value] or {}, 'ECR') then
if value then
if yesno(scope, nil) then
value = mw.ustring.lower(mw.text.trim(value))
ECR[value] = true
local applicableSection = args[value .. '-section'] or sectionParameter
else
value = topicAliases[value] or value -- normalize to the canonical name after we find the applicableSection
ECR[value] = scope
end
if value ~= '' and not seen[value] then
end
if applicableSection then
end
partialTopics[value] = applicableSection
else
local function add(value)
-- first we clear the partialTopics value
if value then
-- this code is needed for articles which are e.g. entirely Eastern Europe but partially [[WP:APL]]
value = mw.ustring.lower(mw.text.trim(value))
partialTopics[value] = nil
value = callFromListTemplate(value, 'canonical') -- normalize to the canonical name after we find the applicableSection
-- then we add it to the list of completeTopics
local applicableSection = args[value .. '-section'] or sectionParameter
table.insert(completeTopics, value)
addECR(value, applicableSection)
end
if value ~= '' and not seen[value] = truethen
if applicableSection then
keepGoing = true
partialTopics[value] = applicableSection
end
else
end
-- first we clear the partialTopics value
end
-- this code is needed for articles which are e.g. entirely Eastern Europe but partially [[WP:APL]]
partialTopics[value] = nil
-- then we add it to the list of completeTopics
table.insert(completeTopics, value)
end
seen[value] = true
keepGoing = true
end
end
end
 
-- Primary topic params
-- we manually add [1], t1, and topic1 to support {{ct/tn|topic=foo|topic2=bar}}
add(args[1])
add(args.t)
add(args.t1)
add(args.topic)
add(args.topic1)
-- Additional topics via numbered forms
while keepGoing do
keepGoing = false -- this is set back to true if any of the below are found
add(args[i])
add(args['t' .. i])
add(args['topic' .. i])
i = i + 1 -- increment the index
end
return completeTopics, partialTopics
end
 
function p.main(frame)
-- process the input
local args = require('Module:Arguments').getArgs(frame)
local args = require('Module:Arguments').getArgs(frame)
local sectionParameter = yesno(args.section, args.section) or yesno(args.relatedcontent, args.relatedcontent) -- whether we are sections all the way down
local completeTopics, partialTopics = collectTopics(args, sectionParameter) -- completeTopics is a sequence. partialTopics is a table with topics as keys and scope as values
-- check whether we are sections all the way down
local restrictions = {} -- A list of which restrictions are enabled for easier iteration
local sectionParameter = yesno(args.section, args.section) or yesno(args.relatedcontent, args.relatedcontent)
local restrictionFlags = {} -- Track which restrictions are enabled, as a set
local currentTitleObject = mw.title.getCurrentTitle()
-- set the topic variables:
local subjectTitleObject = currentTitleObject.subjectPageTitle
--* completeTopics is a sequence for each topic applying the the entire article
local underRestrictions -- a boolean for whether there are any active restrictions
--* partialTopics is a table with topics as keys and scope as values
local articleOrPage -- the string "article" (if a mainspace article) or "page" (if not)
--* active topics subject to ECR as keys, the scope (nil for the entire article, true for an unspecified scope) as the value
local protectionLevel -- the edit protection level
local numberOfCompleteTopics = #completeTopics, --partialTopics, theECR number of= completecollectTopics(args, topicssectionParameter)
 
local numberOfPartialTopics = TableTools.size(partialTopics) -- the number of partial topics (not a sequence, so we have to use TableTools.size)
-- and then declare a bunch more variables which will be needed later
local numberOfTopics = numberOfCompleteTopics + numberOfPartialTopics -- total number of topics
local restrictions = {} -- A list of which restrictions are enabled for easier iteration
local section = sectionParameter or numberOfPartialTopics > 0 -- whether any topics apply to parts of the article
local restrictionFlags = {} -- Track which restrictions are enabled, as a set
local messageBody -- the text within the message box
local currentTitleObject = mw.title.getCurrentTitle()
local underRestrictions -- a boolean for whether there are any active restrictions
local articleOrPage -- the string "article" (if a mainspace article) or "page" (if not)
local numberOfCompleteTopics = #completeTopics -- the number of complete topics
local numberOfPartialTopics = TableTools.size(partialTopics) -- the number of partial topics (not a sequence, so we have to use TableTools.size)
local numberOfTopics = numberOfCompleteTopics + numberOfPartialTopics -- total number of topics
local section = sectionParameter or numberOfPartialTopics > 0 -- whether any topics apply to parts of the article
local messageBody -- the text within the message box
local messageBox -- the message box itself
local unknownParameterCheck -- the result of [[Module:Check for unknown parameters]]
local unknownParameterTable -- the table to pass to the [[Module:Check for unknown parameters]] call
local categories = '' -- initialize categories
local manualRestrictions = false -- have we set any restrictions via |parameters? Set to true when |parameters are processed
--[[
Line 88 ⟶ 113:
--]]
-- Helpers to add a restriction if it's active and hasn't been added yet
local function maybeAddRestriction(restriction)
if yesno(args[restriction]) then
Line 107 ⟶ 132:
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
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
end
local always = restrictionsDatabase["topic-wide"][topic]
if always then
for _, restriction in ipairs(always) do
-- Allow disabling these restrictions (via |1RR=no or similar)
if yesno(args[restriction], true) or args[restriction] == nil then
restrictionFlags[restriction] = true
else
restrictionFlags[restriction] = nil
end
end
end
end
-- Add the protection level
if yesno(args.protection, true) or yesno(args.aeprotection, true) then
local protectionLevel = subjectTitleObject(currentTitleObject.subjectPageTitle.protectionLevels["edit"] or {nil})[1] -- the or {nil} allows a graceful fail if the subjectPage does not (yet) exist
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
Line 165 ⟶ 190:
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
Line 183 ⟶ 208:
-- and finally, convert our set to a list to make it easy to work with
restrictions = TableTools.keysToList(restrictionFlags, false, true)
--[[
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"
local function addToMessage(s)
messageBody = messageBody .. s
end
-- helper to call the appropriate parameter from [[Template:Contentious topics/list]]
local function callFromList(code, arg)
return frame:expandTemplate{
title = "Contentious topics/list/sandbox", -- REMOVE /sandbox when publishing
args = { [arg] = code }
}
end
local function getTopicBlurb(code)
return callFromListcallFromListTemplate(code, 'scope')
end
local function getSuptopicBlurbgetSubtopicBlurb(code)
return callFromListcallFromListTemplate(code, 'subtopic')
end
-- returns the code for a superTopic
local function getSupertopic(code)
return callFromListcallFromListTemplate(code, 'supertopic')
end
local function makeSubtopicCompleteBlurb(code)
local topicSubpage = callFromListTemplate(code, 'topic-subpage')
return '<b>' .. '[[' .. topicSubpage ..'|'
.. mw.ustring.gsub(topicSubpage, 'Wikipedia:Contentious topics/', '')
.. ']]</b>.'
end
Line 223 ⟶ 248:
-- 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)
local topicBlurb = getTopicBlurb(code)
if topicBlurb == '' then
addCategory(categoryDatabase['bad-topic'])
else
if scope then
-- scope is not nil, so we write that into the bullet point
addToMessage('* <b>' .. topicBlurb .. '</b>, specifically the parts about <b>' .. scope .. '</b>')
else
-- scope is nil, so we have nothing to add
addToMessage('* <b>' .. topicBlurb .. '</b>')
end
-- check for a superTopic (e.g. South Asia is the superTopic of Indian military history)
local superTopic = subtopics[callFromListTemplate(code], 'supertopic')
if subtopics[code]superTopic ~= '' then
-- we have a superTopic, so explain that
addToMessage(', a subtopic of <b>' .. getTopicBlurbmakeSubtopicCompleteBlurb(superTopic) .. '</b>\n')
else
addToMessage('\n')
end
end
end
-- Makes a restriction bullet point
local function makeRestrictionBulletPoint(code)
local def = restrictionsDefinition[code]
return def and ('* <b>' .. def .. '</b>\n') or ''
end
--[[
Line 265 ⟶ 291:
--]]
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
Line 282 ⟶ 308:
theCTOP = completeTopics[1]
end
local suptopicBlurbsubtopicBlurb = getSuptopicBlurbgetSubtopicBlurb(theCTOP)
if suptopicBlurbsubtopicBlurb ~= '' then
local topicSubpage = callFromListTemplate(callFromListTemplate(theCTOP, 'supertopic'), 'topic-subpage')
addToMessage(' to <b>' .. suptopicBlurb .. '</b>, part of the contentious topic designation for <b>' .. getTopicBlurb(subtopics[theCTOP]) .. '</b>.')
addToMessage(' to <b>' .. subtopicBlurb .. '</b>, ' .. ' part of the contentious topic designation for ' .. makeSubtopicCompleteBlurb(theCTOP))
else
addToMessage(' to <b>' .. getTopicBlurb(theCTOP) .. '</b>, a contentious topic.')
end
else
-- there is more than one topic, so we have to do some more processing
-- we handle the cases for partialTopics and completeTopics completely seperately
if numberOfCompleteTopics ~= 0 then
-- if there are any complete topics, insert text about them
addToMessage('<p>The entire ' .. articleOrPage .. ' relates to ')
addToMessage(' The entire ' .. articleOrPage .. ' relates to ')
if numberOfCompleteTopics > 1 then
-- we either loop through adding bullet points
addToMessage('the following contentious topics:</p>\n')
addToMessage('the following contentious topics:\n')
for _, topic in ipairs(completeTopics) do
makeTopicBulletPoint(topic, nil)
end
else
-- or we do it once
addToMessage('<b>' .. getTopicBlurb(completeTopics[1]) .. '</b>')
-- TODO: refactor makeTopicBulletPoint into a more versitile function, allowing it to be called here
local superTopic = subtopics[completeTopics[1]]
addToMessage('<b>')
local superTopic = callFromListTemplate(completeTopics[1], 'supertopic')
if superTopic then
addToMessage(getSubtopicBlurb(completeTopics[1]) .. '</b>, part of the contentious topic designation for <b>' .. getTopicBlurbmakeSubtopicCompleteBlurb(superTopiccompleteTopics[1]) .. '</b>.</p>')
else
addToMessage(getTopicBlurb(completeTopics[1]) .. '</b>, a contentious topic.</p>')
end
end
end
if numberOfPartialTopics ~= 0 then
-- if there are any partial topics, insert text about them. Note that this runs regardless of whether there are any completeTopics
addToMessage('<p>')
if numberOfCompleteTopics ~= 0 then
Line 332 ⟶ 366:
addToMessage(', in particular the parts about <b>' .. scope .. '</b>')
end
local superTopic = subtopics[callFromListTemplate(topic], 'supertopic')
if superTopic ~= '' then
addToMessage('. This is a subtopic of <b>' .. getTopicBlurbmakeSubtopicCompleteBlurb(superTopictopic) .. '</b>.</p>')
else
addToMessage('.</p>')
Line 343 ⟶ 377:
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 or args.other1 then
-- we have some form of other restrictions, so add the category
addCategory(categoryDatabase["other"])
-- then define a helper function to add a restriction
local function addOther(s)
addToMessage('* <b>' .. s .. '</b>\n')
end
-- then add the generic 'other' parameter
if args.other then
addOther(args.other)
end
-- and now we loop to infinity and beyond
local i = 1
while true do
if args['other' .. i] then
addOther(args['other' .. i])
i = i + 1
else
break
end
end
end
-- restrictions are all added to the banner text. Here we specify a date placed and a tracking category if not but we have manual restrictions
end
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
addToMessage(' Editors are advised to familiarise themselves with the [[Wikipedia:Contentious topics|contentious topics procedures]] before editing this page.')
Line 380 ⟶ 420:
addToMessage('<p>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.</p>')
end
Line 386 ⟶ 426:
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')messageBoxModule.main("tmbox", {
["type"] = underRestrictions and "delete" or "content",
["image"] = "[[File:Commons-emblem-"
["small"] = yesno(args.small),
.. (underRestrictions and "hand" or "issue")
["image"] = "[[File:Commons-emblem-"
.. ".svg|40px]]",
.. (underRestrictions and "hand" or "issue")
["text"] = messageBody
.. ".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
Line 422 ⟶ 446:
addCategory("Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict")
end
-- Then build the ECR box
messageBox = messageBoxModule.main("tmbox", {
["class"] = "nonextendedconfirmed-show ECR-edit-request-warning",
["style"] = "background: var(--background-color-destructive-subtle, #ffe9e5); border-color: var(--border-color-destructive, #f54739); color: var(--color-base, #202122);",
["image"] = "[[File:Commons-emblem-hand.svg|40px]]"
}).. messageBox
end
Line 453 ⟶ 484:
addKnownParameter('relatedcontent')
addKnownParameter('section')
 
addKnownParameter('small')
-- then add all of the partialTopics section parameters
for code, _ in pairs(partialTopics) do
Line 480 ⟶ 510:
end
return messageBox .. categories .. unknownParameterCheck
end