Module:Staff list

From MyFallen Gaming Community
Jump to navigation Jump to search

Documentation for this module may be created at Module:Staff list/doc

--
-- This module implements {{Staff page}}
--

local p = {}
local navbar = require('Module:Navbar')._navbar

local args = {}
local origArgs
local root

local function notempty( s ) return s and s:match( '%S' ) end

local function fixChildBoxes(sval, tt)
	if notempty(sval) then
		local marker = '<span class=special_infobox_marker>'
		local s = sval
		s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1')
		s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker)
		if s:match(marker) then
			s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '')
			s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1')
			s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1')
			s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1')
			s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1')
			s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
			s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
			s = mw.ustring.gsub(s,  marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1')
			s = mw.ustring.gsub(s,  marker .. '(%s*\n|%})', '%1')
		end
		if s:match(marker) then
			local subcells = mw.text.split(s, marker)
			s = ''
			for k = 1, #subcells do
				if k == 1 then
					s = s .. subcells[k] .. '</' .. tt .. '></tr>'
				elseif k == #subcells then
					local rowstyle = ' style="display:none"'
					if notempty(subcells[k]) then rowstyle = ''	end
					s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' .. subcells[k]
				elseif notempty(subcells[k]) then
					if (k % 2) == 0 then
						s = s .. subcells[k]
					else
						s = s .. '<tr><' .. tt .. ' colspan=2>\n' .. subcells[k] .. '</' .. tt .. '></tr>'
					end
				end
			end
		end
		-- the next two lines add a newline at the end of lists for the PHP parser
		-- https://en.wikipedia.org/w/index.php?title=Template_talk:Infobox_musical_artist&oldid=849054481
		-- remove when [[:phab:T191516]] is fixed or OBE
		s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n')
		s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n')
		s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1')
		s = mw.ustring.gsub(s, '^(%{%|)', '\n%1')
		return s
	else
		return sval
	end
end

local function union(t1, t2)
    -- Returns the union of the values of two tables, as a sequence.
    local vals = {}
    for k, v in pairs(t1) do
        vals[v] = true
    end
    for k, v in pairs(t2) do
        vals[v] = true
    end
    local ret = {}
    for k, v in pairs(vals) do
        table.insert(ret, k)
    end
    return ret
end

local function renderAboveRow()
    root
        :tag('tr')
            :tag('th')
                :attr('colspan', 2)
                :addClass(args.aboveclass)
                :css('text-align', 'center')
                :css('font-size', '125%')
                :css('font-weight', 'bold')
                :css('color', '#fff')
                :css('background-color', '#8E51CC')
                :wikitext(fixChildBoxes('MyFallen Staff','th'))
end

local function addCommunityManagers(cManagerArgs)
    -- Adds a row to the infobox, with either a header cell
    -- or a label/data cell combination.
        local row = root:tag('tr')
        row:addClass(cManagerArgs.rowclass)
        row:cssText(cManagerArgs.rowstyle)
        row:attr('id', cManagerArgs.rowid)
    
            row
                :tag('th')
                    :attr('scope', 'row')
                    :cssText(cManagerArgs.rowcellstyle)
                    :wikitext(cManagerArgs.label)
                    :done()
        
        local cmanagerCell = row:tag('td')
        cmanagerCell
            :attr('id', cManagerArgs.cmanagerid)
            :addClass(cManagerArgs.class)
            :css('text-align', 'center')
            :wikitext(fixChildBoxes('[[User:Jehosophat MFGC|Jehosophat]]', 'td'))
            :wikitext(fixChildBoxes('<br>', 'td'))
            :wikitext(fixChildBoxes('Queen', 'td'))
            :wikitext(fixChildBoxes('<br>', 'td'))
            :wikitext(fixChildBoxes('Halliburton', 'td'))
            :wikitext(fixChildBoxes('<br>', 'td'))
            :wikitext(fixChildBoxes('[[User:NoMansLand|NoMansLand]]', 'td'))
end

local function addCManagerHeader(cManagerHeaderArgs)
    root
            :tag('tr')
                :addClass(cManagerHeaderArgs.rowclass)
                :cssText(cManagerHeaderArgs.rowstyle)
                :attr('id', cManagerHeaderArgs.rowid)
                :tag('th')
                    :attr('colspan', 2)
                    :attr('id', cManagerHeaderArgs.cmheaderid)
                    :addClass(cManagerHeaderArgs.class)
                    :addClass(args.cmheaderclass)
                    :css('text-align', 'center')
                    :css('background-color', '#00C7FF')
                    :css('color', '#fff')
                    :wikitext(fixChildBoxes('Community Managers', 'th'))
end

local function renderCommunityManagers()
    -- Gets the union of the header and data argument numbers,
    -- and renders them all in order using addCommunityManagers.
        addCManagerHeader({
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            rowid = args['rowid' .. tostring(num)],
            cmheaderid = args['cmheaderid' .. tostring(num)],
            cmheaderclass = args['cmheaderclass' .. tostring(num)]
        })

        addCommunityManagers({
            class = args['class' .. tostring(num)],
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            cmanagerid = args['cmanagerid' .. tostring(num)],
            rowid = args['rowid' .. tostring(num)]
        })
end


local function addSeniorManagers(sManagerArgs)
    -- Adds a row to the infobox, with either a header cell
    -- or a label/data cell combination.
        local row = root:tag('tr')
        row:addClass(sManagerArgs.rowclass)
        row:cssText(sManagerArgs.rowstyle)
        row:attr('id', sManagerArgs.rowid)

            row
                :tag('th')
                    :attr('scope', 'row')
                    :cssText(sManagerArgs.rowcellstyle)
                    :wikitext(sManagerArgs.label)
                    :done()
        
        local smanagerCell = row:tag('td')
        smanagerCell
            :attr('id', sManagerArgs.cmanagerid)
            :addClass(sManagerArgs.class)
            :css('text-align', 'center')
            :wikitext(fixChildBoxes('[[User:Cockatoo|Cockatoo]]', 'td'))
            :wikitext(fixChildBoxes('<br>', 'td'))
            :wikitext(fixChildBoxes('[[User:BryIsntHere|BryIsntHere]]', 'td'))
end

local function addSManagerHeader(sManagerHeaderArgs)
    root
            :tag('tr')
                :addClass(sManagerHeaderArgs.rowclass)
                :cssText(sManagerHeaderArgs.rowstyle)
                :attr('id', sManagerHeaderArgs.rowid)
                :tag('th')
                    :attr('colspan', 2)
                    :attr('id', sManagerHeaderArgs.cmheaderid)
                    :addClass(sManagerHeaderArgs.class)
                    :addClass(args.csheaderclass)
                    :css('text-align', 'center')
                    :css('background-color', '#206694')
                    :css('color', '#fff')
                    :wikitext(fixChildBoxes('Senior Managers', 'th'))
end

local function renderSeniorManagers()
    -- Gets the union of the header and data argument numbers,
    -- and renders them all in order using addSeniorManagers.
        addSManagerHeader({
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            rowid = args['rowid' .. tostring(num)],
            smheaderid = args['smheaderid' .. tostring(num)],
            smheaderclass = args['smheaderclass' .. tostring(num)]
        })

        addSeniorManagers({
            class = args['class' .. tostring(num)],
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            smanagerid = args['smanagerid' .. tostring(num)],
            rowid = args['rowid' .. tostring(num)]
        })
end

local function addModerators(moderatorArgs)
    -- Adds a row to the infobox, with either a header cell
    -- or a label/data cell combination.
        local row = root:tag('tr')
        row:addClass(moderatorArgs.rowclass)
        row:cssText(moderatorArgs.rowstyle)
        row:attr('id', moderatorArgs.rowid)
    
            row
                :tag('th')
                    :attr('scope', 'row')
                    :cssText(moderatorArgs.rowcellstyle)
                    :wikitext(moderatorArgs.label)
                    :done()
        
        local moderatorCell = row:tag('td')
        moderatorCell
            :attr('id', moderatorArgs.cmanagerid)
            :addClass(moderatorArgs.class)
            :css('text-align', 'center')
            :wikitext(fixChildBoxes('[[User:Painteh|Painteh]]', 'td'))
            :wikitext(fixChildBoxes('<br>', 'td'))
            :wikitext(fixChildBoxes('Mythic_Gaming', 'td'))
end

local function addModeratorHeader(moderatorHeaderArgs)
    root
            :tag('tr')
                :addClass(moderatorHeaderArgs.rowclass)
                :cssText(moderatorHeaderArgs.rowstyle)
                :attr('id', moderatorHeaderArgs.rowid)
                :tag('th')
                    :attr('colspan', 2)
                    :attr('id', moderatorHeaderArgs.cmheaderid)
                    :addClass(moderatorHeaderArgs.class)
                    :addClass(args.modheaderclass)
                    :css('text-align', 'center')
                    :css('background-color', '#1F8B4C')
                    :css('color', '#fff')
                    :wikitext(fixChildBoxes('Moderators', 'th'))
end

local function renderModerators()
    -- Gets the union of the header and data argument numbers,
    -- and renders them all in order using addSeniorManagers.
        addModeratorHeader({
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            rowid = args['rowid' .. tostring(num)],
            smheaderid = args['smheaderid' .. tostring(num)],
            smheaderclass = args['smheaderclass' .. tostring(num)]
        })

        addModerators({
            class = args['class' .. tostring(num)],
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            smanagerid = args['smanagerid' .. tostring(num)],
            rowid = args['rowid' .. tostring(num)]
        })
end

local function addRecruits(recruitArgs)
    -- Adds a row to the infobox, with either a header cell
    -- or a label/data cell combination.
        local row = root:tag('tr')
        row:addClass(recruitArgs.rowclass)
        row:cssText(recruitArgs.rowstyle)
        row:attr('id', recruitArgs.rowid)
    
            row
                :tag('th')
                    :attr('scope', 'row')
                    :cssText(recruitArgs.rowcellstyle)
                    :wikitext(recruitArgs.label)
                    :done()
        
        local recruitCell = row:tag('td')
        recruitCell
            :attr('id', recruitArgs.cmanagerid)
            :addClass(recruitArgs.class)
            :css('text-align', 'center')
            :wikitext(fixChildBoxes('[[User:Phobos|Phobos]]', 'td'))
            :wikitext(fixChildBoxes('<br>', 'td'))
            :wikitext(fixChildBoxes('[[User:Bumblebea|Bumblebea]]', 'td'))
end

local function addRecruitHeader(recruitHeaderArgs)
    root
            :tag('tr')
                :addClass(recruitHeaderArgs.rowclass)
                :cssText(recruitHeaderArgs.rowstyle)
                :attr('id', recruitHeaderArgs.rowid)
                :tag('th')
                    :attr('colspan', 2)
                    :attr('id', recruitHeaderArgs.cmheaderid)
                    :addClass(recruitHeaderArgs.class)
                    :addClass(args.recheaderclass)
                    :css('text-align', 'center')
                    :css('background-color', '#E74C3C')
                    :css('color', '#fff')
                    :wikitext(fixChildBoxes('Recruits', 'th'))
end

local function renderRecruits()
    -- Gets the union of the header and data argument numbers,
    -- and renders them all in order using addSeniorManagers.
        addRecruitHeader({
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            rowid = args['rowid' .. tostring(num)],
            recruitid = args['recruitid' .. tostring(num)],
            recruitclass = args['recruitclass' .. tostring(num)]
        })

        addRecruits({
            class = args['class' .. tostring(num)],
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            recruitid = args['recruitid' .. tostring(num)],
            rowid = args['rowid' .. tostring(num)]
        })
end

local function renderNavBar()
    if not args.name then return end
    
    root
        :tag('tr')
            :tag('td')
                :attr('colspan', '2')
                :css('text-align', 'right')
                :wikitext(navbar{
                    args.name,
                    mini = 1,
                })
end

local function renderTrackingCategories()
end
		
local function _infobox()
    -- Specify the overall layout of the infobox, with special settings
    -- if the infobox is used as a 'child' inside another infobox.
    if args.child ~= 'yes' then
        root = mw.html.create('table')
        
        root
            :addClass((args.subbox ~= 'yes') and 'infobox' or nil)
            :addClass(args.bodyclass)
            
            if args.subbox == 'yes' then
                root
                    :css('padding', '0')
                    :css('border', 'none')
                    :css('margin', '-3px')
                    :css('width', 'auto')
                    :css('min-width', '100%')
                    :css('font-size', '100%')
                    :css('clear', 'none')
                    :css('float', 'none')
                    :css('background-color', 'transparent')
            else
                root
                    :css('width', '22em')
            end
        root
            :cssText('background-color', '#F5F5F5')
    
        renderAboveRow()
    else
        root = mw.html.create()
    end

    renderCommunityManagers() 
    renderSeniorManagers() 
    renderModerators() 
    renderRecruits() 
    renderNavBar()
    renderTrackingCategories()
    
    return tostring(root)
end

local function preprocessSingleArg(argName)
    -- If the argument exists and isn't blank, add it to the argument table.
    -- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
    if origArgs[argName] and origArgs[argName] ~= '' then
        args[argName] = origArgs[argName]
    end
end

local function preprocessArgs(prefixTable, step)
    -- Assign the parameters with the given prefixes to the args table, in order, in batches
    -- of the step size specified. This is to prevent references etc. from appearing in the
    -- wrong order. The prefixTable should be an array containing tables, each of which has
    -- two possible fields, a "prefix" string and a "depend" table. The function always parses
    -- parameters containing the "prefix" string, but only parses parameters in the "depend"
    -- table if the prefix parameter is present and non-blank.
    if type(prefixTable) ~= 'table' then
        error("Non-table value detected for the prefix table", 2)
    end
    if type(step) ~= 'number' then
        error("Invalid step value detected", 2)
    end
    
    -- Get arguments without a number suffix, and check for bad input.
    for i,v in ipairs(prefixTable) do
        if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then
            error('Invalid input detected to preprocessArgs prefix table', 2)
        end
        preprocessSingleArg(v.prefix)
        -- Only parse the depend parameter if the prefix parameter is present and not blank.
        if args[v.prefix] and v.depend then
            for j, dependValue in ipairs(v.depend) do
                if type(dependValue) ~= 'string' then
                    error('Invalid "depend" parameter value detected in preprocessArgs')
                end
                preprocessSingleArg(dependValue)
            end
        end
    end

    -- Get arguments with number suffixes.
    local a = 1 -- Counter variable.
    local moreArgumentsExist = true
    while moreArgumentsExist == true do
        moreArgumentsExist = false
        for i = a, a + step - 1 do
            for j,v in ipairs(prefixTable) do
                local prefixArgName = v.prefix .. tostring(i)
                if origArgs[prefixArgName] then
                    moreArgumentsExist = true -- Do another loop if any arguments are found, even blank ones.
                    preprocessSingleArg(prefixArgName)
                end
                -- Process the depend table if the prefix argument is present and not blank, or
                -- we are processing "prefix1" and "prefix" is present and not blank, and
                -- if the depend table is present.
                if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
                    for j,dependValue in ipairs(v.depend) do
                        local dependArgName = dependValue .. tostring(i)
                        preprocessSingleArg(dependArgName)
                    end
                end
            end
        end
        a = a + step
    end
end
 
function p.infobox(frame)
    -- If called via #invoke, use the args passed into the invoking template.
    -- Otherwise, for testing purposes, assume args are being passed directly in.
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end
    
    -- Parse the data parameters in the same order that the old {{infobox}} did, so that
    -- references etc. will display in the expected places. Parameters that depend on
    -- another parameter are only processed if that parameter is present, to avoid
    -- phantom references appearing in article reference lists.
    preprocessSingleArg('child')
    preprocessSingleArg('bodyclass')
    preprocessSingleArg('subbox')
    preprocessSingleArg('bodystyle')
    preprocessSingleArg('above')
    preprocessSingleArg('aboveclass')
    preprocessSingleArg('abovestyle')
    preprocessArgs({
        {prefix = 'image', depend = {'caption', 'imagerowclass'}}
    }, 10)
    preprocessSingleArg('captionstyle')
    preprocessSingleArg('imagestyle')
    preprocessSingleArg('imageclass')
    preprocessArgs({
        {prefix = 'cmheader'},
        {prefix = 'cmanager'},
        {prefix = 'rowclass'},
        {prefix = 'rowstyle'},
        {prefix = 'rowcellstyle'},
        {prefix = 'class'},
        {prefix = 'cmanagerid'},
        {prefix = 'cmheaderid'},
        {prefix = 'rowid'}
    }, 50)
    preprocessSingleArg('cmheaderclass')
    preprocessSingleArg('cmheaderstyle')
    preprocessSingleArg('datastyle')
    preprocessSingleArg('name')
    preprocessSingleArg('decat')
 
    return _infobox()
end
 
return p