![](https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Test_Template_Info-Icon_-_Version_%282%29.svg/50px-Test_Template_Info-Icon_-_Version_%282%29.svg.png)
This module is used for speedy deletion notices and aims to increase flexibility greatly.
Features to be included include substitution detection and the ability to print out a full speedy deletion table.
Usage
{{#invoke:Speedy|function_name}}
Full Table of Reasons
See config page to edit
Script error: The function "makeTable" does not exist.
local getArgs = require("Module:Arguments").getArgs
local pageType = require("Module:Pagetype")
local mbox = require("Module:Message box")
local yesno = require("Module:Yesno")
local button = require('Module:Clickable button 2')
local p = {}
local config = mw.loadData('Module:Speedy/config')
local timeAgo = require('Module:Time ago')
----------------------------------------------------------------------------
-- message function from [[Module:Documentation]]
----------------------------------------------------------------------------
local fillStringWithArgs
local function message(cfgKey, valArray, expectType)
--[[
-- Gets a message from the cfg table and formats it if appropriate.
-- The function raises an error if the value from the cfg table is not
-- of the type expectType. The default type for expectType is 'string'.
-- If the table valArray is present, strings such as $1, $2 etc. in the
-- message are substituted with values from the table keys [1], [2] etc.
-- For example, if the message "foo-message" had the value 'Foo $2 bar $1.',
-- message('foo-message', {'baz', 'qux'}) would return "Foo qux bar baz."
--]]
local msg = config.messages[cfgKey]
expectType = expectType or 'string'
if type(msg) ~= expectType then
error('message: type error in message cfg.' .. cfgKey .. ' (' .. expectType .. ' expected, got ' .. type(msg) .. ')', 2)
end
if not valArray then
return msg
end
return fillStringWithArgs(msg, valArray)
end
function fillStringWithArgs(text, valArray)
if not valArray then
return text
end
local function getVal(match)
match = tonumber(match)
return valArray[match] or error('message: no value found for key $' .. match .. ' in message cfg.' .. cfgKey, 4)
end
return mw.ustring.gsub(text, '$([1-9][0-9]*)', getVal)
end
local function detectParameters(text)
return text and mw.ustring.find(text, '$([1-9][0-9]*)') and true or false
end
local function makeUnorderedList(array)
local out = '<ul>'
for k,v in pairs(array) do
out = '<li>' .. v .. '</li>'
end
out = out .. '</ul>'
return out
end
----------------------------------------------------------------------------
-- Argument processing (from [[Module:Documentation]])
----------------------------------------------------------------------------
local function makeInvokeFunc(funcName)
return function (frame)
local args = getArgs(frame, {
valueFunc = function (key, value)
if type(value) == 'string' then
value = value:match('^%s*(.-)%s*$') -- Remove whitespace.
if key == 'heading' or value ~= '' then
return value
else
return nil
end
else
return value
end
end
})
return p[funcName](args)
end
end
p.main = makeInvokeFunc('_main')
----------------------------------------------------------------------------
-- Miscellaneous functions related to speedy deletion
----------------------------------------------------------------------------
local function getDeletionEntry(code)
return config.deletionCodes[code]
end
local function processDeletionArgs(params)
local args = {
deletionReasons = {},
entries = {},
numberOfEntries = 0,
hideButton = false,
highestMessage = 0
}
local entry = nil
local replaceParams = false
local params = {}
for k,v in pairs(params) do
if type(k) == type(1) then
if (replaceParams) then
table.insert(params, fillStringWithArgs(inputFormat[k], {params[k]}))
else
entry = getDeletionEntry(v) or nil
replaceParams = detectParameters(entry.description)
end
if not replaceParams then
table.insert(args.deletionReasons, entry and fillStringWithArgs(entry.description, params) .. '. ' .. message('deleteIntroCriteriaLink', entry.code) or v)
table.insert(args.entries, entry or {})
params = {}
args.numberOfEntries = args.numberOfEntries + 1
args.hideButton = entry.hidebutton or false
args.highestMessage = (entry.notice or 2) > args.highestMessage and entry.notice or args.highestMessage
end
end
end
args.help = yesno(params.help)
args.hideButton = args.hideButton or yesno(params.hidebutton)
args.nocat = yesno(params.nocat)
args.category = params.category
args.bot = yesno(params.bot)
return args
end
----------------------------------------------------------------------------
-- Entry point
----------------------------------------------------------------------------
function p._main(params)
-- get page
local args = processDeletionArgs(params)
local out = ''
local titleOfPage = mw.title.getCurrentTitle()
local pt = pageType._main({page = titleOfPage.fullText})
local introPrefixToUse = args.bot and 'bot' or 'delete'
if args.numberOfEntries == 1 then
out = out .. '<p><b>' .. message(introPrefixToUse .. 'Intro', {
pt,
args.deletionReasons[1]
}) .. '</b> ' .. (args.entries[1].more or '') .. '</p>'
elseif args.numberOfEntries > 1 then
out = out .. '<p><b>' .. message(introPrefixToUse .. 'IntroMultiple', {
pt,
makeUnorderedList(deletionReasons)
}) .. message('deleteCriteriaValid') .. '</b></p>'
else
out = out .. '<p><b>' .. message(introPrefixToUse .. 'IntroMultiple', {
pt,
message("noReasonWarning")
}) .. '</b></p>'
end
if args.hideButton then
out = out .. '<p>' .. message("removeNoticeNoButton", {pt}) .. '</p>'
else
out = out .. '<p>' .. message("removeNotice", {pageType._main({page = titleOfPage}), message('removeNoticeWarning', {titleOfPage.isTalkPage and message('checkBelow') or '[[' .. titleOfPage.talkPageTitle.fullText .. '|' .. message('visitTheTalkPage') .. ']]'})}) .. '</p>'
if args.numberOfEntries == 1 then
out = out .. button.luaMain({
message("contestButton"),
url="{{fullurl:" .. titleOfPage.talkPageTitle.fullText .. '|action=edit§ion=new&preload={{urlencode:' .. (mw.title.new(message('contestPreload', {args.entries[1].code})).exists and message('contestPreload', {args.entries[1].code}) or message('contestPreloadGeneric')) .. '}}&editintro={{urlencode:' .. message('contestPreloadEditintro') .. '}}}}'
})
else
out = out .. button.luaMain({
message("contestButton"),
url="{{fullurl:" .. titleOfPage.talkPageTitle.fullText .. '|action=edit§ion=new&preload={{urlencode:' .. message('contestPreloadGeneric') .. '}}&editintro={{urlencode:' .. message('contestPreloadEditintro') .. '}}}}'
})
end
out = out .. '<p>' .. message("deleteCloser", {
pt,
titleOfPage.isTalkPage and message("deleteCloserProvidedBelowNotice") or message("deleteCloserProvidedOnTalkPage")
}) .. "</p>"
local templateCall = '<code>{{subst|db'
for k,v in pairs(params) do
templateCall = templateCall .. '|' .. k .. '=' .. v
end
templateCall = templateCall .. '}} ~~' .. '~~</code>'
print(message('deleteNoticeTemplate', {templateCall}))
out = out .. '<p>' .. message('deleteNoticeTemplate', {templateCall}) .. '</p>'
if titleOfPage.talkPageTitle.exists then
out = out .. '<p><span class="sysop-show">' .. message("hangOnAdmin", {pt, titleOfPage.isTalkPage and message("hangOnBelow") or message("hangOnTalkPage")}) .. "</span></p>"
else
out = out .. message('hangOn', {pt})
end
end
if args.numberOfEntries == 1 then
out = out .. (args.entries[1].notes and '<p>' .. args.entries[1].notes .. "</p>" or '')
end
local deleteReasonSummary = ''
local lastEditUser = mw.getCurrentFrame():callParserFunction('REVISIONUSER', titleOfPage.fullText)
local editDate = mw.getCurrentFrame():callParserFunction('#time', 'd F Y', mw.getCurrentFrame():callParserFunction('REVISIONTIMESTAMP', titleOfPage.fullText))
out = out .. '<p><span class="sysop-show">' .. message(args.bot and 'checkBot' or 'check', {args.bot and message('check', {deleteReasonSummary}) or deleteReasonSummary}) .. '</span>' .. message('lastEdited', {
'[[User:' .. lastEditUser .. '|' .. lastEditUser .. ']]',
'<span class="plainlinks">[{{fullurl:' .. titleOfPage.fullText .. '|action=history}} ' .. editDate .. ']</span>',
timeAgo.main({editDate})
})
local deletionBoxArgs = {
type = "speedy",
text = mw.getCurrentFrame():preprocess(out)
}
local deletionBox = mbox.main('mbox', deletionBoxArgs)
return deletionBox
end
return p