Difference between revisions of "Module:Protected edit request"

From blackwiki
Jump to navigation Jump to search
blackwiki>Jackmcbarn
(reflect changes to Module:Effective protection level)
blackwiki>Jackmcbarn
Line 1: Line 1:
 +
require('Module:No globals')
 +
 
local yesno = require('Module:Yesno')
 
local yesno = require('Module:Yesno')
 
local makeMessageBox = require('Module:Message box').main
 
local makeMessageBox = require('Module:Message box').main
  
-- may not need these. lazily initalize
+
local activeBox -- lazily initialized if we get an active request
local makeToolbar, getPagetype, effectiveProtectionLevel
 
local modulesLoaded = false
 
 
 
----------------------------------------------------------------------
 
-- Helper functions
 
----------------------------------------------------------------------
 
 
 
local function makeWikilink(page, display)
 
if display then
 
return mw.ustring.format('[[%s|%s]]', page, display)
 
else
 
return mw.ustring.format('[[%s]]', page)
 
end
 
end
 
 
 
----------------------------------------------------------------------
 
-- Title class
 
----------------------------------------------------------------------
 
 
 
-- This is basically the mw.title class with some extras thrown in.
 
 
 
local title = {}
 
title.__index = title
 
 
 
function title.getProtectionLevelText(protectionLevel)
 
-- Gets the text to use in anchors and urn links.
 
local levels = {unprotected = 'editunprotected', autoconfirmed = 'editsemiprotected', templateeditor = 'edittemplateprotected', sysop = 'editprotected'}
 
return levels[protectionLevel]
 
end
 
 
 
function title.new(...)
 
local success, obj = pcall(mw.title.new, ...)
 
if not (success and obj) then return end
 
 
 
-- Add a protectionLevel property.
 
obj.protectionLevel = effectiveProtectionLevel(nil, obj.exists and 'edit' or 'create', obj)
 
if obj.protectionLevel == '*' then
 
-- Make unprotected pages return "unprotected".
 
obj.protectionLevel = 'unprotected'
 
elseif obj.protectionLevel == 'user' then
 
-- If we just need to be registered, pretend we need to be autoconfirmed, since it's the closest thing we have.
 
obj.protectionLevel = 'autoconfirmed'
 
elseif obj.protectionLevel == 'accountcreator' then
 
-- Lump titleblacklisted pages in with template-protected pages, since templateeditors can do both.
 
obj.protectionLevel = 'templateeditor'
 
end
 
 
 
-- Add a pagetype property.
 
obj.pagetype = getPagetype{page = obj.prefixedText, defaultns = 'all'}
 
 
-- Add link-making methods.
 
function obj:makeUrlLink(query, display)
 
return mw.ustring.format('[%s %s]', self:fullUrl(query), display)
 
end
 
 
 
function obj:makeViewLink(display)
 
return self:makeUrlLink({redirect = 'no'}, display)
 
end
 
 
 
function obj:makeEditLink(display)
 
return self:makeUrlLink({action = 'edit'}, display)
 
end
 
 
 
function obj:makeHistoryLink(display)
 
return self:makeUrlLink({action = 'history'}, display)
 
end
 
 
 
function obj:makeLastEditLink(display)
 
return self:makeUrlLink({diff = 'cur', oldid = 'prev'}, display)
 
end
 
 
 
function obj:makeWhatLinksHereLink(display)
 
return makeWikilink('Special:WhatLinksHere/' .. self.prefixedText, display)
 
end
 
 
 
function obj:makeCompareLink(otherTitle, display)
 
display = display or 'diff'
 
local comparePagesTitle = title.new('Special:ComparePages')
 
return comparePagesTitle:makeUrlLink({page1 = self.prefixedText, page2 = otherTitle.prefixedText}, display)
 
end
 
 
 
function obj:makeLogLink(logType, display)
 
local logTitle = title.new('Special:Log')
 
return logTitle:makeUrlLink({type = logType, page = self.prefixedText}, display)
 
end
 
 
 
function obj:urlEncode()
 
return mw.uri.encode(self.prefixedText, 'WIKI')
 
end
 
 
 
function obj:makeUrnLink(boxProtectionLevel)
 
-- Outputs a urn link. The protection level is taken from the template, rather than detected from page itself,
 
-- as the detection may be inaccurate for cascade-protected and title-blacklisted pages as of Nov 2013.
 
