The wiki has moved!

Visit the new wiki at stationeers-wiki.com The old wiki here at legacy.stationeers-wiki.com will sunset eventually.

Edits made after the 7th of March 6PM EST were NOT carried over to the new server as previously announced right here in this box.

 Actions

Module

Difference between revisions of "Message box"

From Unofficial Stationeers Wiki

(more ambox stuff - still a little broken)
(Fixed a few of the ambox bugs. Still have to add category support.)
Line 17: Line 17:
 
         end
 
         end
 
     end
 
     end
     return page or mw.title.getCurrentTitle()
+
     return page
 +
end
 +
 
 +
local function presentButBlank(s)
 +
    if type(s) ~= 'string' then return end
 +
    if s and not mw.ustring.find(s, '%S') then
 +
        return true
 +
    else
 +
        return false
 +
    end
 
end
 
end
  
Line 24: Line 33:
 
     local title = mw.title.getCurrentTitle()
 
     local title = mw.title.getCurrentTitle()
 
     local nsid = title.namespace
 
     local nsid = title.namespace
 +
 +
    -- Get a language object for formatDate.
 +
    local lang = mw.language.getContentLanguage()
 
      
 
      
 
-- Commenting this out for now - this will require tinkering with Namespace detect to differentiate between
 
-- Commenting this out for now - this will require tinkering with Namespace detect to differentiate between
Line 48: Line 60:
  
 
     -- Process data for collapsible text fields
 
     -- Process data for collapsible text fields
     local text, talk, fix, date, info
+
     local name, issue, talk, fix, date, info
 
     if data.useCollapsibleTextFields then
 
     if data.useCollapsibleTextFields then
         text = args.issue
+
         name = args.name
 +
        local nameTitle = getTitleObject(name)
 +
        local isTemplatePage = nameTitle and title.prefixedText == ('Template:' .. nameTitle.text) and true or false
 +
        local sect = args.sect
 +
        if presentButBlank(sect) then
 +
            sect = 'This article '
 +
        elseif type(sect) == 'string' then
 +
            sect = 'This ' .. sect .. ' '
 +
        end
 +
        issue = (sect or '') .. (args.issue or '') .. ' ' .. (args.text or '')
 
         talk = args.talk
 
         talk = args.talk
 +
        if presentButBlank(talk) and isTemplatePage then
 +
            talk = '#'
 +
        end
 
         fix = args.fix
 
         fix = args.fix
 
         date = args.date
 
         date = args.date
 +
        if presentButBlank(date) and isTemplatePage then
 +
            date = lang:formatDate('F Y')
 +
        end
 
         info = args.info
 
         info = args.info
     else
+
     end
        text = args.text
