Latest revision |
Your text |
Line 1: |
Line 1: |
| require('Module:No globals') | | -- This is a meta-module for producing message box templates, including {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. |
| local getArgs
| | |
| | local htmlBuilder = require('Module:HtmlBuilder') |
| local yesno = require('Module:Yesno') | | local yesno = require('Module:Yesno') |
| local lang = mw.language.getContentLanguage()
| |
|
| |
| local CONFIG_MODULE = 'Module:Message box/configuration'
| |
| local DEMOSPACES = {talk = 'tmbox', image = 'imbox', file = 'imbox', category = 'cmbox', article = 'ambox', main = 'ambox'}
| |
|
| |
|
| --------------------------------------------------------------------------------
| | local p = {} |
| -- Helper functions
| |
| --------------------------------------------------------------------------------
| |
|
| |
|
| local function getTitleObject(...) | | local function generateBoxStructure() |
| -- Get the title object, passing the function through pcall
| | local root = htmlBuilder.create() -- Includes error messages and categories added after the box. |
| -- in case we are over the expensive function count limit.
| | local box = root.tag('table') |
| local success, title = pcall(mw.title.new, ...)
| | local row = box.tag('tr') |
| if success then
| | return root, box, row |
| return title
| |
| end
| |
| end | | end |
|
| |
|
| local function union(t1, t2)
| | function p.build(data, args) |
| -- Returns the union of two arrays.
| | -- Process config data. |
| local vals = {}
| | local typeData = data.types[args.type] |
| for i, v in ipairs(t1) do
| | local invalidType = args.type and not typeData and true or false |
| vals[v] = true
| | typeData = typeData or data.types[data.default] |
| end
| |
| for i, v in ipairs(t2) do
| |
| vals[v] = true
| |
| end
| |
| local ret = {}
| |
| for k in pairs(vals) do
| |
| table.insert(ret, k)
| |
| end
| |
| table.sort(ret)
| |
| return ret
| |
| end
| |
|
| |
|
| local function getArgNums(args, prefix) | | local isSmall = (args.small == 'yes' or args.small == true) and true or false |
| local nums = {}
| | local image, imageRight, text, imageSize |
| for k, v in pairs(args) do
| | if isSmall then |
| local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
| | image = args.smallimage or args.image |
| if num then
| | imageRight = args.smallimageright or args.imageright |
| table.insert(nums, tonumber(num))
| | text = args.smalltext or args.text |
| end
| | imageSize = data.imageSizeSmall or data.imageSize or '40x40px' |
| end
| | else |
| table.sort(nums)
| | image = args.image |
| return nums
| | imageRight = args.imageright |
| end | | text = args.text |
| | imageSize = data.imageSizeLarge or data.imageSize or '40x40px' |
| | end |
|
| |
|
| -------------------------------------------------------------------------------- | | -- Get the box structure. |
| -- Box class definition
| | local root, box, row = generateBoxStructure() |
| --------------------------------------------------------------------------------
| |
|
| |
|
| local MessageBox = {}
| | -- Build the box. |
| MessageBox.__index = MessageBox
| | box |
| | .attr('id', args.id) |
| | for i, class in ipairs(data.classes) do |
| | box |
| | .addClass(class) |
| | end |
| | box |
| | .addClass(isSmall and 'mbox-small') |
| | .addClass(data.classPlainlinksYesno and yesno(args.plainlinks or true) and 'plainlinks') |
| | .addClass(typeData.class) |
| | .addClass(args.class) |
| | .cssText(args.style) |
| | .attr('role', 'presentation') |
|
| |
|
| function MessageBox.new(boxType, args, cfg)
| | -- Add the left-hand image. |
| args = args or {}
| | if image ~= 'none' then |
| local obj = {}
| | row.tag('td') |
| | .addClass('mbox-image') |
| | .wikitext(image or mw.ustring.format('[[File:%s|%s|link=|alt=]]', typeData.image, imageSize)) |
| | elseif data.imageEmptyCell then |
| | row.tag('td') |
| | .addClass('mbox-empty-cell') -- No image. Cell with some width or padding necessary for text cell to have 100% width. |
| | end |
|
| |
|
| -- Set the title object and the namespace.
| | -- Add the text. |
| obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
| | row.tag('td') |
| | .addClass('mbox-text') |
| | .cssText(args.textstyle) |
| | .wikitext(text) |
|
| |
|
| -- Set the config for our box type.
| | -- Add the right-hand image. |
| obj.cfg = cfg[boxType]
| | if imageRight and not (data.imageRightNone and imageRight == 'none') then |
| if not obj.cfg then
| | row.tag('td') |
| local ns = obj.title.namespace
| | .addClass('mbox-imageright') |
| -- boxType is "mbox" or invalid input
| | .wikitext(imageRight) |
| if args.demospace and args.demospace ~= '' then
| | end |
| -- implement demospace parameter of mbox
| |
| local demospace = string.lower(args.demospace)
| |
| if DEMOSPACES[demospace] then
| |
| -- use template from DEMOSPACES
| |
| obj.cfg = cfg[DEMOSPACES[demospace]]
| |
| elseif string.find( demospace, 'talk' ) then
| |
| -- demo as a talk page
| |
| obj.cfg = cfg.tmbox
| |
| else
| |
| -- default to ombox
| |
| obj.cfg = cfg.ombox
| |
| end
| |
| elseif ns == 0 then
| |
| obj.cfg = cfg.ambox -- main namespace
| |
| elseif ns == 6 then
| |
| obj.cfg = cfg.imbox -- file namespace
| |
| elseif ns == 14 then
| |
| obj.cfg = cfg.cmbox -- category namespace
| |
| else
| |
| local nsTable = mw.site.namespaces[ns]
| |
| if nsTable and nsTable.isTalk then
| |
| obj.cfg = cfg.tmbox -- any talk namespace
| |
| else
| |
| obj.cfg = cfg.ombox -- other namespaces or invalid input
| |
| end
| |
| end
| |
| end
| |
|
| |
|
| -- Set the arguments, and remove all blank arguments except for the ones
| | -- Add the below row. |
| -- listed in cfg.allowBlankParams.
| | if data.below and args.below then |
| do
| | box.tag('tr') |
| local newArgs = {}
| | .tag('td') |
| for k, v in pairs(args) do
| | .attr('colspan', args.imageright and '3' or '2') |
| if v ~= '' then
| | .addClass('mbox-text') |
| newArgs[k] = v
| | .cssText(args.textstyle) |
| end
| | .wikitext(args.below) |
| end
| | end |
| for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
| |
| newArgs[param] = args[param]
| |
| end
| |
| obj.args = newArgs
| |
| end
| |
|
| |
|
| -- Define internal data structure.
| | -- Add error messages and categories. |
| obj.categories = {}
| | if invalidType then |
| obj.classes = {}
| | local title = mw.title.getCurrentTitle() |
| -- For lazy loading of [[Module:Category handler]].
| | local catsort = (title.namespace == 0 and 'Main:' or '') .. title.prefixedText |
| obj.hasCategories = false
| | root.tag('div') |
| | | .css('text-align', 'center') |
| return setmetatable(obj, MessageBox)
| | .wikitext(mw.ustring.format('This message box is using an invalid "type=%s" parameter and needs fixing.', args.type or '')) |
| | .done() |
| | .wikitext(mw.ustring.format('[[Category:Wikipedia message box parameter needs fixing|%s]]', catsort)) |
| | end |
| | return tostring(root) |
| end | | end |
|
| |
|
| function MessageBox:addCat(ns, cat, sort) | | function p._fmbox(args) |
| if not cat then
| | local data = {} |
| return nil
| | data.types = { |
| end
| | warning = { |
| if sort then
| | class = 'fmbox-warning', |
| cat = string.format('[[Category:%s|%s]]', cat, sort)
| | image = 'Cmbox deletion.png' |
| else
| | }, |
| cat = string.format('[[Category:%s]]', cat)
| | editnotice = { |
| end
| | class = 'fmbox-editnotice', |
| self.hasCategories = true
| | image = 'Imbox notice.png' |
| self.categories[ns] = self.categories[ns] or {}
| | }, |
| table.insert(self.categories[ns], cat)
| | 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 | | end |
|
| |
|
| function MessageBox:addClass(class) | | function p._ombox(args) |
| if not class then
| | local data = {} |
| return nil
| | data.types = { |
| end
| | speedy = { |
| table.insert(self.classes, class)
| | 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.imageSizeLarge = '40x40px' |
| | data.imageSizeSmall = '30x30px' |
| | data.imageEmptyCell = true |
| | data.imageRightNone = true |
| | return p.build(data, args) |
| end | | end |
|
| |
|
| function MessageBox:setParameters() | | function p._imbox(args) |
| local args = self.args
| | local data = {} |
| local cfg = self.cfg
| | data.types = { |
| | | speedy = { |
| -- Get type data.
| | class = 'imbox-speedy', |
| self.type = args.type
| | image = 'Imbox speedy deletion.png' |
| local typeData = cfg.types[self.type]
| | }, |
| self.invalidTypeError = cfg.showInvalidTypeError
| | delete = { |
| and self.type
| | class = 'imbox-delete', |
| and not typeData
| | image = 'Imbox deletion.png' |
| typeData = typeData or cfg.types[cfg.default]
| | }, |
| self.typeClass = typeData.class
| | content = { |
| self.typeImage = typeData.image
| | class = 'imbox-content', |
| | | image = 'Imbox content.png' |
| -- Find if the box has been wrongly substituted.
| | }, |
| self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
| | style = { |
| | | class = 'imbox-style', |
| -- Find whether we are using a small message box.
| | image = 'Edit-clear.svg' |
| self.isSmall = cfg.allowSmall and (
| | }, |
| cfg.smallParam and args.small == cfg.smallParam
| | move = { |
| or not cfg.smallParam and yesno(args.small)
| | class = 'imbox-move', |
| )
| | image = 'Imbox move.png' |
| | | }, |
| -- Add attributes, classes and styles.
| | protection = { |
| self.id = args.id
| | class = 'imbox-protection', |
| self.name = args.name
| | image = 'Imbox protection.png' |
| if self.name then
| | }, |
| self:addClass('box-' .. string.gsub(self.name,' ','_'))
| | license = { |
| end
| | class = 'imbox-license', |
| if yesno(args.plainlinks) ~= false then
| | image = 'Imbox license.png' |
| self:addClass('plainlinks')
| | }, |
| end
| | featured = { |
| for _, class in ipairs(cfg.classes or {}) do
| | class = 'imbox-featured', |
| self:addClass(class)
| | image = 'Imbox featured.png' |
| end
| | }, |
| if self.isSmall then
| | notice = { |
| self:addClass(cfg.smallClass or 'mbox-small')
| | class = 'imbox-notice', |
| end
| | image = 'Imbox notice.png' |
| self:addClass(self.typeClass)
| | } |
| self:addClass(args.class)
| | } |
| self.style = args.style
| | data.default = 'notice' |
| self.attrs = args.attrs
| | data.classes = {'imbox'} |
| | | data.classPlainlinksYesno = true |
| -- Set text style.
| | data.imageEmptyCell = true |
| self.textstyle = args.textstyle
| | data.below = true |
| | | return p.build(data, args) |
| -- Find if we are on the template page or not. This functionality is only
| |
| -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
| |
| -- and cfg.templateCategoryRequireName are set.
| |
| self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
| |
| if self.useCollapsibleTextFields
| |
| or cfg.templateCategory
| |
| and cfg.templateCategoryRequireName
| |
| then
| |
| if self.name then
| |
| local templateName = mw.ustring.match(
| |
| self.name,
| |
| '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
| |
| ) or self.name
| |
| templateName = 'Template:' .. templateName
| |
| self.templateTitle = getTitleObject(templateName)
| |
| end
| |
| self.isTemplatePage = self.templateTitle
| |
| and mw.title.equals(self.title, self.templateTitle)
| |
| end
| |
|
| |
| -- Process data for collapsible text fields. At the moment these are only
| |
| -- used in {{ambox}}.
| |
| if self.useCollapsibleTextFields then
| |
| -- Get the self.issue value.
| |
| if self.isSmall and args.smalltext then
| |
| self.issue = args.smalltext
| |
| else
| |
| local sect
| |
| if args.sect == '' then
| |
| sect = 'This ' .. (cfg.sectionDefault or 'page')
| |
| elseif type(args.sect) == 'string' then
| |
| sect = 'This ' .. args.sect
| |
| end
| |
| local issue = args.issue
| |
| issue = type(issue) == 'string' and issue ~= '' and issue or nil
| |
| local text = args.text
| |
| text = type(text) == 'string' and text or nil
| |
| local issues = {}
| |
| table.insert(issues, sect)
| |
| table.insert(issues, issue)
| |
| table.insert(issues, text)
| |
| self.issue = table.concat(issues, ' ')
| |
| end
| |
| | |
| -- Get the self.talk value.
| |
| local talk = args.talk
| |
| -- Show talk links on the template page or template subpages if the talk
| |
| -- parameter is blank.
| |
| if talk == ''
| |
| and self.templateTitle
| |
| and (
| |
| mw.title.equals(self.templateTitle, self.title)
| |
| or self.title:isSubpageOf(self.templateTitle)
| |
| )
| |
| then
| |
| talk = '#'
| |
| elseif talk == '' then
| |
| talk = nil
| |
| end
| |
| if talk then
| |
| -- If the talk value is a talk page, make a link to that page. Else
| |
| -- assume that it's a section heading, and make a link to the talk
| |
| -- page of the current page with that section heading.
| |
| local talkTitle = getTitleObject(talk)
| |
| local talkArgIsTalkPage = true
| |
| if not talkTitle or not talkTitle.isTalkPage then
| |
| talkArgIsTalkPage = false
| |
| talkTitle = getTitleObject(
| |
| self.title.text,
| |
| mw.site.namespaces[self.title.namespace].talk.id
| |
| )
| |
| end
| |
| if talkTitle and talkTitle.exists then
| |
| local talkText
| |
| if self.isSmall then
| |
| local talkLink = talkArgIsTalkPage and talk or (talkTitle.prefixedText .. '#' .. talk)
| |
| talkText = string.format('([[%s|talk]])', talkLink)
| |
| else
| |
| talkText = 'Relevant discussion may be found on'
| |
| if talkArgIsTalkPage then
| |
| talkText = string.format(
| |
| '%s [[%s|%s]].',
| |
| talkText,
| |
| talk,
| |
| talkTitle.prefixedText
| |
| )
| |
| else
| |
| talkText = string.format(
| |
| '%s the [[%s#%s|talk page]].',
| |
| talkText,
| |
| talkTitle.prefixedText,
| |
| talk
| |
| )
| |
| end
| |
| end
| |
| self.talk = talkText
| |
| end
| |
| end
| |
| | |
| -- Get other values.
| |
| self.fix = args.fix ~= '' and args.fix or nil
| |
| local date
| |
| if args.date and args.date ~= '' then
| |
| date = args.date
| |
| elseif args.date == '' and self.isTemplatePage then
| |
| date = lang:formatDate('F Y')
| |
| end
| |
| if date then
| |
| self.date = string.format(" <span class='date-container'><i>(<span class='date'>%s</span>)</i></span>", date)
| |
| end
| |
| self.info = args.info
| |
| if yesno(args.removalnotice) then
| |
| self.removalNotice = cfg.removalNotice
| |
| end
| |
| end
| |
| | |
| -- Set the non-collapsible text field. At the moment this is used by all box
| |
| -- types other than ambox, and also by ambox when small=yes.
| |
| if self.isSmall then
| |
| self.text = args.smalltext or args.text
| |
| else
| |
| self.text = args.text
| |
| end
| |
| | |
| -- Set the below row.
| |
| self.below = cfg.below and args.below
| |
| | |
| -- General image settings.
| |
| self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
| |
| self.imageEmptyCell = cfg.imageEmptyCell
| |
| | |
| -- Left image settings.
| |
| local imageLeft = self.isSmall and args.smallimage or args.image
| |
| if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none'
| |
| or not cfg.imageCheckBlank and imageLeft ~= 'none'
| |
| then
| |
| self.imageLeft = imageLeft
| |
| if not imageLeft then
| |
| local imageSize = self.isSmall
| |
| and (cfg.imageSmallSize or '30x30px')
| |
| or '40x40px'
| |
| self.imageLeft = string.format('[[File:%s|%s|link=|alt=]]', self.typeImage
| |
| or 'Imbox notice.png', imageSize)
| |
| end
| |
| end
| |
| | |
| -- Right image settings.
| |
| local imageRight = self.isSmall and args.smallimageright or args.imageright
| |
| if not (cfg.imageRightNone and imageRight == 'none') then
| |
| self.imageRight = imageRight
| |
| end
| |
|
| |
| -- set templatestyles
| |
| self.base_templatestyles = cfg.templatestyles
| |
| self.templatestyles = args.templatestyles
| |
| end
| |
| | |
| function MessageBox:setMainspaceCategories()
| |
| local args = self.args
| |
| local cfg = self.cfg
| |
| | |
| if not cfg.allowMainspaceCategories then
| |
| return nil
| |
| end
| |
| | |
| local nums = {}
| |
| for _, prefix in ipairs{'cat', 'category', 'all'} do
| |
| args[prefix .. '1'] = args[prefix]
| |
| nums = union(nums, getArgNums(args, prefix))
| |
| end
| |
| | |
| -- 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(nums) do
| |
| local mainCat = args['cat' .. tostring(num)]
| |
| or args['category' .. tostring(num)]
| |
| local allCat = args['all' .. tostring(num)]
| |
| mainCat = type(mainCat) == 'string' and mainCat
| |
| allCat = type(allCat) == 'string' and allCat
| |
| if mainCat and date and date ~= '' then
| |
| local catTitle = string.format('%s %s %s', mainCat, preposition, date)
| |
| self:addCat(0, catTitle)
| |
| catTitle = getTitleObject('Category:' .. catTitle)
| |
| if not catTitle or not catTitle.exists then
| |
| self:addCat(0, 'Articles with invalid date parameter in template')
| |
| end
| |
| elseif mainCat and (not date or date == '') then
| |
| self:addCat(0, mainCat)
| |
| end
| |
| if allCat then
| |
| self:addCat(0, allCat)
| |
| end
| |
| end
| |
| end | | end |
|
| |
|
| function MessageBox:setTemplateCategories() | | function p._cmbox(args) |
| local args = self.args
| | local data = {} |
| local cfg = self.cfg
| | data.types = { |
| | | speedy = { |
| -- Add template categories.
| | class = 'cmbox-speedy', |
| if cfg.templateCategory then
| | image = 'Cmbox deletion.png' |
| if cfg.templateCategoryRequireName then
| | }, |
| if self.isTemplatePage then
| | delete = { |
| self:addCat(10, cfg.templateCategory)
| | class = 'cmbox-delete', |
| end
| | image = 'Cmbox deletion.png' |
| elseif not self.title.isSubpage then
| | }, |
| self:addCat(10, cfg.templateCategory)
| | content = { |
| end
| | class = 'cmbox-content', |
| end
| | image = 'Cmbox content.png' |
| | | }, |
| -- Add template error categories.
| | style = { |
| if cfg.templateErrorCategory then
| | class = 'cmbox-style', |
| local templateErrorCategory = cfg.templateErrorCategory
| | image = 'Edit-clear.svg' |
| local templateCat, templateSort
| | }, |
| if not self.name and not self.title.isSubpage then
| | move = { |
| templateCat = templateErrorCategory
| | class = 'cmbox-move', |
| elseif self.isTemplatePage then
| | image = 'Cmbox move.png' |
| local paramsToCheck = cfg.templateErrorParamsToCheck or {}
| | }, |
| local count = 0
| | protection = { |
| for i, param in ipairs(paramsToCheck) do
| | class = 'cmbox-protection', |
| if not args[param] then
| | image = 'Cmbox protection.png' |
| count = count + 1
| | }, |
| end
| | notice = { |
| end
| | class = 'cmbox-notice', |
| if count > 0 then
| | image = 'Cmbox notice.png' |
| templateCat = templateErrorCategory
| | } |
| templateSort = tostring(count)
| | } |
| end
| | data.default = 'notice' |
| if self.categoryNums and #self.categoryNums > 0 then
| | data.classes = {'plainlinks', 'cmbox'} |
| templateCat = templateErrorCategory
| | return p.build(data, args) |
| templateSort = 'C'
| |
| end
| |
| end
| |
| self:addCat(10, templateCat, templateSort)
| |
| end
| |
| end | | end |
|
| |
|
| function MessageBox:setAllNamespaceCategories() | | local function makeWrapper(func) |
| -- Set categories for all namespaces.
| | return function (frame) |
| if self.invalidTypeError then
| | -- If called via #invoke, use the args passed into the invoking |
| local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
| | -- template, or the args passed to #invoke if any exist. Otherwise |
| self:addCat('all', 'Wikipedia message box parameter needs fixing', allSort)
| | -- assume args are being passed directly in from the debug console |
| end
| | -- or from another Lua module. |
| if self.isSubstituted then
| | local origArgs |
| self:addCat('all', 'Pages with incorrectly substituted templates')
| | if frame == mw.getCurrentFrame() then |
| end
| | 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 func(args) |
| | end |
| end | | end |
|
| |
|
| function MessageBox:setCategories()
| | p.fmbox = makeWrapper(p._fmbox) |
| if self.title.namespace == 0 then
| | p.imbox = makeWrapper(p._imbox) |
| self:setMainspaceCategories()
| | p.ombox = makeWrapper(p._ombox) |
| elseif self.title.namespace == 10 then
| | p.cmbox = makeWrapper(p._cmbox) |
| self:setTemplateCategories()
| |
| end
| |
| self:setAllNamespaceCategories()
| |
| end
| |
| | |
| function MessageBox:renderCategories()
| |
| if not self.hasCategories then
| |
| -- No categories added, no need to pass them to Category handler so,
| |
| -- if it was invoked, it would return the empty string.
| |
| -- So we shortcut and return the empty string.
| |
| return ""
| |
| end
| |
| -- Convert category tables to strings and pass them through
| |
| -- [[Module:Category handler]].
| |
| return require('Module:Category handler')._main{
| |
| main = table.concat(self.categories[0] or {}),
| |
| template = table.concat(self.categories[10] or {}),
| |
| all = table.concat(self.categories.all or {}),
| |
| nocat = self.args.nocat,
| |
| page = self.args.page
| |
| }
| |
| end
| |
| | |
| function MessageBox:export()
| |
| local root = mw.html.create()
| |
| | |
| -- Add the subst check error.
| |
| if self.isSubstituted and self.name then
| |
| root:tag('b')
| |
| :addClass('error')
| |
| :wikitext(string.format(
| |
| 'Template <code>%s[[Template:%s|%s]]%s</code> has been incorrectly substituted.',
| |
| mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
| |
| ))
| |
| end
| |
| | |
| local frame = mw.getCurrentFrame()
| |
| root:wikitext(frame:extensionTag{
| |
| name = 'templatestyles',
| |
| args = { src = self.base_templatestyles },
| |
| })
| |
| -- Add support for a single custom templatestyles sheet. Undocumented as
| |
| -- need should be limited and many templates using mbox are substed; we
| |
| -- don't want to spread templatestyles sheets around to arbitrary places
| |
| if self.templatestyles then
| |
| root:wikitext(frame:extensionTag{
| |
| name = 'templatestyles',
| |
| args = { src = self.templatestyles },
| |
| })
| |
| end
| |
| | |
| -- Create the box table.
| |
| local boxTable = root:tag('table')
| |
| boxTable:attr('id', self.id or nil)
| |
| for i, class in ipairs(self.classes or {}) do
| |
| boxTable:addClass(class or nil)
| |
| end
| |
| boxTable
| |
| :cssText(self.style or nil)
| |
| :attr('role', 'presentation')
| |
| | |
| if self.attrs then
| |
| boxTable:attr(self.attrs)
| |
| end
| |
| | |
| -- Add the left-hand image.
| |
| local row = boxTable:tag('tr')
| |
| if self.imageLeft then
| |
| local imageLeftCell = row:tag('td'):addClass('mbox-image')
| |
| if self.imageCellDiv then
| |
| -- If we are using a div, redefine imageLeftCell so that the image
| |
| -- is inside it. Divs use style="width: 52px;", which limits the
| |
| -- image width to 52px. If any images in a div are wider than that,
| |
| -- they may overlap with the text or cause other display problems.
| |
| imageLeftCell = imageLeftCell:tag('div'):addClass('mbox-image-div')
| |
| end
| |
| imageLeftCell:wikitext(self.imageLeft or nil)
| |
| elseif self.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')
| |
| end
| |
| | |
| -- Add the text.
| |
| local textCell = row:tag('td'):addClass('mbox-text')
| |
| if self.useCollapsibleTextFields then
| |
| -- The message box uses advanced text parameters that allow things to be
| |
| -- collapsible. At the moment, only ambox uses this.
| |
| textCell:cssText(self.textstyle or nil)
| |
| local textCellDiv = textCell:tag('div')
| |
| textCellDiv
| |
| :addClass('mbox-text-span')
| |
| :wikitext(self.issue or nil)
| |
| if (self.talk or self.fix) then
| |
| textCellDiv:tag('span')
| |
| :addClass('hide-when-compact')
| |
| :wikitext(self.talk and (' ' .. self.talk) or nil)
| |
| :wikitext(self.fix and (' ' .. self.fix) or nil)
| |
| end
| |
| textCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
| |
| if self.info and not self.isSmall then
| |
| textCellDiv
| |
| :tag('span')
| |
| :addClass('hide-when-compact')
| |
| :wikitext(self.info and (' ' .. self.info) or nil)
| |
| end
| |
| if self.removalNotice then
| |
| textCellDiv:tag('span')
| |
| :addClass('hide-when-compact')
| |
| :tag('i')
| |
| :wikitext(string.format(" (%s)", self.removalNotice))
| |
| end
| |
| else
| |
| -- Default text formatting - anything goes.
| |
| textCell
| |
| :cssText(self.textstyle or nil)
| |
| :wikitext(self.text or nil)
| |
| end
| |
| | |
| -- Add the right-hand image.
| |
| if self.imageRight then
| |
| local imageRightCell = row:tag('td'):addClass('mbox-imageright')
| |
| if self.imageCellDiv then
| |
| -- If we are using a div, redefine imageRightCell so that the image
| |
| -- is inside it.
| |
| imageRightCell = imageRightCell:tag('div'):addClass('mbox-image-div')
| |
| end
| |
| imageRightCell
| |
| :wikitext(self.imageRight or nil)
| |
| end
| |
| | |
| -- Add the below row.
| |
| if self.below then
| |
| boxTable:tag('tr')
| |
| :tag('td')
| |
| :attr('colspan', self.imageRight and '3' or '2')
| |
| :addClass('mbox-text')
| |
| :cssText(self.textstyle or nil)
| |
| :wikitext(self.below or nil)
| |
| end
| |
| | |
| -- Add error message for invalid type parameters.
| |
| if self.invalidTypeError then
| |
| root:tag('div')
| |
| :addClass('mbox-invalid-type')
| |
| :wikitext(string.format(
| |
| 'This message box is using an invalid "type=%s" parameter and needs fixing.',
| |
| self.type or ''
| |
| ))
| |
| end
| |
| | |
| -- Add categories.
| |
| root:wikitext(self:renderCategories() or nil)
| |
| | |
| return tostring(root)
| |
| end
| |
| | |
| --------------------------------------------------------------------------------
| |
| -- Exports
| |
| --------------------------------------------------------------------------------
| |
| | |
| local p, mt = {}, {}
| |
| | |
| function p._exportClasses()
| |
| -- For testing.
| |
| return {
| |
| MessageBox = MessageBox
| |
| }
| |
| end
| |
| | |
| function p.main(boxType, args, cfgTables)
| |
| local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
| |
| box:setParameters()
| |
| box:setCategories()
| |
| return box:export()
| |
| end
| |
| | |
| function mt.__index(t, k)
| |
| return function (frame)
| |
| if not getArgs then
| |
| getArgs = require('Module:Arguments').getArgs
| |
| end
| |
| return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
| |
| end
| |
| end
| |
|
| |
|
| return setmetatable(p, mt) | | return p |