local protectionLinkText = title.getProtectionLevelText(boxProtectionLevel)
 
return mw.ustring.format('[urn:x-wp-%s:%s <span/>]', protectionLinkText, self:urlEncode())
 
end
 
 
 
-- Get a subpage title object, but go through pcall rather than use the unprotected mw.title:subPageTitle.
 
function obj:getSubpageTitle(subpage)
 
return title.new(self.prefixedText .. '/' .. subpage)
 
end
 
 
return obj
 
end
 
 
 
----------------------------------------------------------------------
 
-- TitleTable class
 
----------------------------------------------------------------------
 
 
 
local titleTable = {}
 
titleTable.__index = titleTable
 
 
 
function titleTable.new(args)
 
-- Get numerical arguments and make title objects for each of them.
 
local nums = {}
 
for k, v in pairs(args) do
 
if type(k) == 'number' then
 
table.insert(nums, k)
 
end
 
end
 
table.sort(nums)
 
local titles = {}
 
for _, num in ipairs(nums) do
 
local title = title.new(args[num])
 
table.insert(titles, title)
 
end
 
-- Get the current title, and get the subject title if no titles were specified.
 
titles.currentTitle = mw.title.getCurrentTitle()
 
if #titles < 1 then
 
local subjectNs = titles.currentTitle.subjectNsText
 
if subjectNs ~= '' then
 
subjectNs = subjectNs .. ':'
 
end
 
table.insert(titles, title.new(subjectNs .. titles.currentTitle.text))
 
end
 
-- Set the metatable.
 
setmetatable(titles, titleTable)
 
return titles
 
end
 
 
 
function titleTable:memoize(memoField, func, ...)
 
if self[memoField] ~= nil then
 
return self[memoField]
 
else
 
self[memoField] = func(...)
 
return self[memoField]
 
end
 
end
 
 
 
function titleTable:titleIterator()
 
local i = 0
 
local n = #self
 
return function()
 
i = i + 1
 
if i <= n then
 
return self[i]
 
end
 
end
 
end
 
 
 
function titleTable:hasSameProperty(memoField, getPropertyFunc)
 
-- If the titles table has more than one title in it, check if they have the same property.
 
-- The property is found using the getPropertyFunc function, which takes a title object as its single argument.
 
 
local function hasSameProperty(getPropertyFunc)
 
local property
 
for i, obj in ipairs(self) do
 
if i == 1 then
 
property = getPropertyFunc(obj)
 
elseif getPropertyFunc(obj) ~= property then
 
return false
 
end
 
end
 
return true
 
end
 
 
 
return self:memoize(memoField, hasSameProperty, getPropertyFunc)
 
end
 
 
 
function titleTable:hasSameExistenceStatus()
 
-- Returns true if all the titles exist, or if they all don't exist. Returns false if there is a mixture of existence statuses.
 
return self:hasSameProperty('sameExistenceStatus', function (title) return title.exists end)
 
end
 
 
 
function titleTable:hasSameProtectionStatus()
 
-- Checks if all the titles have the same protection status (either for creation protection or for edit-protection - the two are not mixed).
 
local sameExistenceStatus = self:hasSameExistenceStatus()
 
if sameExistenceStatus then
 
return self:hasSameProperty('sameProtectionStatus', function (title) return title.protectionLevel end)
 
else
 
return sameExistenceStatus
 
end
 
end
 
 
 
function titleTable:hasSamePagetype()
 
-- Checks if all the titles have the same pagetype.
 
return self:hasSameProperty('samePagetype', function (title) return title.pagetype end)
 
end
 
 
 
function titleTable:propertyExists(memoField, getPropertyFunc)
 
-- Checks if a title with a certain property exists.
 
-- The property is found using the getPropertyFunc function, which takes a title object as its single argument
 
-- and should return a boolean value.
 
local function propertyExists(getPropertyFunc)
 
for titleObj in self:titleIterator() do
 
if getPropertyFunc(titleObj) then
 
return true
 
end
 
end
 
return false
 
end
 
return self:memoize(memoField, propertyExists, getPropertyFunc)
 
end
 
 
 
function titleTable:hasNonInterfacePage()
 
return self:propertyExists('nonInterfacePage', function (titleObj) return titleObj.namespace ~= 8 end)
 
end
 
 
 
function titleTable:hasTemplateOrModule()
 
