Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Editing Module:Message box

From WikiOasis Meta
Warning: You are not logged in. Once you make an edit, a temporary account will be created for you. Learn more. Log in or create an account to continue receiving notifications after this account expires, and to access other features.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('strict')
require('strict')
local getArgs
local getArgs
local yesno = require('Module:Yesno')
local yesno = require('Module:Yesno')
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
local lang = mw.language.getContentLanguage()


-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
local CONFIG_MODULE = 'Module:Message box/configuration'
local DEMOSPACES = {talk = 'tmbox', image = 'imbox', file = 'imbox', category = 'cmbox', article = 'ambox', main = 'ambox'}
local DEMOSPACES = {talk = 'tmbox', image = 'imbox', file = 'imbox', category = 'cmbox', article = 'ambox', main = 'ambox'}
local TEMPLATE_STYLES = 'Module:Message box/%s.css'


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Line 59: Line 67:
args = args or {}
args = args or {}
local obj = {}
local obj = {}
obj.boxType = boxType


-- Set the title object and the namespace.
-- Set the title object and the namespace.
Line 74: Line 84:
-- use template from DEMOSPACES
-- use template from DEMOSPACES
obj.cfg = cfg[DEMOSPACES[demospace]]
obj.cfg = cfg[DEMOSPACES[demospace]]
obj.boxType = DEMOSPACES[demospace]
elseif string.find( demospace, 'talk' ) then
elseif string.find( demospace, 'talk' ) then
-- demo as a talk page
-- demo as a talk page
obj.cfg = cfg.tmbox
obj.cfg = cfg.tmbox
obj.boxType = 'tmbox'
else
else
-- default to ombox
-- default to ombox
obj.cfg = cfg.ombox
obj.cfg = cfg.ombox
obj.boxType = 'ombox'
end
end
elseif ns == 0 then
elseif ns == 0 then
obj.cfg = cfg.ambox -- main namespace
obj.cfg = cfg.ambox -- main namespace
obj.boxType = 'ambox'
elseif ns == 6 then
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
obj.cfg = cfg.imbox -- file namespace
obj.boxType = 'imbox'
elseif ns == 14 then
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
obj.cfg = cfg.cmbox -- category namespace
obj.boxType = 'cmbox'
else
else
local nsTable = mw.site.namespaces[ns]
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
obj.cfg = cfg.tmbox -- any talk namespace
obj.boxType = 'tmbox'
else
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
obj.cfg = cfg.ombox -- other namespaces or invalid input
obj.boxType = 'ombox'
end
end
end
end
Line 139: Line 157:
return nil
return nil
end
end
table.insert(self.classes, class)
self.classes[class] = 1
end
 
function MessageBox:removeClass(class)
if not class then
return nil
end
self.classes[class] = nil
end
end


Line 155: Line 180:
self.typeClass = typeData.class
self.typeClass = typeData.class
self.typeImage = typeData.image
self.typeImage = typeData.image
self.typeImageNeedsLink = typeData.imageNeedsLink


-- Find if the box has been wrongly substituted.
-- Find if the box has been wrongly substituted.
Line 166: Line 190:
)
)


-- Set the below row.
self.below = cfg.below and args.below
-- Add attributes, classes and styles.
-- Add attributes, classes and styles.
self.id = args.id
self.id = args.id
self.name = args.name
self.name = args.name
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.name then
if self.name then
self:addClass('box-' .. string.gsub(self.name,' ','_'))
self:addClass('box-' .. string.gsub(self.name,' ','_'))
end
end
if yesno(args.plainlinks) ~= false then
local plainlinks = yesno(args.plainlinks)
if plainlinks == true then
self:addClass('plainlinks')
self:addClass('plainlinks')
end
elseif plainlinks == false then
if self.below then
self:removeClass('plainlinks')
self:addClass('mbox-with-below')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
end
if self.isSmall then
if self.isSmall then
Line 194: Line 215:
-- Set text style.
-- Set text style.
self.textstyle = args.textstyle
self.textstyle = args.textstyle
-- Set image classes.
self.imageRightClass = args.imagerightclass or args.imageclass
self.imageLeftClass = args.imageleftclass or args.imageclass


