×
Create a new article
Write your page title here:
We currently have 230 articles on Farthest Frontier. Type your article name above or create one of the articles listed here!



    Farthest Frontier

    This module does the processing for three userbox templates, {{userbox}}, {{userbox-2}} and {{userbox-r}}.

    Template Description Examples
    {{userbox}} Makes userboxes with an id on the left-hand side, or with no id.
    id{{{info}}}
    {{{info}}}
    {{userbox-2}} Makes userboxes with an id on both the left- and right-hand sides. Template:Userbox-2
    {{userbox-r}} Makes userboxes with an id on the right-hand side. Template:Userbox-r

    To use any of these templates from a wiki page, please see the individual template pages for documentation. To generate userboxes directly from Lua, read on.

    Generating userboxes from Lua

    To generate a userbox directly from Lua, first load the module.

    local userbox = require('Module:Userbox')
    

    You can then run any of the three templates with the code:

    userbox.main(functionName, args)
    

    For {{userbox}} use the function name "_userbox"; for {{userbox-2}} use the function name "_userbox-2"; and for {{userbox-r}} use the function name "_userbox-r". The args parameter is a table of arguments to pass to the different userbox functions. To see a list of valid arguments, please consult the individual template pages.

    Tracking categories


    -- This module implements {{userbox}}.
    
    local categoryHandler = require('Module:Category handler').main
    
    local p = {}
    
    --------------------------------------------------------------------------------
    -- Helper functions
    --------------------------------------------------------------------------------
    
    local function checkNum(val, default)
    	-- Checks whether a value is a number greater than or equal to zero. If so,
    	-- returns it as a number. If not, returns a default value.
    	val = tonumber(val)
    	if val and val >= 0 then
    		return val
    	else
    		return default
    	end
    end
    
    local function addSuffix(num, suffix)
    	-- Turns a number into a string and adds a suffix.
    	if num then
    		return tostring(num) .. suffix
    	else
    		return nil
    	end
    end
    
    local function checkNumAndAddSuffix(num, default, suffix)
    	-- Checks a value with checkNum and adds a suffix.
    	num = checkNum(num, default)
    	return addSuffix(num, suffix)
    end
    
    local function makeCat(cat, sort)
    	-- Makes a category link.
    	if sort then
    		return mw.ustring.format('[[Category:%s|%s]]', cat, sort)
    	else
    		return mw.ustring.format('[[Category:%s]]', cat)
    	end
    end
    
    --------------------------------------------------------------------------------
    -- Argument processing
    --------------------------------------------------------------------------------
    
    local function makeInvokeFunc(funcName)
    	return function (frame)
    		local origArgs = require('Module:Arguments').getArgs(frame)
    		local args = {}
    		for k, v in pairs(origArgs) do
    			args[k] = v
    		end
    		return p.main(funcName, args)
    	end
    end
    
    p.userbox = makeInvokeFunc('_userbox')
    p['userbox-2'] = makeInvokeFunc('_userbox-2')
    p['userbox-r'] = makeInvokeFunc('_userbox-r')
    
    --------------------------------------------------------------------------------
    -- Main functions
    --------------------------------------------------------------------------------
    
    function p.main(funcName, args)
    	local userboxData = p[funcName](args)
    	local userbox = p.render(userboxData)
    	local cats = p.categories(args)
    	return userbox .. (cats or '')
    end
    
    function p._userbox(args)
    	-- Does argument processing for {{userbox}}.
    	local data = {}
    
    	-- Get div tag values.
    	data.float = args.float or 'left'
    	local borderWidthNum = checkNum(args['border-width'] or args['border-s'], 1) -- Used to calculate width.
    	data.borderWidth = addSuffix(borderWidthNum, 'px')
    	data.borderColor = args['border-color'] or args['border-c'] or args[1] or args['id-c'] or '#999'
    	data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
    	data.bodyClass = args.bodyclass
    
    	-- Get table tag values.
    	data.backgroundColor = args['info-background'] or args[2] or args['info-c'] or '#eee'
    
    	-- Get info values.
    	data.info = args.info or args[4] or "<code>{{{info}}}</code>"
    	data.infoTextAlign = args['info-a'] or 'left'
    	data.infoFontSize = checkNumAndAddSuffix(args['info-size'] or args['info-s'], 8, 'pt')
    	data.infoHeight = checkNumAndAddSuffix(args['logo-height'] or args['id-h'], 45, 'px')
    	data.infoPadding = args['info-padding'] or args['info-p'] or '0 4px 0 4px'
    	data.infoLineHeight = args['info-line-height'] or args['info-lh'] or '1.25em'
    	data.infoColor = args['info-color'] or args['info-fc'] or 'black'
    	data.infoOtherParams = args['info-other-param'] or args['info-op']
    	data.infoClass = args['info-class']
    
    	-- Get id values.
    	local id = args.logo or args[3] or args.id
    	data.id = id
    	data.showId = id and true or false
    	data.idWidth = checkNumAndAddSuffix(args['logo-width'] or args['id-w'], 45, 'px')
    	data.idHeight = checkNumAndAddSuffix(args['logo-height'] or args['id-h'], 45, 'px')
    	data.idBackgroundColor = args['logo-background'] or args[1] or args['id-c'] or '#ddd'
    	data.idTextAlign = args['id-a'] or 'center'
    	data.idFontSize = checkNumAndAddSuffix(args['logo-size'] or args[5] or args['id-s'], 14, 'pt')
    	data.idColor = args['logo-color'] or args['id-fc'] or data.infoColor
    	data.idPadding = args['logo-padding'] or args['id-p'] or '0 1px 0 0'
    	data.idLineHeight = args['logo-line-height'] or args['id-lh'] or '1.25em'
    	data.idOtherParams = args['logo-other-param'] or args['id-op']
    	data.idClass = args['id-class']
    
    	return data
    end
    
    p['_userbox-2'] = function (args)
    	-- Does argument processing for {{userbox-2}}.
    	local data = {}
    
    	-- Get div tag values.
    	data.float = args.float or 'left'
    	local borderWidthNum = checkNum(args['border-s'] or args[9], 1) -- Used to calculate width.
    	data.borderWidth = addSuffix(borderWidthNum, 'px')
    	data.borderColor = args['border-c'] or args[6] or args['id1-c'] or args[1] or '#999999'
    	data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
    	data.bodyClass = args.bodyclass
    
    	-- Get table tag values.
    	data.backgroundColor = args['info-c'] or args[2] or '#eeeeee'
    
    	-- Get info values.
    	data.info = args.info or args[4] or "<code>{{{info}}}</code>"
    	data.infoTextAlign = args['info-a'] or 'left'
    	data.infoFontSize = checkNumAndAddSuffix(args['info-s'], 8, 'pt')
    	data.infoColor = args['info-fc'] or args[8] or 'black'
    	data.infoPadding = args['info-p'] or '0 4px 0 4px'
    	data.infoLineHeight = args['info-lh'] or '1.25em'
    	data.infoOtherParams = args['info-op']
    
    	-- Get id values.
    	data.showId = true
    	data.id = args.logo or args[3] or args.id1 or 'id1'
    	data.idWidth = checkNumAndAddSuffix(args['id1-w'], 45, 'px')
    	data.idHeight = checkNumAndAddSuffix(args['id-h'], 45, 'px')
    	data.idBackgroundColor = args['id1-c'] or args[1] or '#dddddd'
    	data.idTextAlign = 'center'
    	data.idFontSize = checkNumAndAddSuffix(args['id1-s'], 14, 'pt')
    	data.idLineHeight = args['id1-lh'] or '1.25em'
    	data.idColor = args['id1-fc'] or data.infoColor
    	data.idPadding = args['id1-p'] or '0 1px 0 0'
    	data.idOtherParams = args['id1-op']
    
    	-- Get id2 values.
    	data.showId2 = true
    	data.id2 = args.logo or args[5] or args.id2 or 'id2'
    	data.id2Width = checkNumAndAddSuffix(args['id2-w'], 45, 'px')
    	data.id2Height = data.idHeight
    	data.id2BackgroundColor = args['id2-c'] or args[7] or args[1] or '#dddddd'
    	data.id2TextAlign = 'center'
    	data.id2FontSize = checkNumAndAddSuffix(args['id2-s'], 14, 'pt')
    	data.id2LineHeight = args['id2-lh'] or '1.25em'
    	data.id2Color = args['id2-fc'] or data.infoColor
    	data.id2Padding = args['id2-p'] or '0 0 0 1px'
    	data.id2OtherParams = args['id2-op']
    
    	return data
    end
    
    p['_userbox-r'] = function (args)
    	-- Does argument processing for {{userbox-r}}.
    	local data = {}
    
    	-- Get div tag values.
    	data.float = args.float or 'left'
    	local borderWidthNum = checkNum(args['border-width'] or args['border-s'], 1) -- Used to calculate width.
    	data.borderWidth = addSuffix(borderWidthNum, 'px')
    	data.borderColor = args['border-color'] or args['border-c'] or args[1] or args['id-c'] or '#999'
    	data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
    	data.bodyClass = args.bodyclass
    	
    	-- Get table tag values.
    	data.backgroundColor = args['info-background'] or args[2] or args['info-c'] or '#eee'
    
    	-- Get id values.
    	data.showId = false -- We only show id2 in userbox-r.
    
    	-- Get info values.
    	data.info = args.info or args[4] or "<code>{{{info}}}</code>"
    	data.infoTextAlign = args['info-align'] or args['info-a'] or 'left'
    	data.infoFontSize = checkNumAndAddSuffix(args['info-size'] or args['info-s'], 8, 'pt')
    	data.infoPadding = args['info-padding'] or args['info-p'] or '0 4px 0 4px'
    	data.infoLineHeight = args['info-line-height'] or args['info-lh'] or '1.25em'
    	data.infoColor = args['info-color'] or args['info-fc'] or 'black'
    	data.infoOtherParams = args['info-other-param'] or args['info-op']
    	
    	-- Get id2 values.
    	data.showId2 = true
    	data.id2 = args.logo or args[3] or args.id or 'id'
    	data.id2Width = checkNumAndAddSuffix(args['logo-width'] or args['id-w'], 45, 'px')
    	data.id2Height = checkNumAndAddSuffix(args['logo-height'] or args['id-h'], 45, 'px')
    	data.id2BackgroundColor = args['logo-background'] or args[1] or args['id-c'] or '#ddd'
    	data.id2TextAlign = args['id-a'] or 'center'
    	data.id2FontSize = checkNumAndAddSuffix(args['logo-size'] or args[5] or args['id-s'], 14, 'pt')
    	data.id2Color = args['logo-color'] or args['id-fc'] or data.infoColor
    	data.id2Padding = args['logo-padding'] or args['id-p'] or '0 0 0 1px'
    	data.id2LineHeight = args['logo-line-height'] or args['id-lh'] or '1.25em'
    	data.id2OtherParams = args['logo-other-param'] or args['id-op']
    
    	return data
    end
    
    function p.render(data)
    	-- Renders the userbox html using the content of the data table. 
    	-- Render the div tag html.
    	local root = mw.html.create('div')
    	root
    		:css('float', data.float)
    		:css('border', (data.borderWidth or '') .. ' solid ' .. (data.borderColor or ''))
    		:css('margin', '1px')
    		:css('width', data.width)
    		:addClass('wikipediauserbox')
    		:addClass(data.bodyClass)
    
    	-- Render the table tag html.
    	local tableroot = root:tag('table')
    	tableroot
    		:attr('role', 'presentation')
    		:css('border-collapse', 'collapse')
    		:css('width', data.width)
    		:css('margin-bottom', '0')
    		:css('margin-top', '0')
    		:css('background', data.backgroundColor)
    	
    	-- Render the id html.
    	local tablerow = tableroot:tag('tr')
    	if data.showId then
    		tablerow:tag('td')
    			:css('border', '0')
    			:css('width', data.idWidth)
    			:css('height', data.idHeight)
    			:css('background', data.idBackgroundColor)
    			:css('text-align', data.idTextAlign)
    			:css('font-size', data.idFontSize)
    			:css('font-weight', 'bold')
    			:css('color', data.idColor)
    			:css('padding', data.idPadding)
    			:css('line-height', data.idLineHeight)
    			:css('vertical-align', 'middle')
    			:cssText(data.idOtherParams)
    			:addClass(data.idClass)
    			:wikitext(data.id)
    	end
    
    	-- Render the info html.
    	tablerow:tag('td')
    		:css('border', '0')
    		:css('text-align', data.infoTextAlign)
    		:css('font-size', data.infoFontSize)
    		:css('padding', data.infoPadding)
    		:css('height', data.infoHeight)
    		:css('line-height', data.infoLineHeight)
    		:css('color', data.infoColor)
    		:css('vertical-align', 'middle')
    		:cssText(data.infoOtherParams)
    		:addClass(data.infoClass)
    		:wikitext(data.info)
    	
    	-- Render the second id html.
    	if data.showId2 then
    		tablerow:tag('td')
    			:css('border', '0')
    			:css('width', data.id2Width)
    			:css('height', data.id2Height)
    			:css('background', data.id2BackgroundColor)
    			:css('text-align', data.id2TextAlign)
    			:css('font-size', data.id2FontSize)
    			:css('font-weight', 'bold')
    			:css('color', data.id2Color)
    			:css('padding', data.id2Padding)
    			:css('line-height', data.id2LineHeight)
    			:css('vertical-align', 'middle')
    			:cssText(data.id2OtherParams)
    			:wikitext(data.id2)
    	end
    
    	local title = mw.title.getCurrentTitle()
    	if (title.namespace == 2) and not title.text:match("/") then
    		return tostring(root) -- regular user page
    	elseif title.namespace == 14 then
    		return tostring(root) -- category
    	elseif title.isTalkPage then
    		return tostring(root) -- talk page
    	end
    
    	local legible = true
    	local contrast = require('Module:Color contrast')._ratio
    
    	local function has_text(wikitext)
    		local function get_alt(text)
    			return text:match("|alt=([^|]*)") or ""
    		end
    	
    		wikitext = wikitext:gsub("]]", "|]]")
    		wikitext = wikitext:gsub("%[%[%s*[Mm][Ee][Dd][Ii][Aa]%s*:[^|]-(|.-)]]", get_alt)
    		wikitext = wikitext:gsub("%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:[^|]-(|.-)]]", get_alt)
    		wikitext = wikitext:gsub("%[%[%s*[Ff][Ii][Ll][Ee]%s*:[^|]-(|.-)]]", get_alt)
    		return mw.text.trim(wikitext) ~= ""
    	end
    
    	if contrast { data.infoColor, data.backgroundColor, error = 0 } < 4.5 then
    		legible = false
    	end
    
    	if data.showId and contrast { data.idColor, data.idBackgroundColor, error = 0 } < 4.5 then
    		if has_text(data.id or "") then
    			legible = false
    		end
    	end
    
    	if data.showId2 and contrast { data.id2Color, data.id2BackgroundColor, error = 0 } < 4.5 then
    		if has_text(data.id2 or "") then
    			legible = false
    		end
    	end
    
    	if not legible then
    		root:wikitext('[[Category:Userboxes with insufficient color contrast]]')
    	end
    
    	return tostring(root)
    end
    
    function p.categories(args, page)
    	-- Gets categories from [[Module:Category handler]].
    	-- The page parameter makes the function act as though the module was being called from that page.
    	-- It is included for testing purposes.
    	local cats = {}
    	cats[#cats + 1] = args.usercategory
    	cats[#cats + 1] = args.usercategory2
    	cats[#cats + 1] = args.usercategory3
    	cats[#cats + 1] = args.usercategory4
    	cats[#cats + 1] = args.usercategory5
    	-- Get the title object
    	local title
    	if page then
    		title = mw.title.new(page)
    	else
    		title = mw.title.getCurrentTitle()
    	end
    	-- Build category handler arguments.
    	local chargs = {}
    	chargs.page = page
    	chargs.nocat = args.nocat
    	chargs.main = '[[Category:Pages with templates in the wrong namespace]]'
    	if args.notcatsubpages then
    		chargs.subpage = 'no'
    	end
    	-- User namespace.
    	local user = ''
    	for i, cat in ipairs(cats) do
    		user = user .. makeCat(cat)
    	end
    	chargs.user = user
    	-- Template namespace.
    	local basepage = title.baseText
    	local template = ''
    	for i, cat in ipairs(cats) do
    		template = template .. makeCat(cat, ' ' .. basepage)
    	end
    	chargs.template = template
    	return categoryHandler(chargs)
    end
    
    return p
    
    Cookies help us deliver our services. By using our services, you agree to our use of cookies.
    Cookies help us deliver our services. By using our services, you agree to our use of cookies.