return self:propertyExists('templateOrModule', function (titleObj) return titleObj.namespace == 10 or titleObj.namespace == 828 end)
 
end
 
 
 
function titleTable:hasNonTemplateOrModule()
 
return self:propertyExists('nontemplateormodule', function (titleobj) return titleobj.namespace ~= 10 and titleobj.namespace ~= 828 end)
 
end
 
 
 
function titleTable:hasOtherProtectionLevel(level)
 
for titleObj in self:titleIterator() do
 
if titleObj.protectionLevel ~= level then
 
return true
 
end
 
end
 
return false
 
end
 
 
 
function titleTable:getProtectionLevels()
 
local function getProtectionLevels()
 
local levels = {}
 
for titleObj in self:titleIterator() do
 
local level = titleObj.protectionLevel
 
levels[level] = true
 
end
 
return levels
 
end
 
return self:memoize('protectionLevels', getProtectionLevels)
 
end
 
 
 
----------------------------------------------------------------------
 
-- Blurb class definition
 
----------------------------------------------------------------------
 
 
 
local blurb = {}
 
blurb.__index = blurb
 
 
 
function blurb.new(titleTable, boxProtectionLevel)
 
local obj = {}
 
obj.titles = titleTable
 
obj.boxProtectionLevel = boxProtectionLevel
 
obj.linkCount = 0 -- Counter for the number of total items in the object's link lists.
 
setmetatable(obj, blurb)
 
return obj
 
end
 
 
 
-- Static methods --
 
 
 
function blurb.makeParaText(name, val)
 
local pipe = mw.text.nowiki('|')
 
local equals = mw.text.nowiki('=')
 
val = val and ("''" .. val .. "''") or ''
 
return mw.ustring.format('<code style="white-space: nowrap;">%s%s%s%s</code>', pipe, name, equals, val)
 
end
 
 
 
function blurb.makeTemplateLink(s)
 
return mw.ustring.format('%s[[Template:%s|%s]]%s', mw.text.nowiki('{{'), s, s, mw.text.nowiki('}}'))
 
end
 
 
 
function blurb:makeProtectionText()
 
local boxProtectionLevel = self.boxProtectionLevel
 
local levels = {unprotected = 'unprotected', autoconfirmed = 'semi-protected', templateeditor = 'template-protected', sysop = 'fully protected'}
 
for level, protectionText in pairs(levels) do
 
if level == boxProtectionLevel then
 
return mw.ustring.format('[[Help:Protection|%s]]', protectionText)
 
end
 
end
 
end
 
 
 
function blurb.getPagetypePlural(title)
 
local pagetype = title.pagetype
 
if pagetype == 'category' then
 
return 'categories'
 
else
 
return pagetype .. 's'
 
end
 
end
 
 
 
-- Normal methods --
 
 
 
function blurb:makeLinkList(title)
 
local tbargs = {} -- The argument list to pass to Module:Toolbar
 
tbargs.style = 'font-size: smaller;'
 
tbargs.separator = 'dot'
 
-- Page links.
 
table.insert(tbargs, title:makeEditLink('edit'))
 
table.insert(tbargs, title:makeHistoryLink('history'))
 
table.insert(tbargs, title:makeLastEditLink('last'))
 
table.insert(tbargs, title:makeWhatLinksHereLink('links'))
 
-- Sandbox links.
 
local sandboxTitle = title:getSubpageTitle('sandbox')
 
if sandboxTitle and sandboxTitle.exists then
 
table.insert(tbargs, sandboxTitle:makeViewLink('sandbox'))
 
table.insert(tbargs, sandboxTitle:makeEditLink('edit sandbox'))
 
table.insert(tbargs, sandboxTitle:makeHistoryLink('sandbox history'))
 
table.insert(tbargs, sandboxTitle:makeLastEditLink('sandbox last edit'))
 
table.insert(tbargs, title:makeCompareLink(sandboxTitle, 'sandbox diff'))
 
end
 
-- Test cases links.
 
local testcasesTitle = title:getSubpageTitle('testcases')
 
if testcasesTitle and testcasesTitle.exists then
 
table.insert(tbargs, testcasesTitle:makeViewLink('test cases'))
 
end
 
-- Transclusion count link.
 
if title.namespace == 10 or title.namespace == 828 then -- Only add the transclusion count link for templates and modules.
 
