Module:Message box
This template is from Wikipedia.
require('strict')
local getArgs
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'}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
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 in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
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
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
if args.demospace and args.demospace ~= '' then
local demospace = string.lower(args.demospace)
if DEMOSPACES[demospace] then
obj.cfg = cfg[DEMOSPACES[demospace]]
elseif string.find(demospace, 'talk') then
obj.cfg = cfg.tmbox
else
obj.cfg = cfg.ombox
end
elseif ns == 0 then
obj.cfg = cfg.ambox
elseif ns == 6 then
obj.cfg = cfg.imbox
elseif ns == 14 then
obj.cfg = cfg.cmbox
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox
else
obj.cfg = cfg.ombox
end
end
end
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
obj.categories = {}
obj.classes = {}
obj.hasCategories = false
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then return nil end
if sort then
cat = string.format('[[Category:%s|%s]]', cat, sort)
else
cat = string.format('[[Category:%s]]', cat)
end
self.hasCategories = true
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then return nil end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
self.typeImageNeedsLink = typeData.imageNeedsLink
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
self.id = args.id
self.name = args.name
if self.name then
self:addClass('box-' .. string.gsub(self.name, ' ', '_'))
end
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.textstyle = args.textstyle
self.imageRightClass = args.imagerightclass or args.imageclass
self.imageLeftClass = args.imageleftclass or args.imageclass
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
if self.useCollapsibleTextFields then
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
local talk = args.talk
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
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 == '#' and '' or '#') .. 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' .. (talk == '#' and '' or '#') .. '%s|talk page]].', talkText, talkTitle.prefixedText, talk)
end
end
self.talk = talkText
end
end
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
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
end
self.below = args.below
self.page = args.page
return self
end
function MessageBox:getArgs()
return self.args
end
function MessageBox:export()
local root = mw.html.create('div')
root
:addClass('mbox')
:addClass(table.concat(self.classes, ' '))
:attr('id', self.id)
:attr('style', self.style)
:attr('aria-label', self.cfg.ariaLabel)
:attr('role', 'region')
:attr('tabindex', 0)
:attr('lang', self.cfg.lang or lang:getCode())
-- Removed all dynamic templatestyles loading here to rely solely on MediaWiki:Common.css
local content = mw.html.create('div')
content:addClass('mbox-text')
if self.textstyle then
content:cssText(self.textstyle)
end
content:wikitext(self.text or '')
root:node(content)
if self.below and self.below ~= '' then
root:wikitext(self.below)
end
if self.hasCategories then
for ns, cats in pairs(self.categories) do
for _, cat in ipairs(cats) do
root:wikitext(cat)
end
end
end
return tostring(root)
end
--------------------------------------------------------------------------------
-- Module entry point
--------------------------------------------------------------------------------
local function main(frame)
local args = getArgs and getArgs(frame) or {}
local cfg = mw.loadData(CONFIG_MODULE)
local boxType = args.type or cfg.default
local box = MessageBox.new(boxType, args, cfg)
box:setParameters()
return box:export()
end
getArgs = function(frame)
return frame:getParent().args or frame.args or {}
end
return {
main = main,
}