Changes
rewrite with a "box" object to make the code a little less spaghetti-like
local tconcat = table.concat
local p box = {}
local function getTitleObject(page)
return false
end
end
end
if not ns then return end
if type(ns) == 'string' then
end
-- Gets the mbox type from a namespace number.
if nsid == 0 then
end
function p.buildbox:addCat(boxTypens, argscat, sort) if type(argscat) ~= 'tablestring' thenreturn end error(format( local nsVals = {'main', 'template'invalid "args" parameter type; expected type "table", got type "%s"'all'} local tname for i, typeval in ipairs(args)), 2nsVals)do if ns == val then tname = ns .. 'Cats' end
end
if not tname then
for i, val in ipairs(nsVals) do
nsVals[i] = format('"%s"', val)
end
error('invalid ns parameter passed to box:addCat; valid values are ' .. mw.text.listToText(nsVals, nil, ' or '))
end
self[tname] = self[tname] or {}
if type(sort) == 'string' then
tinsert(self[tname], format('[[Category:%s|%s]]', cat, sort))
else
tinsert(self[tname], format('[[Category:%s]]', cat))
end
end
function box:addClass(class)
if type(class) ~= 'string' then return end
self.classes = self.classes or {}
tinsert(self.classes, class)
end
function box:setTitle(args)
-- Get the title object and the namespace.
local pageTitle = getTitleObject(args.page ~= '' and args.page)
function box:getConfig(boxType)
-- Get the box config data from the data page.
if boxType == 'mbox' then
boxType = box.getMboxType(self.nsid)
end
local dataTables cfgTables = mw.loadData('Module:Message box/dataconfiguration') local data cfg = dataTablescfgTables[boxType] if not data cfg then
local boxTypes = {}
for k, v in pairs(dataTables) do
error(format('invalid message box type "%s"; valid types are %s', tostring(boxType), mw.text.listToText(boxTypes)), 2)
end
return cfg
end
function box:removeBlankArgs(cfg, args) -- Only allow blank arguments for the parameter names listed in datacfg.allowBlankParams.
local newArgs = {}
for k, v in pairs(args) do
for i, param in ipairs(datacfg.allowBlankParams or {}) do
if v ~= '' or k == param then
newArgs[k] = v
end
end
return newArgsend function box:setBoxParameters(cfg, args) -- Get type data. self.type = args .type local typeData = cfg.types[self.type] self.invalidType = self.type and not typeData and true or false typeData = typeData or cfg.types[cfg.default] self.typeClass = newArgstypeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. if cfg.substCheck and args.subst == 'SUBST' then self.isSubstituted = true end -- Find whether we are using a small message box. newArgs self.isSmall = cfg.allowSmall and (args.small == 'yes' or args.small == niltrue) and true or false
--Add attributes, classes and styles. self.id = args.id self:addClass(cfg.usePlainlinksParam and yesno(args.plainlinks or true) and 'plainlinks') for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox---------------------- Process config data ----------------------------small') end self:addClass(self.typeClass) self.style = args.style
-- Type dataSet text style. local typeData = dataself.types[args.type] local invalidType textstyle = args.type and not typeData and true or false typeData = typeData or data.types[data.default]textstyle
-- Process data for collapsible text fields. At the moment these are only used in {{ambox}}. local name, issue, talk, fix, date, infoself.useCollapsibleTextFields = cfg.useCollapsibleTextFields if dataself.useCollapsibleTextFields then self.name = args.name
local nameTitle = getTitleObject(name)
local sect = args.sect
if presentButBlank(sect) then
sect = format('This %s ', data.. (cfg.sectionDefault or 'page')
elseif type(sect) == 'string' then
sect = 'This ' .. sect .. ' ' else sect = nil
end
local issue = args.issue issue = type(sect issue) == 'string' and issue or nil local text = args.text text = type(text) == 'string'and text or nil local issues = {} tinsert(issues, sect) tinsert(issues, issue) .. tinsert(argsissues, text) self.issue or = tconcat(issues, '') -- Get the self.talk value. ' ' .. (args.text or '') local talk = args.talk if presentButBlank(talk) and self.isTemplatePage then
talk = '#'
end
end
end
self.info = args.info
end
-- Find whether we are using a small message Set the non-collapsible text field. At the moment this is used by all box and process our data accordingly.types other than ambox, local isSmall = data.allowSmall -- and (args.also by ambox when small == 'yes' or args.small == true) and true or false local smallClass, image, imageRight, text, imageSize if self.isSmall then smallClass = data.smallClass or 'mbox-small' image = args.smallimage or args.image imageRight = args.smallimageright or args.imageright if dataself.useCollapsibleTextFields then self.text = args.smalltext or self.issue
else
self.text = args.smalltext or args.text
end
else
end
-- Process mainspace categoriesLeft image settings. local mainCats imageCheckBlank = {}cfg.imageCheckBlank local origCategoryNums imageLeft = self.isSmall and args.smallimage or args.image if imageLeft ~= 'none' and not imageCheckBlank or imageLeft ~= 'none' and imageCheckBlank and image ~= 'blank' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or '40x40px' self.imageLeft = format('[[File:%s|%s|link=|alt=]]', self.typeImage or 'Imbox notice.png', imageSize) end end -- origCategoryNums might be used in computing the template error categoryRight image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if datanot (cfg.allowMainspaceCategories imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- Categories for Add mainspace categories. At the main namespacemoment these are only used in {{ambox}}. if cfg.allowMainspaceCategories then
if args.cat then
args.cat1 = args.cat
end
if args.category then
args.category1 = args.category
end
end
end
-- Process Add template -namespace categories. local self.isTemplatePage = type(self.name) == 'string' and title.prefixedText == ('Template:' .. self. name) local templateCats = {} if datacfg.templateCategory then if self.name then if self.isTemplatePage then tinsert(templateCats, formatself:addCat('[[Category:%s]]template', datacfg.templateCategory))
end
elseif not self.title.isSubpage then tinsert(templateCats, formatself:addCat('[[Category:%s]]template', datacfg.templateCategory))
end
end
-- Add an template error category for the template namespace if appropriate. if datacfg.templateErrorCategory then local catName templateErrorCategory = datacfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = format('[[Category:%s]]', catName)templateErrorCategory elseif type(self.name) == 'string' and title.prefixedText == ('Template:' .. name) then local paramsToCheck = datacfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
end
if count > 0 then
templateCat = formattemplateErrorCategory templateSort = tostring('[[Category:%s|%d]]', catName, count)
end
if origCategoryNums self.categoryNums and #origCategoryNums self.categoryNums > 0 then templateCat = format(templateErrorCategory templateSort = '[[Category:%s|C]]', catName)
end
end
end
-- Categories for all namespaces.
end
------------------------ Build the box ----------------------------Convert category tables to strings and pass them through [[Module:Category handler]]. self.categories = categoryHandler{ main = tconcat(self.mainCats or {}), template = tconcat(self.templateCats or {}), all = tconcat(self.allCats or {}), nocat = args.nocat, demospace = self.demospace and args.demospace or nil, page = self.pageTitle and pageTitle.prefixedText or nil }end function box:export()
local root = htmlBuilder.create()
-- Do Add the subst checkerror. if dataself.substCheck isSubstituted and argsself.subst == 'SUBST' name then if type(name) == 'string' thenroot root .tag('b') .addClass('error') .wikitext(format( 'Template <code>%s%s%s</code> has been incorrectly substituted.', mw.text.nowiki('{{'), self.name, mw.text.nowiki('}}') ) ) end tinsert(allCats, '[[Category:Pages with incorrectly substituted templates]]')
end
-- Create the box table.
local box boxTable = root.tag('table') boxboxTable .attr('id', argsself.id) for i, class in ipairs(dataself.classesor {}) do boxboxTable
.addClass(class)
end
.attr('role', 'presentation')
-- Add the left-hand image.
local row = boxboxTable.tag('tr') local imageCheckBlank = dataif self.imageCheckBlank if image ~= 'none' and not imageCheckBlank or image ~= 'none' and imageCheckBlank and image ~= 'blank' imageLeft then
local imageLeftCell = row.tag('td').addClass('mbox-image')
if not isSmall and dataself.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image is inside it. -- Not sure why only some box types use divs, but it probably has something to do -- with that style="width: 52px;". @TODO: find out exactly what this does and fix this comment. imageLeftCell = imageLeftCell.tag('div').css('width', '52px') -- If we are using a div, redefine imageLeftCell so that the image is inside it.
end
imageLeftCell
.wikitext(image or format('[[File:%s|%s|link=|alt=]]', typeDataself.image, imageSize)imageLeft) elseif dataself.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and some don't. -- The old template code in templates where empty cells are specified gives the following hint: -- "No image. Cell with some width or padding necessary for text cell to have 100% width."
row.tag('td')
.addClass('mbox-empty-cell') -- No image. Cell with some width or padding necessary for text cell to have 100% width. .cssText(dataself.imageEmptyCellStyle and 'border:none;padding:0px;width:1px')
end
-- Add the text.
local textCell = row.tag('td').addClass('mbox-text')
if dataself.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be collapsible. At the -- moment, only ambox uses this.
textCell
.cssText(argsself.textstyle)
local textCellSpan = textCell.tag('span')
textCellSpan
.addClass('mbox-text-span')
.wikitext(self.issue)
if not isSmall then
textCellSpan
.tag('span')
.addClass('hide-when-compact')
.wikitext(self.talk and ' ' .. self.talk) .wikitext(self.fix and ' ') .wikitext(. self.fix) .done()
end
textCellSpan
.wikitext(self.date and format(" <small>''(%s)''</small>", .. self.date))
if not isSmall then
textCellSpan
.tag('span')
.addClass('hide-when-compact')
.wikitext(self.info and ' ' .. self. info)
end
else
-- Default text formatting - anything goes.
textCell
.cssText(argsself.textstyle) .wikitext(self.text)
end
-- Add the right-hand image.
if imageRight and not (dataself.imageRightNone and imageRight == 'none') then
local imageRightCell = row.tag('td').addClass('mbox-imageright')
if not isSmall and dataself.imageCellDiv then
imageRightCell = imageRightCell.tag('div').css('width', '52px') -- If we are using a div, redefine imageRightCell so that the image is inside it.
end
imageRightCell
.wikitext(self.imageRight)
end
-- Add the below row.
if data.below and argsself.below then boxboxTable.tag('tr')
.tag('td')
.attr('colspan', argsself.imageright imageRight and '3' or '2')
.addClass('mbox-text')
.cssText(argsself.textstyle) .wikitext(argsself.below)
end
-- Add error message for invalid type parameters.
if self.invalidType then
root
.tag('div')
.addClass('error')
.css('text-align', 'center')
.wikitext(format('This message box is using an invalid type parameter (<code>type=%s</code>) and needs fixing.', argsself.type or ''))
end
-- Add categories using categoryHandler.
root
.wikitext(categoryHandler{ main = tconcat(mainCats), template = tconcat(templateCats), all = tconcat(allCats), nocat = args.nocat, demospace = demospace and args.demospace or nil, page = pageTitle and pageTitleself.prefixedText or nil }categories)
return tostring(root)
end
local function makeBox(boxType, args)
box:setTitle(args)
local cfg = box:getConfig(boxType)
args = box:removeBlankArgs(cfg, args)
box:setBoxParameters(cfg, args)
return box:export()
end
-- assume args are being passed directly in from the debug console
-- or from another Lua module.
local origArgsargs
if frame == mw.getCurrentFrame() then
for k, v in pairs(frame.args) do
break
end
else
end
end
end