local tclink = mw.uri.new{
 
host = 'tools.wmflabs.org',
 
path = '/templatecount/index.php',
 
query = {
 
lang = 'en',
 
name = title.text,
 
namespace = title.namespace,
 
},
 
fragment = 'bottom'
 
}
 
tclink = string.format('[%s transclusion count]', tostring(tclink))
 
table.insert(tbargs, tclink)
 
end
 
-- Protection log link.
 
if title.namespace ~= 8 then -- MediaWiki pages don't have protection log entries.
 
table.insert(tbargs, title:makeLogLink('protect', 'protection log'))
 
end
 
self.linkCount = self.linkCount + #tbargs -- Keep track of the number of total links created by the object.
 
return makeToolbar(tbargs)
 
end
 
 
 
function blurb:makeLinkLists()
 
local titles = self.titles
 
if #titles == 1 then
 
return self:makeLinkList(titles[1])
 
else
 
local ret = {}
 
table.insert(ret, '<ul>')
 
for i, titleObj in ipairs(titles) do
 
table.insert(ret, mw.ustring.format('<li>%s %s</li>', titleObj:makeViewLink(titleObj.prefixedText), self:makeLinkList(titleObj)))
 
end
 
table.insert(ret, '</ul>')
 
return table.concat(ret)
 
end
 
end
 
 
 
function blurb:makeIntro()
 
local titles = self.titles
 
local requested = 'It is [[Wikipedia:Edit requests|requested]] that'
 
local protectionText
 
if titles:hasNonInterfacePage() then
 
protectionText = ' ' .. self:makeProtectionText()
 
else
 
protectionText = '' -- Interface pages cannot be unprotected, so we don't need to explicitly say they are protected.
 
end
 
-- Deal with cases where we are passed multiple titles.
 
if #titles > 1 then
 
local pagetype
 
if titles:hasSamePagetype() then
 
pagetype = blurb.getPagetypePlural(titles[1])
 
else
 
pagetype = 'pages'
 
end
 
return mw.ustring.format("'''%s edits be made to the following%s %s''':", requested, protectionText, pagetype)
 
end
 
-- Deal with cases where we are passed only one title.
 
local title = titles[1]
 
local stringToFormat
 
if title.exists then
 
stringToFormat = '%s an edit be made to the%s %s at %s.'
 
else
 
stringToFormat = '%s the%s %s at %s be created.'
 
end
 
stringToFormat = "'''" .. stringToFormat .. "'''"
 
return mw.ustring.format(stringToFormat, requested, protectionText, title.pagetype, title:makeViewLink(title.prefixedText))
 
end
 
 
 
function blurb:makeBody()
 
local titles = self.titles
 
local protectionLevels = titles:getProtectionLevels()
 
local boxProtectionLevel = self.boxProtectionLevel
 
local hasNonInterfacePage = titles:hasNonInterfacePage()
 
local isPlural = false
 
if #titles > 1 then
 
isPlural = true
 
end
 
 
 
local descriptionText = "This template must be followed by a '''complete and specific description''' of the request, "
 
if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
 
local editText = 'edit'
 
if isPlural then
 
editText = editText .. 's'
 
end
 
local descriptionCompleteText = mw.ustring.format('so that an editor unfamiliar with the subject matter could complete the requested %s immediately.', editText)
 
descriptionText = descriptionText .. descriptionCompleteText
 
else
 
descriptionText = descriptionText .. 'that is, specify what text should be removed and a verbatim copy of the text that should replace it. '
 
.. [["Please change ''X''" is '''not acceptable''' and will be rejected; the request '''must''' be of the form "please change ''X'' to ''Y''".]]
 
end
 
 
 
local smallText = ''
 
if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
 
local templateFullText
 
if boxProtectionLevel == 'sysop' then
 
templateFullText = 'fully protected'
 
elseif boxProtectionLevel == 'templateeditor' then
 
templateFullText = 'template-protected'
 
end
 
smallText = 'Edit requests to ' .. templateFullText .. " pages should only be used for edits that are either '''uncontroversial''' or supported by [[Wikipedia:Consensus|consensus]]."
 
.. " If the proposed edit might be controversial, discuss it on the protected page's talk page '''before''' using this template."
 
else
 
local userText
 
if boxProtectionLevel == 'autoconfirmed' then
 
userText = '[[Wikipedia:User access levels#Autoconfirmed|autoconfirmed]] user'
 