-- Find if we are on the template page or not. This functionality is only
-- Find if we are on the template page or not. This functionality is only
Line 272: Line 289:
end
end
if talkTitle and talkTitle.exists then
if talkTitle and talkTitle.exists then
                local talkText
local talkText = 'Relevant discussion may be found on'
                if self.isSmall then
if talkArgIsTalkPage then
                    local talkLink = talkArgIsTalkPage and talk or (talkTitle.prefixedText .. (talk == '#' and '' or '#') .. talk)
talkText = string.format(
                    talkText = string.format('([[%s|talk]])', talkLink)
'%s [[%s|%s]].',
                else
talkText,
                    talkText = 'Relevant discussion may be found on'
talk,
                    if talkArgIsTalkPage then
talkTitle.prefixedText
                        talkText = string.format(
)
                            '%s [[%s|%s]].',
else
                            talkText,
talkText = string.format(
                            talk,
'%s the [[%s#%s|talk page]].',
                            talkTitle.prefixedText
talkText,
                        )
talkTitle.prefixedText,
                    else
talk
                        talkText = string.format(
)
                            '%s the [[%s' .. (talk == '#' and '' or '#') .. '%s|talk page]].',
end
                            talkText,
                            talkTitle.prefixedText,
                            talk
                        )
                    end
                end
self.talk = talkText
self.talk = talkText
end
end
Line 307: Line 318:
end
end
if date then
if date then
self.date = string.format(" <span class='date-container'><i>(<span class='date'>%s</span>)</i></span>", date)
self.date = string.format(" <small class='date-container'>''(<span class='date'>%s</span>)''</small>", date)
end
end
self.info = args.info
self.info = args.info
Line 322: Line 333:
self.text = args.text
self.text = args.text
end
end
-- Set the below row.
self.below = cfg.below and args.below


-- General image settings.
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end


-- Left image settings.
-- Left image settings.
Line 337: Line 354:
and (cfg.imageSmallSize or '30x30px')
and (cfg.imageSmallSize or '30x30px')
or '40x40px'
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s%s|alt=]]', self.typeImage
self.imageLeft = string.format('[[File:%s|%s|link=|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize, self.typeImageNeedsLink and "" or "|link=" )
or 'Information icon4.svg', imageSize)
end
end
end
end
Line 347: Line 364:
self.imageRight = imageRight
self.imageRight = imageRight
end
end
-- set templatestyles
self.base_templatestyles = cfg.templatestyles
self.templatestyles = args.templatestyles
end
end


Line 437: Line 450:
function MessageBox:setAllNamespaceCategories()
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Wikipedia message box parameter needs fixing', allSort)
end
if self.isSubstituted then
if self.isSubstituted then
self:addCat('all', 'Pages with incorrectly substituted templates')
self:addCat('all', 'Pages with incorrectly substituted templates')
Line 473: Line 482:
end
end


function MessageBox:exportDiv()
function MessageBox:export()
local root = mw.html.create()
local root = mw.html.create()


Line 486: Line 495:
end
end


local frame = mw.getCurrentFrame()
-- Add TemplateStyles
root:wikitext(frame:extensionTag{
root:wikitext(mw.getCurrentFrame():extensionTag{
name = 'templatestyles',
name = 'templatestyles',
args = { src = self.base_templatestyles },
args = { src = TEMPLATE_STYLES:format(self.boxType) },
})
})
-- 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.
-- Create the box table.
local mbox = root:tag('div')
local boxTable
mbox:attr('id', self.id or nil)
-- Check for fmbox because not all interface messages have mw-parser-output
for i, class in ipairs(self.classes or {}) do
-- which is necessary for TemplateStyles. Add the wrapper class if it is and
mbox:addClass(class or nil)
-- then start the actual mbox, else start the mbox.
end
if self.boxType == 'fmbox' then
mbox
boxTable = root:tag('div')
:cssText(self.style or nil)
:addClass('mw-parser-output')
 
