Changes

Jump to: navigation, search

Module:Message box

2,939 bytes added, 23:15, 27 September 2013
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
 
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 = format('Category:%s %s %s', cat, preposition, date)
tinsert(ret, format('[[%s]]', catTitle))
catTitle = getTitleObject(catTitle)
if not catTitle or not catTitle.exists then
tinsert(ret, '[[Category:Articles with invalid date parameter in template]]')
end
elseif cat and not date then
tinsert(ret, format('[[Category:%s]]', cat))
end
if all then
tinsert(ret, format('[[Category:%s]]', all))
end
return tconcat(ret)
end
end
local function box.getNamespaceId(ns)
if not ns then return end
if type(ns) == 'string' then
end
local function box.getMboxType(nsid)
-- 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)
local self.title = pageTitle or mw.title.getCurrentTitle() local demospace = box.getNamespaceId(args.demospace ~= '' and args.demospace) local self.nsid = demospace or self.title.namespaceend
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 self.isTemplatePage = nameTitle and title.prefixedText == ('Template:' .. nameTitle.text) and true or false  -- Get the self.issue value.
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
fix if talk then -- See if the talk link exists and is for a talk or a content namespace. local talkTitle = argsgetTitleObject(talk) if not talkTitle or not talkTitle.isTalkPage then -- If we couldn't process the talk page link, get the talk page of the current page.fix date local success success, talkTitle = argspcall(title.datetalkPageTitle, title) if presentButBlanknot success then talkTitle = nil end end if talkTitle and talkTitle.exists then local talkText = 'Relevant discussion may be found on' if talkTitle.isTalkPage then talkText = format(date'%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText) and isTemplatePage then date else talkText = lang:formatDateformat('F Y%s the [[%s#%s|talk page]].', talkText, talkTitle.prefixedText, talk) end self.talk = talkText end
end
info = args.info
end
-- Process the talk link, if presentGet other values. if talk then self.fix = args.fix -- See if the talk link exists and is for a talk or a content namespacelocal date = args.date local talkTitle self.date = typedate and format(talk" <small>''(%s) == 'string' and getTitleObject(talk</small>", date) if not talkTitle or not talkTitle.isTalkPage then -- If we couldn't process the talk page link, get the talk page of the current page. local success success, talkTitle = pcallpresentButBlank(titleself.talkPageTitle, titledate) if not success then talkTitle = nil end end if talkTitle and talkTitleself.exists isTemplatePage then local talkText = ' Relevant discussion may be found on' if talkTitle.isTalkPage then talkText = format('%s [[%s|%s]]self.', talkText, talk, talkTitle.prefixedText) else talkText date = formatlang:formatDate('%s the [[%s#%s|talk page]].F Y', talkText, talkTitle.prefixedText, talk) end talk = talkText
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
imageSize = data.imageSmallSize or '30x30px'
else
image self.text = args.text end  -- Set the below row. self.below = cfg.below and args.below  -- General imagesettings. imageRight self.imageCellDiv = not self.isSmall and cfg.imageCellDiv and true or false self.imageEmptyCell = argscfg.imageEmptyCell if cfg.imagerightimageEmptyCellStyle then imageSize self.imageEmptyCellStyle = '40x40pxborder:none;padding:0px;width:1px' text = args.text
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
local origCatNums self.catNums = getArgNums(args, 'cat')
if args.category then
args.category1 = args.category
end
local origCategoryNums self.categoryNums = getArgNums(args, 'category') local catNums self.categoryParamNums = union(origCatNumsself.catNums, origCategoryNumsself.categoryNums) -- The following is roughly equivalent to the old {{Ambox/category}}. local date = args.date date = type(date) == 'string' and date local preposition = 'from' for _, num in ipairs(catNumsself.categoryParamNums) do local cat mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local all allCat = args['all' .. tostring(num)] tinsertmainCat = type(mainCatsmainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date then local catTitle = format('%s %s %s', formatCategorymainCat, preposition, date) self:addCat(cat'main', argscatTitle) catTitle = getTitleObject('Category:' .. catTitle) if not catTitle or not catTitle.exists then self:addCat('main', 'Articles with invalid date parameter in template') end elseif mainCat and not datethen self:addCat('main', allmainCat) end if allCat then self:addCat('main', allCat) 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
tinsertself:addCat(templateCats'template', templatecattemplateCat, templateSort)
end
-- Categories for all namespaces.
local allCats = {} if self.invalidType then local catsort allSort = (nsid == 0 and 'Main:' or '') .. title.prefixedText tinsertself:addCat(allCats'all', format('[[Category:Wikipedia message box parameter needs fixing|%s]]', catsortallSort) end if self.isSubstituted then self:addCat('all', 'Pages with incorrectly substituted templates')
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
box .addClass(isSmall and smallClass) .addClass(data.classPlainlinksYesno and yesno(args.plainlinks or true) and 'plainlinks') .addClass(typeData.class) .addClass(args.class)boxTable .cssText(argsself.style)
.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
 
------------------------ Error messages and categories ----------------------------
-- 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
origArgs args = frame:getParent().args
for k, v in pairs(frame.args) do
origArgs args = frame.args
break
end
else
origArgs args = 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 args[k] = v end return p.buildmakeBox(boxType, args)
end
end
p.return { box = box, makeBox = makeBox, mbox = makeWrapper('mbox'),p. ambox = makeWrapper('ambox'),p. cmbox = makeWrapper('cmbox'),p. fmbox = makeWrapper('fmbox'),p. imbox = makeWrapper('imbox'),p. ombox = makeWrapper('ombox'),p. tmbox = makeWrapper('tmbox') return p}
Anonymous user

Navigation menu