else
 
userText = 'user'
 
end
 
local answeredPara = blurb.makeParaText('answered', 'no')
 
local stringToFormat = 'The edit may be made by any %s. '
 
.. [[Remember to change the %s parameter to "'''yes'''" when the request has been accepted, rejected or on hold awaiting user input. ]]
 
.. "This is so that inactive or completed requests don't needlessly fill up the edit requests category. "
 
.. 'You may also wish to use the %s template in the response.'
 
smallText = mw.ustring.format(stringToFormat, userText, answeredPara, blurb.makeTemplateLink('ESp'))
 
end
 
if hasNonInterfacePage then
 
smallText = smallText .. ' To request that a page be protected or unprotected, make a [[Wikipedia:Requests for page protection|protection request]].'
 
end
 
if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
 
smallText = smallText .. ' When the request has been completed or denied, please add the ' .. blurb.makeParaText('answered', 'yes') .. ' parameter to deactivate the template.'
 
end
 
return mw.ustring.format('%s\n<p style="font-size:smaller; line-height:1.3em;">\n%s\n</p>', descriptionText, smallText)
 
end
 
 
 
function blurb:export()
 
local intro = self:makeIntro()
 
local linkLists = self:makeLinkLists()
 
local body = self:makeBody()
 
-- Start long links lists on a new line.
 
local linkListSep = ' '
 
if self.linkCount > 5 then
 
linkListSep = '<br />'
 
end
 
return mw.ustring.format('%s%s%s\n\n%s', intro, linkListSep, linkLists, body)
 
end
 
  
 
----------------------------------------------------------------------
 
----------------------------------------------------------------------
Line 469: Line 15:
 
function box.new(protectionType, args)
 
function box.new(protectionType, args)
 
local obj = {}
 
local obj = {}
 +
setmetatable(obj, box)
 
obj.tmboxArgs = {} -- Used to store arguments to be passed to tmbox by the box:export method.
 
obj.tmboxArgs = {} -- Used to store arguments to be passed to tmbox by the box:export method.
 
-- Set data fields.
 
-- Set data fields.
 
obj.tmboxArgs.attrs = { ['data-origlevel'] = protectionType }
 
obj.tmboxArgs.attrs = { ['data-origlevel'] = protectionType }
local answered = args.answered or args.ans
 
obj.answered = yesno(answered, true) or false
 
if not obj.answered then
 
if not modulesLoaded then
 
-- We know we'll need these now, so go ahead and load them
 
modulesLoaded = true
 
makeToolbar = require('Module:Toolbar')._main
 
getPagetype = require('Module:Pagetype')._main
 
effectiveProtectionLevel = require('Module:Effective protection level').main
 
end
 
local boxProtectionLevels = {semi = 'autoconfirmed', template = 'templateeditor', full = 'sysop'}
 
obj.boxProtectionLevel = boxProtectionLevels[protectionType]
 
obj.demo = yesno(args.demo)
 
-- Set dependent objects.
 
obj.titles = titleTable.new(args)
 
if not yesno(args.force) and obj.titles:hasSameProperty('sameProtectionStatus', function (title) return title.protectionLevel end) and obj.titles[1].protectionLevel ~= 'unprotected' then
 
obj.boxProtectionLevel = obj.titles[1].protectionLevel
 
end
 
obj.blurb = blurb.new(obj.titles, obj.boxProtectionLevel)
 
end
 
setmetatable(obj, box)
 
 
return obj
 
return obj
 
end
 
end
Line 503: Line 29:
 
end
 
end
  
function box:setImage()
+
function box:export()
local titles = self.titles
+
self:setArg('smalltext', "This [[Wikipedia:Edit requests|edit request]] has been answered. Set the <code style=\"white-space: nowrap;\">&#124;answered&#61;</code> or <code style=\"white-space: nowrap;\">&#124;ans&#61;</code> parameter to '''no''' to reactivate your request.")
local boxProtectionLevel = self.boxProtectionLevel
 
local padlock
 
if boxProtectionLevel == 'sysop' and not titles:hasNonTemplateOrModule() then
 
padlock = 'Padlock-red.svg'
 
elseif boxProtectionLevel == 'sysop' then
 
padlock = 'Padlock.svg'
 
elseif boxProtectionLevel == 'templateeditor' then
 
padlock = 'Padlock-pink.svg'
 
