Difference between revisions of "Module:Message box"
Jump to navigation
Jump to search
Created page with "-- This is a meta-module for producing message box templates, including {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Require necessary m..."
>Mr. Stradivarius (fix bug for data being shared between multiple message boxes called from the same module; allow boxes to be hidden; use Module:Arguments to fetch the arguments) |
(Created page with "-- This is a meta-module for producing message box templates, including {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Require necessary m...") |
||
Line 1: | Line 1: | ||
-- This is a meta-module for producing message box templates, including {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. | -- This is a meta-module for producing message box templates, including {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. | ||
-- Require necessary modules. | -- Require necessary modules. | ||
local getArgs = require('Module:Arguments').getArgs | local getArgs = require('Module:Arguments').getArgs | ||
Line 6: | Line 6: | ||
local categoryHandler = require('Module:Category handler').main | local categoryHandler = require('Module:Category handler').main | ||
local yesno = require('Module:Yesno') | local yesno = require('Module:Yesno') | ||
-- Load the configuration page. | -- Load the configuration page. | ||
local cfgTables = mw.loadData('Module:Message box/configuration') | local cfgTables = mw.loadData('Module:Message box/configuration') | ||
-- Get a language object for formatDate and ucfirst. | -- Get a language object for formatDate and ucfirst. | ||
local lang = mw.language.getContentLanguage() | local lang = mw.language.getContentLanguage() | ||
-- Set aliases for often-used functions to reduce table lookups. | -- Set aliases for often-used functions to reduce table lookups. | ||
local format = mw.ustring.format | local format = mw.ustring.format | ||
Line 18: | Line 18: | ||
local tconcat = table.concat | local tconcat = table.concat | ||
local trim = mw.text.trim | local trim = mw.text.trim | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Helper functions | -- Helper functions | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local function getTitleObject(page, ...) | local function getTitleObject(page, ...) | ||
if type(page) == 'string' then | if type(page) == 'string' then | ||
Line 33: | Line 33: | ||
end | end | ||
end | end | ||
local function union(t1, t2) | local function union(t1, t2) | ||
-- Returns the union of two arrays. | -- Returns the union of two arrays. | ||
Line 50: | Line 50: | ||
return ret | return ret | ||
end | end | ||
local function getArgNums(args, prefix) | local function getArgNums(args, prefix) | ||
local nums = {} | local nums = {} | ||
Line 62: | Line 62: | ||
return nums | return nums | ||
end | end | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Box class definition | -- Box class definition | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local box = {} | local box = {} | ||
box.__index = box | box.__index = box | ||
function box.new() | function box.new() | ||
local obj = {} | local obj = {} | ||
Line 75: | Line 75: | ||
return obj | return obj | ||
end | end | ||
function box.getNamespaceId(ns) | function box.getNamespaceId(ns) | ||
if not ns then return end | if not ns then return end | ||
Line 89: | Line 89: | ||
end | end | ||
end | end | ||
function box.getMboxType(nsid) | function box.getMboxType(nsid) | ||
-- Gets the mbox type from a namespace number. | -- Gets the mbox type from a namespace number. | ||
Line 107: | Line 107: | ||
end | end | ||
end | end | ||
function box:addCat(ns, cat, sort) | function box:addCat(ns, cat, sort) | ||
if type(cat) ~= 'string' then return end | if type(cat) ~= 'string' then return end | ||
Line 130: | Line 130: | ||
end | end | ||
end | end | ||
function box:addClass(class) | function box:addClass(class) | ||
if type(class) ~= 'string' then return end | if type(class) ~= 'string' then return end | ||
Line 136: | Line 136: | ||
tinsert(self.classes, class) | tinsert(self.classes, class) | ||
end | end | ||
function box:setTitle(args) | function box:setTitle(args) | ||
-- Get the title object and the namespace. | -- Get the title object and the namespace. | ||
Line 144: | Line 144: | ||
self.nsid = box.getNamespaceId(self.demospace) or self.title.namespace | self.nsid = box.getNamespaceId(self.demospace) or self.title.namespace | ||
end | end | ||
function box:getConfig(boxType) | function box:getConfig(boxType) | ||
-- Get the box config data from the data page. | -- Get the box config data from the data page. | ||
Line 161: | Line 161: | ||
return cfg | return cfg | ||
end | end | ||
function box:removeBlankArgs(cfg, args) | function box:removeBlankArgs(cfg, args) | ||
-- Only allow blank arguments for the parameter names listed in cfg.allowBlankParams. | -- Only allow blank arguments for the parameter names listed in cfg.allowBlankParams. | ||
Line 175: | Line 175: | ||
return newArgs | return newArgs | ||
end | end | ||
function box:setBoxParameters(cfg, args) | function box:setBoxParameters(cfg, args) | ||
-- Get type data. | -- Get type data. | ||
Line 184: | Line 184: | ||
self.typeClass = typeData.class | self.typeClass = typeData.class | ||
self.typeImage = typeData.image | self.typeImage = typeData.image | ||
-- Find if the box has been wrongly substituted. | -- Find if the box has been wrongly substituted. | ||
if cfg.substCheck and args.subst == 'SUBST' then | if cfg.substCheck and args.subst == 'SUBST' then | ||
self.isSubstituted = true | self.isSubstituted = true | ||
end | end | ||
-- Find whether we are using a small message box. | -- Find whether we are using a small message box. | ||
if cfg.allowSmall and ( | if cfg.allowSmall and ( | ||
Line 200: | Line 200: | ||
self.isSmall = false | self.isSmall = false | ||
end | end | ||
-- Add attributes, classes and styles. | -- Add attributes, classes and styles. | ||
if cfg.allowId then | if cfg.allowId then | ||
Line 218: | Line 218: | ||
self:addClass(args.class) | self:addClass(args.class) | ||
self.style = args.style | self.style = args.style | ||
-- Set text style. | -- Set text style. | ||
self.textstyle = args.textstyle | self.textstyle = args.textstyle | ||
-- Find if we are on the template page or not. This functionality is only used if useCollapsibleTextFields is set, | -- 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. | -- or if both cfg.templateCategory and cfg.templateCategoryRequireName are set. | ||
Line 234: | Line 234: | ||
self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) or false | self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) or false | ||
end | end | ||
-- Process data for collapsible text fields. At the moment these are only used in {{ambox}}. | -- Process data for collapsible text fields. At the moment these are only used in {{ambox}}. | ||
if self.useCollapsibleTextFields then | if self.useCollapsibleTextFields then | ||
Line 257: | Line 257: | ||
self.issue = tconcat(issues, ' ') | self.issue = tconcat(issues, ' ') | ||
end | end | ||
-- Get the self.talk value. | -- Get the self.talk value. | ||
local talk = args.talk | local talk = args.talk | ||
Line 287: | Line 287: | ||
end | end | ||
end | end | ||
-- Get other values. | -- Get other values. | ||
self.fix = args.fix ~= '' and args.fix or nil | self.fix = args.fix ~= '' and args.fix or nil | ||
Line 301: | Line 301: | ||
self.info = args.info | self.info = args.info | ||
end | end | ||
-- Set the non-collapsible text field. At the moment this is used by all box types other than ambox, | -- 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. | -- and also by ambox when small=yes. | ||
Line 309: | Line 309: | ||
self.text = args.text | self.text = args.text | ||
end | end | ||
-- Set the below row. | -- Set the below row. | ||
self.below = cfg.below and args.below | self.below = cfg.below and args.below | ||
-- General image settings. | -- General image settings. | ||
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv and true or false | self.imageCellDiv = not self.isSmall and cfg.imageCellDiv and true or false | ||
Line 319: | Line 319: | ||
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' | self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' | ||
end | end | ||
-- Left image settings. | -- Left image settings. | ||
local imageLeft = self.isSmall and args.smallimage or args.image | local imageLeft = self.isSmall and args.smallimage or args.image | ||
Line 331: | Line 331: | ||
end | end | ||
end | end | ||
-- Right image settings. | -- Right image settings. | ||
local imageRight = self.isSmall and args.smallimageright or args.imageright | local imageRight = self.isSmall and args.smallimageright or args.imageright | ||
Line 337: | Line 337: | ||
self.imageRight = imageRight | self.imageRight = imageRight | ||
end | end | ||
-- Add mainspace categories. At the moment these are only used in {{ambox}}. | -- Add mainspace categories. At the moment these are only used in {{ambox}}. | ||
if cfg.allowMainspaceCategories then | if cfg.allowMainspaceCategories then | ||
Line 378: | Line 378: | ||
end | end | ||
end | end | ||
-- Add template-namespace categories. | -- Add template-namespace categories. | ||
if cfg.templateCategory then | if cfg.templateCategory then | ||
Line 389: | Line 389: | ||
end | end | ||
end | end | ||
-- Add template error category. | -- Add template error category. | ||
if cfg.templateErrorCategory then | if cfg.templateErrorCategory then | ||
Line 415: | Line 415: | ||
self:addCat('template', templateCat, templateSort) | self:addCat('template', templateCat, templateSort) | ||
end | end | ||
-- Categories for all namespaces. | -- Categories for all namespaces. | ||
if self.invalidTypeError then | if self.invalidTypeError then | ||
Line 424: | Line 424: | ||
self:addCat('all', 'Pages with incorrectly substituted templates') | self:addCat('all', 'Pages with incorrectly substituted templates') | ||
end | end | ||
-- Convert category tables to strings and pass them through [[Module:Category handler]]. | -- Convert category tables to strings and pass them through [[Module:Category handler]]. | ||
self.categories = categoryHandler{ | self.categories = categoryHandler{ | ||
Line 435: | Line 435: | ||
} | } | ||
end | end | ||
function box:export() | function box:export() | ||
local root = htmlBuilder.create() | local root = htmlBuilder.create() | ||
-- Add the subst check error. | -- Add the subst check error. | ||
if self.isSubstituted and self.name then | if self.isSubstituted and self.name then | ||
Line 449: | Line 449: | ||
)) | )) | ||
end | end | ||
-- Create the box table. | -- Create the box table. | ||
local boxTable = root.tag('table') | local boxTable = root.tag('table') | ||
Line 461: | Line 461: | ||
.cssText(self.style) | .cssText(self.style) | ||
.attr('role', 'presentation') | .attr('role', 'presentation') | ||
-- Add the left-hand image. | -- Add the left-hand image. | ||
local row = boxTable.tag('tr') | local row = boxTable.tag('tr') | ||
Line 483: | Line 483: | ||
.cssText(self.imageEmptyCellStyle) | .cssText(self.imageEmptyCellStyle) | ||
end | end | ||
-- Add the text. | -- Add the text. | ||
local textCell = row.tag('td').addClass('mbox-text') | local textCell = row.tag('td').addClass('mbox-text') | ||
Line 516: | Line 516: | ||
.wikitext(self.text) | .wikitext(self.text) | ||
end | end | ||
-- Add the right-hand image. | -- Add the right-hand image. | ||
if self.imageRight then | if self.imageRight then | ||
Line 526: | Line 526: | ||
.wikitext(self.imageRight) | .wikitext(self.imageRight) | ||
end | end | ||
-- Add the below row. | -- Add the below row. | ||
if self.below then | if self.below then | ||
Line 536: | Line 536: | ||
.wikitext(self.below) | .wikitext(self.below) | ||
end | end | ||
-- Add error message for invalid type parameters. | -- Add error message for invalid type parameters. | ||
if self.invalidTypeError then | if self.invalidTypeError then | ||
Line 544: | Line 544: | ||
.wikitext(format('This message box is using an invalid "type=%s" parameter and needs fixing.', self.type or '')) | .wikitext(format('This message box is using an invalid "type=%s" parameter and needs fixing.', self.type or '')) | ||
end | end | ||
-- Add categories. | -- Add categories. | ||
root | root | ||
.wikitext(self.categories) | .wikitext(self.categories) | ||
return tostring(root) | return tostring(root) | ||
end | end | ||
local function main(boxType, args) | local function main(boxType, args) | ||
local outputBox = box.new() | local outputBox = box.new() | ||
Line 560: | Line 560: | ||
return outputBox:export() | return outputBox:export() | ||
end | end | ||
local function makeWrapper(boxType) | local function makeWrapper(boxType) | ||
return function (frame) | return function (frame) | ||
Line 567: | Line 567: | ||
end | end | ||
end | end | ||
local p = { | local p = { | ||
main = main, | main = main, | ||
mbox = makeWrapper('mbox') | mbox = makeWrapper('mbox') | ||
} | } | ||
for boxType in pairs(cfgTables) do | for boxType in pairs(cfgTables) do | ||
p[boxType] = makeWrapper(boxType) | p[boxType] = makeWrapper(boxType) | ||
end | end | ||
return p | return p |