Module:Message box: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
(Fixed a few of the ambox bugs. Still have to add category support.) |
(finish ambox and split the config functions out to Module:Message box/data) |
||
Line 3: | Line 3: | ||
local htmlBuilder = require('Module:HtmlBuilder') |
local htmlBuilder = require('Module:HtmlBuilder') |
||
local nsDetect = require('Module:Namespace detect') |
local nsDetect = require('Module:Namespace detect') |
||
local categoryHandler = require('Module:Category handler').main |
|||
local yesno = require('Module:Yesno') |
local yesno = require('Module:Yesno') |
||
Line 29: | Line 30: | ||
end |
end |
||
function |
local function formatCategory(cat, date, all) |
||
local ret = {} |
|||
cat = type(cat) == 'string' and cat |
|||
date = type(date) == 'string' and date |
|||
all = type(all) == 'string' and all |
|||
local preposition = 'from' |
|||
if cat and date then |
|||
local catTitle = mw.ustring.format('Category:%s %s %s', cat, preposition, date) |
|||
table.insert(ret, mw.ustring.format('[[%s]]', catTitle)) |
|||
catTitle = getTitleObject(catTitle) |
|||
if not catTitle or not catTitle.exists then |
|||
table.insert(ret, '[[Category:Articles with invalid date parameter in template]]') |
|||
end |
|||
elseif cat and not date then |
|||
table.insert(ret, mw.ustring.format('[[Category:%s]]', cat)) |
|||
end |
|||
if all then |
|||
table.insert(ret, mw.ustring.format('[[Category:%s]]', all)) |
|||
end |
|||
return table.concat(ret) |
|||
end |
|||
local function union(t1, t2) |
|||
-- Returns the union of two arrays. |
|||
local vals = {} |
|||
for i, v in ipairs(t1) do |
|||
vals[v] = true |
|||
end |
|||
for i, v in ipairs(t2) do |
|||
vals[v] = true |
|||
end |
|||
local ret = {} |
|||
for k, v in pairs(vals) do |
|||
table.insert(ret, k) |
|||
end |
|||
return ret |
|||
end |
|||
local function getArgNums(args, prefix) |
|||
local nums = {} |
|||
for k, v in pairs(args) do |
|||
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') |
|||
if num then |
|||
table.insert(nums, tonumber(num)) |
|||
end |
|||
end |
|||
table.sort(nums) |
|||
return nums |
|||
end |
|||
function p.build(boxType, args) |
|||
-- Get the box config data from the data page. |
|||
local dataTables = mw.loadData('Module:Message box/data') |
|||
local data = dataTables[boxType] |
|||
if not data then |
|||
local boxTypes = {} |
|||
for k, v in pairs(dataTables) do |
|||
table.insert(boxTypes, mw.ustring.format('"%s"', k)) |
|||
end |
|||
error(mw.ustring.format('Invalid message box type. Valid types are %s.', mw.text.listToText(boxTypes))) |
|||
end |
|||
-- Get the title object and the namespace. |
-- Get the title object and the namespace. |
||
local title = mw.title.getCurrentTitle() |
local title = mw.title.getCurrentTitle() |
||
Line 67: | Line 129: | ||
local sect = args.sect |
local sect = args.sect |
||
if presentButBlank(sect) then |
if presentButBlank(sect) then |
||
sect = 'This |
sect = mw.ustring.format('This %s ', data.sectionDefault or 'page') |
||
elseif type(sect) == 'string' then |
elseif type(sect) == 'string' then |
||
sect = 'This ' .. sect .. ' ' |
sect = 'This ' .. sect .. ' ' |
||
Line 125: | Line 187: | ||
imageSize = '40x40px' |
imageSize = '40x40px' |
||
text = args.text |
text = args.text |
||
end |
|||
-- Process mainspace categories. |
|||
local mainCats = {} |
|||
local origCategoryNums -- origCategoryNums might be used in computing the template error category. |
|||
if data.allowMainspaceCategories then |
|||
-- Categories for the main namespace. |
|||
local origCatNums = getArgNums(args, 'cat') |
|||
local origCategoryNums = getArgNums(args, 'category') |
|||
local catNums = union(origCatNums, origCategoryNums) |
|||
for _, num in ipairs(catNums) do |
|||
local cat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] |
|||
local all = args['all' .. tostring(num)] |
|||
table.insert(mainCats, formatCategory(cat, args.date, all)) |
|||
end |
|||
end |
|||
-- Process template namespace categories |
|||
local templateCats = {} |
|||
if data.templateCategory and not title.isSubpage and not yesno(args.nocat) then |
|||
table.insert(templateCats, mw.ustring.format('[[Category:%s]]', data.templateCategory)) |
|||
end |
|||
-- Add an error category for the template namespace if appropriate. |
|||
if data.templateErrorCategory then |
|||
local catName = data.templateErrorCategory |
|||
local templateCat |
|||
if not name and not title.isSubpage then |
|||
templateCat = mw.ustring.format('[[Category:%s]]', catName) |
|||
elseif type(name) == 'string' and title.prefixedText == ('Template:' .. name) then |
|||
local paramsToCheck = data.templateErrorParamsToCheck or {} |
|||
local count = 0 |
|||
for i, param in ipairs(paramsToCheck) do |
|||
if not args[param] then |
|||
count = count + 1 |
|||
end |
|||
end |
|||
if count > 0 then |
|||
templateCat = mw.ustring.format('[[Category:%s|%d]]', catName, count) |
|||
end |
|||
if origCategoryNums and #origCategoryNums > 0 then |
|||
templateCat = mw.ustring.format('[[Category:%s|C]]', catName) |
|||
end |
|||
end |
|||
table.insert(templateCats, templatecat) |
|||
end |
|||
-- Categories for all namespaces. |
|||
local allCats = {} |
|||
if invalidType then |
|||
local catsort = (nsid == 0 and 'Main:' or '') .. title.prefixedText |
|||
table.insert(allCats, mw.ustring.format('[[Category:Wikipedia message box parameter needs fixing|%s]]', catsort)) |
|||
end |
end |
||
Line 133: | Line 247: | ||
-- Do the subst check. |
-- Do the subst check. |
||
if data.substCheck and args.subst == 'SUBST' then |
if data.substCheck and args.subst == 'SUBST' then |
||
if type( |
if type(name) == 'string' then |
||
root |
root |
||
.tag('b') |
.tag('b') |
||
Line 139: | Line 253: | ||
.wikitext(mw.ustring.format( |
.wikitext(mw.ustring.format( |
||
'Template <code>%s%s%s</code> has been incorrectly substituted.', |
'Template <code>%s%s%s</code> has been incorrectly substituted.', |
||
mw.text.nowiki('{{'), |
mw.text.nowiki('{{'), name, mw.text.nowiki('}}') |
||
args.name, |
|||
mw.text.nowiki('}}') |
|||
)) |
)) |
||
end |
end |
||
table.insert(allCats, '[[Category:Pages with incorrectly substituted templates]]') |
|||
end |
end |
||
-- |
-- Create the box table. |
||
local box = root.tag('table') |
local box = root.tag('table') |
||
box |
box |
||
Line 165: | Line 277: | ||
-- Add the left-hand image. |
-- Add the left-hand image. |
||
local row = box.tag('tr') |
local row = box.tag('tr') |
||
local imageLeftCell = row.tag('td').addClass('mbox-image') |
|||
local imageCheckBlank = data.imageCheckBlank |
local imageCheckBlank = data.imageCheckBlank |
||
if image ~= 'none' and not imageCheckBlank or image ~= 'none' and imageCheckBlank and image ~= 'blank' then |
if image ~= 'none' and not imageCheckBlank or image ~= 'none' and imageCheckBlank and image ~= 'blank' then |
||
local imageLeftCell = row.tag('td').addClass('mbox-image') |
|||
if not isSmall and data.imageCellDiv then |
if not isSmall and data.imageCellDiv then |
||
imageLeftCell = imageLeftCell.tag('div').css('width', '52px') -- If we are using a div, redefine imageLeftCell so that the image is inside it. |
imageLeftCell = imageLeftCell.tag('div').css('width', '52px') -- If we are using a div, redefine imageLeftCell so that the image is inside it. |
||
Line 212: | Line 324: | ||
-- Add the right-hand image. |
-- Add the right-hand image. |
||
local imageRightCell = row.tag('td').addClass('mbox-imageright') |
|||
if imageRight and not (data.imageRightNone and imageRight == 'none') then |
if imageRight and not (data.imageRightNone and imageRight == 'none') then |
||
local imageRightCell = row.tag('td').addClass('mbox-imageright') |
|||
if not isSmall and data.imageCellDiv then |
if not isSmall and data.imageCellDiv then |
||
imageRightCell = imageRightCell.tag('div').css('width', '52px') -- If we are using a div, redefine imageRightCell so that the image is inside it. |
imageRightCell = imageRightCell.tag('div').css('width', '52px') -- If we are using a div, redefine imageRightCell so that the image is inside it. |
||
Line 231: | Line 343: | ||
end |
end |
||
------------------------ |
------------------------ Error messages and categories ---------------------------- |
||
-- Add error message |
-- Add error message for invalid type parameters. |
||
if invalidType then |
if invalidType then |
||
local catsort = (nsid == 0 and 'Main:' or '') .. title.prefixedText |
|||
root |
root |
||
.tag('div') |
.tag('div') |
||
.addClass('error') |
|||
.css('text-align', 'center') |
.css('text-align', 'center') |
||
.wikitext(mw.ustring.format('This message box is using an invalid |
.wikitext(mw.ustring.format('This message box is using an invalid type parameter (<code>type=%s</code>) and needs fixing.', args.type or '')) |
||
.done() |
|||
.wikitext(mw.ustring.format('[[Category:Wikipedia message box parameter needs fixing|%s]]', catsort)) |
|||
end |
end |
||
-- Add categories using categoryHandler. |
|||
-- Categorise template pages. |
|||
root |
|||
if data.category and nsid == 10 and not title.isSubpage and not yesno(args.nocat) then |
|||
.wikitext(categoryHandler{ |
|||
main = table.concat(mainCats), |
|||
end |
|||
template = table.concat(templateCats), |
|||
all = table.concat(allCats) |
|||
}) |
|||
return tostring(root) |
return tostring(root) |
||
end |
end |
||
function |
local function makeWrapper(boxType) |
||
local data = {} |
|||
data.types = { |
|||
speedy = { |
|||
class = 'ambox-speedy', |
|||
image = 'Ambox speedy deletion.png' |
|||
}, |
|||
delete = { |
|||
class = 'ambox-delete', |
|||
image = 'Ambox deletion.png' |
|||
}, |
|||
content = { |
|||
class = 'ambox-content', |
|||
image = 'Ambox content.png' |
|||
}, |
|||
style = { |
|||
class = 'ambox-style', |
|||
image = 'Edit-clear.svg' |
|||
}, |
|||
move = { |
|||
class = 'ambox-move', |
|||
image = 'Ambox move.png' |
|||
}, |
|||
protection = { |
|||
class = 'ambox-protection', |
|||
image = 'Ambox protection.png' |
|||
}, |
|||
notice = { |
|||
class = 'ambox-notice', |
|||
image = 'Ambox notice.png' |
|||
} |
|||
} |
|||
data.default = 'notice' |
|||
data.allowSmall = true |
|||
data.substCheck = true |
|||
data.classes = {'metadata', 'plainlinks', 'ambox'} |
|||
data.smallClass = 'mbox-small-left' |
|||
data.imageEmptyCell = true |
|||
data.imageCheckBlank = true |
|||
data.imageSmallSize = '20x20px' |
|||
data.imageCellDiv = true |
|||
data.useCollapsibleTextFields = true |
|||
data.imageRightNone = true |
|||
return p.build(data, args) |
|||
end |
|||
function p._fmbox(args) |
|||
local data = {} |
|||
data.types = { |
|||
warning = { |
|||
class = 'fmbox-warning', |
|||
image = 'Cmbox deletion.png' |
|||
}, |
|||
editnotice = { |
|||
class = 'fmbox-editnotice', |
|||
image = 'Imbox notice.png' |
|||
}, |
|||
system = { |
|||
class = 'fmbox-system', |
|||
image = 'Imbox notice.png' |
|||
} |
|||
} |
|||
data.default = 'system' |
|||
data.classes = { 'plainlinks', 'fmbox' } |
|||
data.imageEmptyCell = false |
|||
data.imageRightNone = false |
|||
return p.build(data, args) |
|||
end |
|||
function p._ombox(args) |
|||
local data = {} |
|||
data.types = { |
|||
speedy = { |
|||
class = 'ombox-speedy', |
|||
image = 'Imbox speedy deletion.png' |
|||
}, |
|||
delete = { |
|||
class = 'ombox-delete', |
|||
image = 'Imbox deletion.png' |
|||
}, |
|||
content = { |
|||
class = 'ombox-content', |
|||
image = 'Imbox content.png' |
|||
}, |
|||
style = { |
|||
class = 'ombox-style', |
|||
image = 'Edit-clear.svg' |
|||
}, |
|||
move = { |
|||
class = 'ombox-move', |
|||
image = 'Imbox move.png' |
|||
}, |
|||
protection = { |
|||
class = 'ombox-protection', |
|||
image = 'Imbox protection.png' |
|||
}, |
|||
notice = { |
|||
class = 'ombox-notice', |
|||
image = 'Imbox notice.png' |
|||
} |
|||
} |
|||
data.default = 'notice' |
|||
data.classes = {'plainlinks', 'ombox'} |
|||
data.allowSmall = true |
|||
data.imageEmptyCell = true |
|||
data.imageRightNone = true |
|||
return p.build(data, args) |
|||
end |
|||
function p._imbox(args) |
|||
local data = {} |
|||
data.types = { |
|||
speedy = { |
|||
class = 'imbox-speedy', |
|||
image = 'Imbox speedy deletion.png' |
|||
}, |
|||
delete = { |
|||
class = 'imbox-delete', |
|||
image = 'Imbox deletion.png' |
|||
}, |
|||
content = { |
|||
class = 'imbox-content', |
|||
image = 'Imbox content.png' |
|||
}, |
|||
style = { |
|||
class = 'imbox-style', |
|||
image = 'Edit-clear.svg' |
|||
}, |
|||
move = { |
|||
class = 'imbox-move', |
|||
image = 'Imbox move.png' |
|||
}, |
|||
protection = { |
|||
class = 'imbox-protection', |
|||
image = 'Imbox protection.png' |
|||
}, |
|||
license = { |
|||
class = 'imbox-license', |
|||
image = 'Imbox license.png' |
|||
}, |
|||
featured = { |
|||
class = 'imbox-featured', |
|||
image = 'Imbox featured.png' |
|||
}, |
|||
notice = { |
|||
class = 'imbox-notice', |
|||
image = 'Imbox notice.png' |
|||
} |
|||
} |
|||
data.default = 'notice' |
|||
data.classes = {'imbox'} |
|||
data.classPlainlinksYesno = true |
|||
data.imageEmptyCell = true |
|||
data.below = true |
|||
return p.build(data, args) |
|||
end |
|||
function p._cmbox(args) |
|||
local data = {} |
|||
data.types = { |
|||
speedy = { |
|||
class = 'cmbox-speedy', |
|||
image = 'Cmbox deletion.png' |
|||
}, |
|||
delete = { |
|||
class = 'cmbox-delete', |
|||
image = 'Cmbox deletion.png' |
|||
}, |
|||
content = { |
|||
class = 'cmbox-content', |
|||
image = 'Cmbox content.png' |
|||
}, |
|||
style = { |
|||
class = 'cmbox-style', |
|||
image = 'Edit-clear.svg' |
|||
}, |
|||
move = { |
|||
class = 'cmbox-move', |
|||
image = 'Cmbox move.png' |
|||
}, |
|||
protection = { |
|||
class = 'cmbox-protection', |
|||
image = 'Cmbox protection.png' |
|||
}, |
|||
notice = { |
|||
class = 'cmbox-notice', |
|||
image = 'Cmbox notice.png' |
|||
} |
|||
} |
|||
data.default = 'notice' |
|||
data.classes = {'plainlinks', 'cmbox'} |
|||
return p.build(data, args) |
|||
end |
|||
function p._tmbox(args) |
|||
local data = {} |
|||
data.types = { |
|||
speedy = { |
|||
class = 'tmbox-speedy', |
|||
image = 'Imbox speedy deletion.png' |
|||
}, |
|||
delete = { |
|||
class = 'tmbox-delete', |
|||
image = 'Imbox deletion.png' |
|||
}, |
|||
content = { |
|||
class = 'tmbox-content', |
|||
image = 'Imbox content.png' |
|||
}, |
|||
style = { |
|||
class = 'tmbox-style', |
|||
image = 'Edit-clear.svg ' |
|||
}, |
|||
move = { |
|||
class = 'tmbox-move', |
|||
image = 'Imbox move.png' |
|||
}, |
|||
protection = { |
|||
class = 'tmbox-protection', |
|||
image = 'Imbox protection.png' |
|||
}, |
|||
notice = { |
|||
class = 'tmbox-notice', |
|||
image = 'Imbox notice.png' |
|||
} |
|||
} |
|||
data.default = 'notice' |
|||
data.classes = {'plainlinks', 'tmbox'} |
|||
data.allowSmall = true |
|||
data.imageRightNone = true |
|||
data.imageEmptyCellStyle = true |
|||
data.category = 'Talk message boxes' |
|||
return p.build(data, args) |
|||
end |
|||
local function makeWrapper(func) |
|||
return function (frame) |
return function (frame) |
||
-- If called via #invoke, use the args passed into the invoking |
-- If called via #invoke, use the args passed into the invoking |
||
Line 512: | Line 391: | ||
end |
end |
||
end |
end |
||
return |
return p.build(boxType, args) |
||
end |
end |
||
end |
end |
||
p.ambox = makeWrapper( |
p.ambox = makeWrapper('ambox') |
||
p.fmbox = makeWrapper( |
p.fmbox = makeWrapper('fmbox') |
||
p.imbox = makeWrapper( |
p.imbox = makeWrapper('imbox') |
||
p.ombox = makeWrapper( |
p.ombox = makeWrapper('ombox') |
||
p.cmbox = makeWrapper( |
p.cmbox = makeWrapper('cmbox') |
||
p.tmbox = makeWrapper( |
p.tmbox = makeWrapper('tmbox') |
||
return p |
return p |