elseif boxProtectionLevel == 'autoconfirmed' then
 
padlock = 'Padlock-silver.svg'
 
else
 
padlock = 'Padlock-bronze-open.svg'
 
end
 
local stringToFormat = '[[File:%s|%dpx|alt=|link=]]'
 
local smallPadlock = mw.ustring.format(stringToFormat, padlock, 25)
 
local largePadlock = mw.ustring.format(stringToFormat, padlock, 60)
 
self:setArg('smallimage', smallPadlock)
 
self:setArg('image', largePadlock)
 
end
 
 
 
function box:setBlurbText()
 
local blurbText = self.blurb:export()
 
self:setArg('text', blurbText)
 
end
 
 
 
function box:setAnsweredText()
 
local answeredText = mw.ustring.format(
 
"This [[Wikipedia:Edit requests|edit request]] has been answered. Set the %s or %s parameter to '''no''' to reactivate your request.",
 
blurb.makeParaText('answered'), blurb.makeParaText('ans')
 
)
 
self:setArg('smalltext', answeredText)
 
end
 
 
 
function box:exportRequestTmbox()
 
self:setImage()
 
self:setBlurbText()
 
self:setArg('class', 'editrequest')
 
self:setArg('id', title.getProtectionLevelText(self.boxProtectionLevel)) -- for anchor. yes, this leads to multiple elements with the same ID. we should probably fix this at some point
 
return makeMessageBox('tmbox', self.tmboxArgs)
 
end
 
 
 
function box:exportAnsweredTmbox()
 
self:setAnsweredText()
 
 
self:setArg('small', true)
 
self:setArg('small', true)
 
self:setArg('class', 'editrequest')
 
self:setArg('class', 'editrequest')
 
return makeMessageBox('tmbox', self.tmboxArgs)
 
return makeMessageBox('tmbox', self.tmboxArgs)
end
 
 
function box:exportRequestCategories()
 
local cats = {}
 
local boxProtectionLevel = self.boxProtectionLevel
 
local function addCat(cat)
 
table.insert(cats, mw.ustring.format('[[Category:%s]]', cat))
 
end
 
local protectionCats = {
 
autoconfirmed = 'Wikipedia semi-protected edit requests',
 
templateeditor = 'Wikipedia template-protected edit requests',
 
sysop = 'Wikipedia protected edit requests'
 
}
 
addCat(protectionCats[boxProtectionLevel])
 
if self.titles:hasOtherProtectionLevel(boxProtectionLevel) then
 
addCat('Wikipedia edit requests possibly using incorrect templates')
 
end
 
return table.concat(cats)
 
end
 
 
function box:exportUrnLinks()
 
local ret = {}
 
local boxProtectionLevel = self.boxProtectionLevel
 
for titleObj in self.titles:titleIterator() do
 
table.insert(ret, titleObj:makeUrnLink(boxProtectionLevel))
 
end
 
return mw.ustring.format('<span class="plainlinks" style="display:none">%s</span>', table.concat(ret))
 
end
 
 
function box:export()
 
local ret = {}
 
if self.answered then
 
table.insert(ret, self:exportAnsweredTmbox())
 
elseif self.titles.currentTitle.isTalkPage or self.demo then
 
table.insert(ret, self:exportRequestTmbox())
 
table.insert(ret, self:exportUrnLinks())
 
if not self.demo then
 
table.insert(ret, self:exportRequestCategories())
 
end
 
else
 
table.insert(ret, '<span class="error">Error: Protected edit requests can only be made on the talk page.</span>[[Category:Non-talk pages requesting an edit to a protected page]]')
 
end
 
return table.concat(ret)
 
 
end
 
end
  
Line 603: Line 43:
  
 
function p.main(protectionType, args)
 
function p.main(protectionType, args)
local requestBox = box.new(protectionType, args)
+
local boxType = box
 +
if not yesno(args.answered or args.ans, true) then
 +
if not activeBox then
 +
activeBox = require('Module:Protected edit request/active')(box, yesno, makeMessageBox)
 +
end
 +
boxType = activeBox
 +
end
 +
local requestBox = boxType.new(protectionType, args)
 
return requestBox:export()
 
return requestBox:export()
 
end
 
end

Revision as of 19:58, 11 May 2014

This module produces a message box used to request edits to protected pages. Edit requests can be made for fully protected, template-protected and semi-protected pages, and it is possible to request edits to multiple pages at once.