:tag('table')
if self.attrs then
mbox:attr(self.attrs)
end
local flex_container
if self.below then
-- we need to wrap the flex components (`image(right)` and `text`) in their
-- own container div to support the `below` parameter
flex_container = mw.html.create('div')
flex_container:addClass('mbox-flex')
else
-- the mbox itself is the parent, so we need no HTML flex_container
flex_container = mw.html.create()
end
 
-- Add the left-hand image.
if self.imageLeft then
local imageLeftCell = flex_container:tag('div'):addClass('mbox-image')
imageLeftCell
:addClass(self.imageLeftClass)
:wikitext(self.imageLeft or nil)
end
 
-- Add the text.
local textCell = flex_container:tag('div'):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
else
-- Default text formatting - anything goes.
boxTable = root:tag('table')
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
 
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = flex_container:tag('div'):addClass('mbox-imageright')
imageRightCell
:addClass(self.imageRightClass)
:wikitext(self.imageRight or nil)
end
mbox:node(flex_container)
 
-- Add the below row.
if self.below then
mbox:tag('div')
:addClass('mbox-text mbox-below')
: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
end


-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
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)
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
for class, _ in pairs(self.classes or {}) do
boxTable:addClass(class or nil)
boxTable:addClass(class or nil)
end
end
Line 655: Line 535:
-- image width to 52px. If any images in a div are wider than that,
-- 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.
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):addClass('mbox-image-div')
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
end
imageLeftCell
imageLeftCell:wikitext(self.imageLeft or nil)
:addClass(self.imageLeftClass)
:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- Some message boxes define an empty cell if no image is specified, and
Line 667: Line 545:
row:tag('td')
row:tag('td')
:addClass('mbox-empty-cell')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
end


Line 679: Line 558:
:addClass('mbox-text-span')
:addClass('mbox-text-span')
:wikitext(self.issue or nil)
:wikitext(self.issue or nil)
if (self.talk or self.fix) then
if (self.talk or self.fix) and not self.isSmall then
textCellDiv:tag('span')
textCellDiv:tag('span')
:addClass('hide-when-compact')
:addClass('hide-when-compact')
Line 693: Line 572:
end
end
if self.removalNotice then
if self.removalNotice then
textCellDiv:tag('span')
textCellDiv:tag('small')
:addClass('hide-when-compact')
:addClass('hide-when-compact')
:tag('i')
:tag('i')
Line 711: Line 590:
-- If we are using a div, redefine imageRightCell so that the image
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
-- is inside it.
imageRightCell = imageRightCell:tag('div'):addClass('mbox-image-div')
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
end
imageRightCell
imageRightCell
:addClass(self.imageRightClass)
:wikitext(self.imageRight or nil)
:wikitext(self.imageRight or nil)
end
end
Line 731: Line 609:
if self.invalidTypeError then
if self.invalidTypeError then
root:tag('div')
root:tag('div')
:addClass('mbox-invalid-type')
:css('text-align', 'center')
:wikitext(string.format(
:wikitext(string.format(
'This message box is using an invalid "type=%s" parameter and needs fixing.',
'This message box is using an invalid "type=%s" parameter and needs fixing.',
Line 761: Line 639:
box:setParameters()
box:setParameters()
box:setCategories()
box:setCategories()
-- DIV MIGRATION CONDITIONAL
if box.cfg.div_structure then
return box:exportDiv()
end
-- END DIV MIGRATION CONDITIONAL
return box:export()
return box:export()
end
end
Please note that all contributions to WikiOasis Meta are considered to be released under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) (see Meta:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)

 

Page included on this page:

Cookies help us deliver our services. By using our services, you agree to our use of cookies.