+
 
 +
    -- Process the talk link, if present.
 +
    if talk then
 +
        -- See if the talk link exists and is for a talk or a content namespace.
 +
        local talkTitle = type(talk) == 'string' and getTitleObject(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.
 +
            local success
 +
            success, talkTitle = pcall(title.talkPageTitle, title)
 +
            if not 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 = mw.ustring.format('%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText)
 +
            else
 +
                talkText = mw.ustring.format('%s the [[%s#%s|talk page]].', talkText, talkTitle.prefixedText, talk)
 +
            end
 +
            talk = talkText
 +
        end
 
     end
 
     end
  
 
     -- Find whether we are using a small message box and process our data accordingly.
 
     -- Find whether we are using a small message box and process our data accordingly.
 
     local isSmall = data.allowSmall and (args.small == 'yes' or args.small == true) and true or false
 
     local isSmall = data.allowSmall and (args.small == 'yes' or args.small == true) and true or false
     local smallClass, image, imageRight, imageSize
+
     local smallClass, image, imageRight, text, imageSize
 
     if isSmall then
 
     if isSmall then
 
         smallClass = data.smallClass or 'mbox-small'
 
         smallClass = data.smallClass or 'mbox-small'
 
         image = args.smallimage or args.image
 
         image = args.smallimage or args.image
 
         imageRight = args.smallimageright or args.imageright
 
         imageRight = args.smallimageright or args.imageright
         text = args.smalltext or text
+
         if data.useCollapsibleTextFields then
 +
            text = args.smalltext or issue
 +
        else
 +
            text = args.smalltext or args.text
 +
        end
 
         imageSize = data.imageSmallSize or '30x30px'
 
         imageSize = data.imageSmallSize or '30x30px'
 
     else
 
     else
Line 72: Line 124:
 
         imageRight = args.imageright
 
         imageRight = args.imageright
 
         imageSize = '40x40px'
 
         imageSize = '40x40px'
 +
        text = args.text
 
     end
 
     end
 
    ------------------------ Get the box structure ----------------------------
 
 
    local root = htmlBuilder.create() -- Includes error messages and categories added after the box.
 
    local substCheck = root.tag('b').addClass('error')
 
    local box = root.tag('table')
 
    local row = box.tag('tr')
 
    local imageLeftCell = row.tag('td').addClass('mbox-image')
 
    local textCell = row.tag('td').addClass('mbox-text')
 
    local imageRightCell = row.tag('td').addClass('mbox-imageright')
 
  
 
     ------------------------ Build the box ----------------------------
 
     ------------------------ Build the box ----------------------------
 +
   
 +
    local root = htmlBuilder.create()
  
 
     -- Do the subst check.
 
     -- Do the subst check.
 
     if data.substCheck and args.subst == 'SUBST' then
 
     if data.substCheck and args.subst == 'SUBST' then
 
         if type(args.name) == 'string' then
 
         if type(args.name) == 'string' then
             substCheck
+
             root
                 .wikitext(mw.ustring.format(
+
                 .tag('b')
                    'Template <code>%s%s%s</code> has been incorrectly substituted.',
+
                    .addClass('error')
                    mw.text.nowiki('{{'),
+
                    .wikitext(mw.ustring.format(
                    args.name,
+
                        'Template <code>%s%s%s</code> has been incorrectly substituted.',
                    mw.text.nowiki('}}')
+
                        mw.text.nowiki('{{'),
                ))
+
                        args.name,
 +
                        mw.text.nowiki('}}')
 +
                    ))
 
         end
 
         end
         root.wikitext('[[Category:Pages with incorrectly substituted templates]]') -- This puts the category at the *end* of the output, rather than after the subst error message.
+
         root.wikitext('[[Category:Pages with incorrectly substituted templates]]')
 
     end
 
     end
  
 
     -- Build the box.
 
     -- Build the box.
 +
    local box = root.tag('table')
 
     box
 
     box
 
         .attr('id', args.id)
 
         .attr('id', args.id)
Line 116: Line 164:
  
 
     -- Add the left-hand image.
 
     -- Add the left-hand image.
 +
    local row = box.tag('tr')
 +
    local imageLeftCell = row.tag('td').addClass('mbox-image')
 
     local imageCheckBlank = data.imageCheckBlank
 
     local imageCheckBlank = data.imageCheckBlank
 
     if image ~= 'none' and not imageCheckBlank or image ~= 'none' and imageCheckBlank and image ~= 'blank' then
 
     if image ~= 'none' and not imageCheckBlank or image ~= 'none' and imageCheckBlank and image ~= 'blank' then
Line 130: Line 180:
  
 
     -- Add the text.
 
     -- Add the text.
 +
    local textCell = row.tag('td').addClass('mbox-text')
 
     if data.useCollapsibleTextFields then
 
     if data.useCollapsibleTextFields then
 
         textCell
 
         textCell
Line 136: Line 187:
 
         textCellSpan
 
         textCellSpan
 
             .addClass('mbox-text-span')
 
             .addClass('mbox-text-span')
             .wikitext(text)
+
             .wikitext(issue)
 
         if not isSmall then
 
         if not isSmall then
 
             textCellSpan
 
             textCellSpan
Line 142: Line 193:
 
                     .addClass('hide-when-compact')
 
                     .addClass('hide-when-compact')
 
                     .wikitext(talk)
 
                     .wikitext(talk)
 +
                    .wikitext(' ')
 
                     .wikitext(fix)
 
                     .wikitext(fix)
 
                     .done()
 
                     .done()
Line 160: Line 212:
  
 
     -- Add the right-hand image.
 
     -- Add the right-hand image.
 +
    local imageRightCell = row.tag('td').addClass('mbox-imageright')
 
     if imageRight and not (data.imageRightNone and imageRight == 'none') then
 
     if imageRight and not (data.imageRightNone and imageRight == 'none') then
 
         if not isSmall and data.imageCellDiv then
 
         if not isSmall and data.imageCellDiv then

Revision as of 09:14, 23 September 2013

Documentation for this module may be created at Module:Message box/doc

-- This is a meta-module for producing message box templates, including {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.

local htmlBuilder = require('Module:HtmlBuilder')
local nsDetect = require('Module:Namespace detect')
local yesno = require('Module:Yesno')

local p = {}

local function getTitleObject(page)
    if type(page) == 'string' then
        -- Get the title object, passing the function through pcall 
        -- in case we are over the expensive function count limit.
        local success
        success, page = pcall(mw.title.new, page)
        if not success then
            page = nil
        end
    end
    return page
end

local function presentButBlank(s)
    if type(s) ~= 'string' then return end
    if s and not mw.ustring.find(s, '%S') then
        return true
    else
        return false
    end
end

function p.build(data, args)
    -- Get the title object and the namespace.
    local title = mw.title.getCurrentTitle()
    local nsid = title.namespace

    -- Get a language object for formatDate.
    local lang = mw.language.getContentLanguage()
    
-- Commenting this out for now - this will require tinkering with Namespace detect to differentiate between
-- invalid titles and pages where the expensive parser function count has been exceeded.
--[[
    local title = nsDetect.getPageObject(args.page)
    local namespace = nsDetect.main{
        page = args.page,
        demospace = args.demospace,
        main = 'main',
        talk = 'talk',
        file = 'file',
        category = 'category',
        other = 'other'
    }
]]

    ------------------------ Process config data ----------------------------

    -- Type data.
    local typeData = data.types[args.type]
    local invalidType = args.type and not typeData and true or false
    typeData = typeData or data.types[data.default]

    -- Process data for collapsible text fields
    local name, issue, talk, fix, date, info
    if data.useCollapsibleTextFields then
        name = args.name
        local nameTitle = getTitleObject(name)
        local isTemplatePage = nameTitle and title.prefixedText == ('Template:' .. nameTitle.text) and true or false
        local sect = args.sect
        if presentButBlank(sect) then
            sect = 'This article '
        elseif type(sect) == 'string' then
            sect = 'This ' .. sect .. ' '
        end
        issue = (sect or '') .. (args.issue or '') .. ' ' .. (args.text or '')
        talk = args.talk
        if presentButBlank(talk) and isTemplatePage then
            talk = '#'
        end
        fix = args.fix
        date = args.date
        if presentButBlank(date) and isTemplatePage then
            date = lang:formatDate('F Y')
        end
        info = args.info
    end

    -- Process the talk link, if present.
    if talk then
        -- See if the talk link exists and is for a talk or a content namespace.
        local talkTitle = type(talk) == 'string' and getTitleObject(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.
            local success
            success, talkTitle = pcall(title.talkPageTitle, title)
            if not 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 = mw.ustring.format('%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText)
            else
                talkText = mw.ustring.format('%s the [[%s#%s|talk page]].', talkText, talkTitle.prefixedText, talk)
            end
            talk = talkText
        end
    end

    -- Find whether we are using a small message box and process our data accordingly.
    local isSmall = data.allowSmall and (args.small == 'yes' or args.small == true) and true or false
    local smallClass, image, imageRight, text, imageSize
    if isSmall then
        smallClass = data.smallClass or 'mbox-small'
        image = args.smallimage or args.image
        imageRight = args.smallimageright or args.imageright
        if data.useCollapsibleTextFields then
            text = args.smalltext or issue
        else
            text = args.smalltext or args.text
        end
        imageSize = data.imageSmallSize or '30x30px'
    else
        image = args.image
        imageRight = args.imageright
        imageSize = '40x40px'
        text = args.text
    end

    ------------------------ Build the box ----------------------------
    
    local root = htmlBuilder.create()

    -- Do the subst check.
    if data.substCheck and args.subst == 'SUBST' then
        if type(args.name) == 'string' then
            root
                .tag('b')
                    .addClass('error')
                    .wikitext(mw.ustring.format(
                        'Template <code>%s%s%s</code> has been incorrectly substituted.',
                        mw.text.nowiki('{{'),
                        args.name,
                        mw.text.nowiki('}}')
                    ))
        end
        root.wikitext('[[Category:Pages with incorrectly substituted templates]]')
    end

    -- Build the box.
    local box = root.tag('table')
    box
        .attr('id', args.id)
    for i, class in ipairs(data.classes) do
        box
            .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)
        .cssText(args.style)
        .attr('role', 'presentation')

    -- Add the left-hand image.
    local row = box.tag('tr')
    local imageLeftCell = row.tag('td').addClass('mbox-image')
    local imageCheckBlank = data.imageCheckBlank
    if image ~= 'none' and not imageCheckBlank or image ~= 'none' and imageCheckBlank and image ~= 'blank' then
        if not isSmall and data.imageCellDiv then
            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 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.
            .cssText(data.imageEmptyCellStyle and 'border:none;padding:0px;width:1px')
    end

    -- Add the text.
    local textCell = row.tag('td').addClass('mbox-text')
    if data.useCollapsibleTextFields then
        textCell
            .cssText(args.textstyle)
        local textCellSpan = textCell.tag('span')
        textCellSpan
            .addClass('mbox-text-span')
            .wikitext(issue)
        if not isSmall then
            textCellSpan
                .tag('span')
                    .addClass('hide-when-compact')
                    .wikitext(talk)
                    .wikitext(' ')
                    .wikitext(fix)
                    .done()
        end
        textCellSpan
            .wikitext(date and mw.ustring.format(" <small>''(%s)''</small>", date))
        if not isSmall then
            textCellSpan
                .tag('span')
                    .addClass('hide-when-compact')
                    .wikitext(info and ' ' .. info)
        end
    else
        textCell
            .cssText(args.textstyle)
            .wikitext(text)
    end

    -- Add the right-hand image.
    local imageRightCell = row.tag('td').addClass('mbox-imageright')
    if imageRight and not (data.imageRightNone and imageRight == 'none') then
        if not isSmall and data.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(imageRight)
    end

    -- Add the below row.
    if data.below and args.below then
        box.tag('tr')
            .tag('td')
                .attr('colspan', args.imageright and '3' or '2')
                .addClass('mbox-text')
                .cssText(args.textstyle)
                .wikitext(args.below)
    end

    ------------------------ Add error messages and categories ----------------------------

    -- Add error message and tracking category for invalid type parameters.
    if invalidType then
        local catsort = (nsid == 0 and 'Main:' or '') .. title.prefixedText
        root
            .tag('div')
                .css('text-align', 'center')
                .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

    -- Categorise template pages.
    if data.category and nsid == 10 and not title.isSubpage and not yesno(args.nocat) then
            root.wikitext(mw.ustring.format('[[Category:%s]]', data.category))
    end
    return tostring(root)
end

function p._ambox(args)
    local data = {}
    data.types = {
        speedy = {
            class = 'ambox-speedy',
            image = 'Ambox speedy deletion.png'
        },
        delete = {
            class = 'ambox-delete',
            image = 'Ambox deletion.png'
        },
        content = {
            class = 'ambox-content',
            image = 'Ambox content.png'
        },
        style = {
            class = 'ambox-style',
            image = 'Edit-clear.svg'
        },
        move = {
            class = 'ambox-move',
            image = 'Ambox move.png'
        },
        protection = {
            class = 'ambox-protection',
            image = 'Ambox protection.png'
        },
        notice = {
            class = 'ambox-notice',
            image = 'Ambox notice.png'
        }
    }
    data.default = 'notice'
    data.allowSmall = true
    data.substCheck = true
    data.classes = {'metadata', 'plainlinks', 'ambox'}
    data.smallClass = 'mbox-small-left'
    data.imageEmptyCell = true
    data.imageCheckBlank = true
    data.imageSmallSize = '20x20px'
    data.imageCellDiv = true
    data.useCollapsibleTextFields = true
    data.imageRightNone = true
    return p.build(data, args)
end

function p._fmbox(args)
    local data = {}
    data.types = {
        warning = {
            class = 'fmbox-warning',
            image = 'Cmbox deletion.png'
        },
        editnotice = {
            class = 'fmbox-editnotice',
            image = 'Imbox notice.png'
        },
        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

function p._ombox(args)
    local data = {}
    data.types = {
        speedy = {
            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.allowSmall = true
    data.imageEmptyCell = true
    data.imageRightNone = true
    return p.build(data, args)
end

function p._imbox(args)
    local data = {}
    data.types = {
        speedy = {
            class = 'imbox-speedy',
            image = 'Imbox speedy deletion.png'
        },
        delete = {
            class = 'imbox-delete',
            image = 'Imbox deletion.png'
        },
        content = {
            class = 'imbox-content',
            image = 'Imbox content.png'
        },
        style = {
            class = 'imbox-style',
            image = 'Edit-clear.svg'
        },
        move = {
            class = 'imbox-move',
            image = 'Imbox move.png'
        },
        protection = {
            class = 'imbox-protection',
            image = 'Imbox protection.png'
        },
        license = {
            class = 'imbox-license',
            image = 'Imbox license.png'
        },
        featured = {
            class = 'imbox-featured',
            image = 'Imbox featured.png'
        },
        notice = {
            class = 'imbox-notice',
            image = 'Imbox notice.png'
        }
    }
    data.default = 'notice'
    data.classes = {'imbox'}
    data.classPlainlinksYesno = true
    data.imageEmptyCell = true
    data.below = true
    return p.build(data, args)
end

function p._cmbox(args)
    local data = {}
    data.types = {
        speedy = {
            class = 'cmbox-speedy',
            image = 'Cmbox deletion.png'
        },
        delete = {
            class = 'cmbox-delete',
            image = 'Cmbox deletion.png'
        },
        content = {
            class = 'cmbox-content',
            image = 'Cmbox content.png'
        },
        style = {
            class = 'cmbox-style',
            image = 'Edit-clear.svg'
        },
        move = {
            class = 'cmbox-move',
            image = 'Cmbox move.png'
        },
        protection = {
            class = 'cmbox-protection',
            image = 'Cmbox protection.png'
        },
        notice = {
            class = 'cmbox-notice',
            image = 'Cmbox notice.png'
        }
    }
    data.default = 'notice'
    data.classes = {'plainlinks', 'cmbox'}
    return p.build(data, args)
end

function p._tmbox(args)
    local data = {}
    data.types = {
        speedy = {
            class = 'tmbox-speedy',
            image = 'Imbox speedy deletion.png'
        },
        delete = {
            class = 'tmbox-delete',
            image = 'Imbox deletion.png'
        },
        content = {
            class = 'tmbox-content',
            image = 'Imbox content.png'
        },
        style = {
            class = 'tmbox-style',
            image = 'Edit-clear.svg '
        },
        move = {
            class = 'tmbox-move',
            image = 'Imbox move.png'
        },
        protection = {
            class = 'tmbox-protection',
            image = 'Imbox protection.png'
        },
        notice = {
            class = 'tmbox-notice',
            image = 'Imbox notice.png'
        }
    }
    data.default = 'notice'
    data.classes = {'plainlinks', 'tmbox'}
    data.allowSmall = true
    data.imageRightNone = true
    data.imageEmptyCellStyle = true
    data.category = 'Talk message boxes'
    return p.build(data, args)
end

local function makeWrapper(func)
    return function (frame)
        -- If called via #invoke, use the args passed into the invoking
        -- template, or the args passed to #invoke if any exist. Otherwise
        -- assume args are being passed directly in from the debug console
        -- or from another Lua module.
        local origArgs
        if frame == mw.getCurrentFrame() then
            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 ~= '' or k == 'talk' or k == 'sect' or k == 'date' then
                args[k] = v
            end
        end
        return func(args)
    end
end

p.ambox = makeWrapper(p._ambox)
p.fmbox = makeWrapper(p._fmbox)
p.imbox = makeWrapper(p._imbox)
p.ombox = makeWrapper(p._ombox)
p.cmbox = makeWrapper(p._cmbox)
p.tmbox = makeWrapper(p._tmbox)

return p