This module should be used on the talk page of the page to be edited. If you are not able to place it directly on this talk page, then you can specify the page to be edited with the positional parameters. You can also specify multiple pages to be edited, if this is more convenient than making multiple edit requests in different locations.

Syntax

The module has five functions, one for each available protection level:

Function Protection level Template
interface CSS/JS protection {{edit interface-protected}}
full Full protection {{edit fully-protected}}
template Template protection {{edit template-protected}}
extended Extended confirmed protection {{edit extended-protected}}
semi Semi-protection {{edit semi-protected}}
Basic usage
{{#invoke:protected edit request|function}}
Specify pages to be edited
{{#invoke:protected edit request|function|First page to be edited|Second page to be edited|...}}
Deactivate a request
{{#invoke:protected edit request|function|answered=yes}}
Force a request's protection level rather than allowing auto-detection
{{#invoke:protected edit request|function|force=yes}}
All parameters
{{#invoke:protected edit request|function
| First page to be edited|Second page to be edited|Third page to be edited|...
| answered = 
| ans      = 
| demo     = 
| force    = 
}}

Categories

The template categorises the page depending on the protection level of the pages to be edited.

Function Category
interface Category:Wikipedia interface-protected edit requests
full Category:Wikipedia fully-protected edit requests
template Category:Wikipedia template-protected edit requests
extended Category:Wikipedia extended-confirmed-protected edit requests
semi Category:Wikipedia semi-protected edit requests

The module attempts to detect the protection level of the pages used. If one or more of the pages are unprotected, or multiple pages with different protection levels are specified, the page is categorized in Category:Wikipedia edit requests possibly using incorrect templates. Otherwise, if the force parameter is not set, it is automatically categorized in the correct protection level.


require('Module:No globals')

local yesno = require('Module:Yesno')
local makeMessageBox = require('Module:Message box').main

local activeBox -- lazily initialized if we get an active request

----------------------------------------------------------------------
-- Box class definition
----------------------------------------------------------------------

local box = {}
box.__index = box

function box.new(protectionType, args)
	local obj = {}
	setmetatable(obj, box)
	obj.tmboxArgs = {} -- Used to store arguments to be passed to tmbox by the box:export method.
	-- Set data fields.
	obj.tmboxArgs.attrs = { ['data-origlevel'] = protectionType }
	return obj
end

function box:setArg(key, value)
	-- This sets a value to be passed to tmbox.
	if key then
		self.tmboxArgs[key] = value
	end
end

function box:export()
	self:setArg('smalltext', "This [[Wikipedia:Edit requests|edit request]] has been answered. Set the <code style=\"white-space: nowrap;\">&#124;answered&#61;</code> or <code style=\"white-space: nowrap;\">&#124;ans&#61;</code> parameter to '''no''' to reactivate your request.")
	self:setArg('small', true)
	self:setArg('class', 'editrequest')
	return makeMessageBox('tmbox', self.tmboxArgs)
end

----------------------------------------------------------------------
-- Process arguments and initialise objects
----------------------------------------------------------------------

local p = {}

function p.main(protectionType, args)
	local boxType = box
	if not yesno(args.answered or args.ans, true) then
		if not activeBox then
			activeBox = require('Module:Protected edit request/active')(box, yesno, makeMessageBox)
		end
		boxType = activeBox
	end
	local requestBox = boxType.new(protectionType, args)
	return requestBox:export()
end

local function makeWrapper(protectionType)
	return function (frame)
		-- If called via #invoke, use the args passed into the invoking template, or the args passed to #invoke if any exist.
		-- Otherwise assume args are being passed directly in from the debug console or from another Lua module.
		local origArgs
		if frame == mw.getCurrentFrame() then
			origArgs = frame:getParent().args
			for k, v in pairs(frame.args) do
				origArgs = frame.args
				break
			end
		else
			origArgs = frame
		end
		-- Trim whitespace and remove blank arguments.
		local args = {}
		for k, v in pairs(origArgs) do
			if type(v) == 'string' then
				v = mw.text.trim(v)
			end
			if v ~= '' then
				args[k] = v
			end
		end
		return p.main(protectionType, args)
	end
end

local funcNames = {'semi', 'template', 'full'}
for _, funcName in ipairs(funcNames) do
	p[funcName] = makeWrapper(funcName)
end

return p