Module:Message box: Difference between revisions

    From Nonbinary Wiki
    m>Mr. Stradivarius
    (add cmbox)
    m>Mr. Stradivarius
    (add tmbox)
    Line 2: Line 2:


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


    local p = {}
    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 or mw.title.getCurrentTitle()
    end


    local function generateBoxStructure()
    local function generateBoxStructure()
    Line 14: Line 28:


    function p.build(data, args)
    function p.build(data, args)
        -- Get the title object and the namespace.
        local title = mw.title.getCurrentTitle()
        local nsid = title.namespace
       
    -- 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.
         -- Process config data.
         local typeData = data.types[args.type]
         local typeData = data.types[args.type]
    Line 19: Line 52:
         typeData = typeData or data.types[data.default]
         typeData = typeData or data.types[data.default]


         local isSmall = (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 image, imageRight, text, imageSize
         local image, imageRight, text, imageSize
         if isSmall then
         if isSmall then
    Line 25: Line 58:
             imageRight = args.smallimageright or args.imageright
             imageRight = args.smallimageright or args.imageright
             text = args.smalltext or args.text
             text = args.smalltext or args.text
             imageSize = data.imageSizeSmall or data.imageSize or '40x40px'
             imageSize = '30x30px'
         else
         else
             image = args.image
             image = args.image
             imageRight = args.imageright
             imageRight = args.imageright
             text = args.text
             text = args.text
             imageSize = data.imageSizeLarge or data.imageSize or '40x40px'
             imageSize = '40x40px'
         end
         end


    Line 59: Line 92:
             row.tag('td')
             row.tag('td')
                 .addClass('mbox-empty-cell') -- No image. Cell with some width or padding necessary for text cell to have 100% width.
                 .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
         end


    Line 84: Line 118:
         end
         end


         -- Add error messages and categories.
         -- Add error messages and tracking categories.
         if invalidType then
         if invalidType then
            local title = mw.title.getCurrentTitle()
             local catsort = (nsid == 0 and 'Main:' or '') .. title.prefixedText
             local catsort = (title.namespace == 0 and 'Main:' or '') .. title.prefixedText
             root
             root.tag('div')
                .tag('div')
                .css('text-align', 'center')
                    .css('text-align', 'center')
                .wikitext(mw.ustring.format('This message box is using an invalid "type=%s" parameter and needs fixing.', args.type or ''))
                    .wikitext(mw.ustring.format('This message box is using an invalid "type=%s" parameter and needs fixing.', args.type or ''))
                .done()
                    .done()
            .wikitext(mw.ustring.format('[[Category:Wikipedia message box parameter needs fixing|%s]]', catsort))
                .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
         end
         return tostring(root)
         return tostring(root)
    Line 154: Line 193:
         data.default = 'notice'
         data.default = 'notice'
         data.classes = {'plainlinks', 'ombox'}
         data.classes = {'plainlinks', 'ombox'}
         data.imageSizeLarge = '40x40px'
         data.allowSmall = true
        data.imageSizeSmall = '30x30px'
         data.imageEmptyCell = true
         data.imageEmptyCell = true
         data.imageRightNone = true
         data.imageRightNone = true
    Line 243: Line 281:
         data.default = 'notice'
         data.default = 'notice'
         data.classes = {'plainlinks', 'cmbox'}
         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)
         return p.build(data, args)
    end
    end
    Line 280: Line 359:
    p.ombox = makeWrapper(p._ombox)
    p.ombox = makeWrapper(p._ombox)
    p.cmbox = makeWrapper(p._cmbox)
    p.cmbox = makeWrapper(p._cmbox)
    p.tmbox = makeWrapper(p._tmbox)


    return p
    return p

    Revision as of 10:39, 21 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 or mw.title.getCurrentTitle()
    end
    
    local function generateBoxStructure()
        local root = htmlBuilder.create() -- Includes error messages and categories added after the box.
        local box = root.tag('table')
        local row = box.tag('tr')
        return root, box, row
    end
    
    function p.build(data, args)
        -- Get the title object and the namespace.
        local title = mw.title.getCurrentTitle()
        local nsid = title.namespace
        
    -- 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.
        local typeData = data.types[args.type]
        local invalidType = args.type and not typeData and true or false
        typeData = typeData or data.types[data.default]
    
        local isSmall = data.allowSmall and (args.small == 'yes' or args.small == true) and true or false
        local image, imageRight, text, imageSize
        if isSmall then
            image = args.smallimage or args.image
            imageRight = args.smallimageright or args.imageright
            text = args.smalltext or args.text
            imageSize = '30x30px'
        else
            image = args.image
            imageRight = args.imageright
            text = args.text
            imageSize = '40x40px'
        end
    
        -- Get the box structure.
        local root, box, row = generateBoxStructure()
    
        -- Build the box.
        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')
    
        -- Add the left-hand image.
        if image ~= 'none' then
            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.
                .cssText(data.imageEmptyCellStyle and 'border:none;padding:0px;width:1px')
        end
    
        -- Add the text.
        row.tag('td')
            .addClass('mbox-text')
            .cssText(args.textstyle)
            .wikitext(text)
    
        -- Add the right-hand image.
        if imageRight and not (data.imageRightNone and imageRight == 'none') then
            row.tag('td')
                .addClass('mbox-imageright')
                .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 tracking categories.
        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._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 ~= '' then
                    args[k] = v
                end
            end
            return func(args)
        end
    end
    
    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