Module:Userbox/sandbox

From Uncyclopedia, the content-free encyclopedia
Jump to navigation Jump to search
-- This module implements {{userbox}}.

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
	local borderWidthNum = checkNum(args['border-width'] or args['border-s'], nil)
	data.borderWidth = addSuffix(borderWidthNum, 'px')
	data.borderColor = args['border-color'] or args['border-c'] or args[1] or args['id-c']
	data.width = borderWidthNum and addSuffix(240 - 2 * borderWidthNum, 'px')
	data.bodyClass = args.bodyclass

	-- Get table tag values.
	data.backgroundColor = args['info-background'] or args[2] or args['info-c']

	-- Get info values.
	data.info = args.info or args[4] or "<code>{{{info}}}</code>"
	data.infoTextAlign = args['info-a']
	data.infoFontSize = checkNumAndAddSuffix(args['info-size'] or args['info-s'], nil, 'pt')
	data.infoHeight = checkNumAndAddSuffix(args['logo-height'] or args['id-h'], nil, 'px')
	data.infoPadding = args['info-padding'] or args['info-p']
	data.infoLineHeight = args['info-line-height'] or args['info-lh']
	data.infoColor = args['info-color'] or args['info-fc']
	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'], nil, 'px')
	data.idHeight = checkNumAndAddSuffix(args['logo-height'] or args['id-h'], nil, 'px')
	data.idBackgroundColor = args['logo-background'] or args[1] or args['id-c']
	data.idTextAlign = args['id-a']
	data.idFontSize = checkNum(args['logo-size'] or args[5] or args['id-s'], nil)
	data.idColor = args['logo-color'] or args['id-fc'] or data.infoColor
	data.idPadding = args['logo-padding'] or args['id-p']
	data.idLineHeight = args['logo-line-height'] or args['id-lh']
	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
	local borderWidthNum = checkNum(args['border-s'] or args[9], nil)
	data.borderWidth = addSuffix(borderWidthNum, 'px')
	data.borderColor = args['border-c'] or args[6] or args['id1-c'] or args[1]
	data.width = borderWidthNum and addSuffix(240 - 2 * borderWidthNum, 'px')
	data.bodyClass = args.bodyclass

	-- Get table tag values.
	data.backgroundColor = args['info-c'] or args[2]

	-- Get info values.
	data.info = args.info or args[4] or "<code>{{{info}}}</code>"
	data.infoTextAlign = args['info-a']
	data.infoFontSize = checkNumAndAddSuffix(args['info-s'], nil, 'pt')
	data.infoColor = args['info-fc'] or args[8]
	data.infoPadding = args['info-p']
	data.infoLineHeight = args['info-lh']
	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'], nil, 'px')
	data.idHeight = checkNumAndAddSuffix(args['id-h'], nil, 'px')
	data.idBackgroundColor = args['id1-c'] or args[1]
	data.idTextAlign = args['id-a']
	data.idFontSize = checkNum(args['id1-s'], nil)
	data.idLineHeight = args['id1-lh']
	data.idColor = args['id1-fc'] or data.infoColor
	data.idPadding = args['id1-p']
	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'], nil, 'px')
	data.id2Height = data.idHeight
	data.id2BackgroundColor = args['id2-c'] or args[7] or args[1]
	data.id2TextAlign = nil -- Always center, but don't set if no content
	data.id2FontSize = checkNum(args['id2-s'], nil)
	data.id2LineHeight = args['id2-lh']
	data.id2Color = args['id2-fc'] or data.infoColor
	data.id2Padding = args['id2-p']
	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
	local borderWidthNum = checkNum(args['border-width'] or args['border-s'], nil)
	data.borderWidth = addSuffix(borderWidthNum, 'px')
	data.borderColor = args['border-color'] or args['border-c'] or args[1] or args['id-c']
	data.width = borderWidthNum and addSuffix(240 - 2 * borderWidthNum, 'px')
	data.bodyClass = args.bodyclass

	-- Get table tag values.
	data.backgroundColor = args['info-background'] or args[2] or args['info-c']

	-- 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']
	data.infoFontSize = checkNumAndAddSuffix(args['info-size'] or args['info-s'], nil, 'pt')
	data.infoPadding = args['info-padding'] or args['info-p']
	data.infoLineHeight = args['info-line-height'] or args['info-lh']
	data.infoColor = args['info-color'] or args['info-fc']
	data.infoOtherParams = args['info-other-param'] or args['info-op']

	-- Get id2 values.
	data.showId2 = true  -- userbox-r always shows the ID cell (as id2)
	data.id2 = args.logo or args[3] or args.id or 'id'
	data.id2Width = checkNumAndAddSuffix(args['logo-width'] or args['id-w'], nil, 'px')
	data.id2Height = checkNumAndAddSuffix(args['logo-height'] or args['id-h'], nil, 'px')
	data.id2BackgroundColor = args['logo-background'] or args[1] or args['id-c']
	data.id2TextAlign = args['id-a']
	data.id2FontSize = checkNum(args['logo-size'] or args[5] or args['id-s'], nil)
	data.id2Color = args['logo-color'] or args['id-fc'] or data.infoColor
	data.id2Padding = args['logo-padding'] or args['id-p']
	data.id2LineHeight = args['logo-line-height'] or args['id-lh']
	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.
	-- Add TemplateStyles
	local templateStyles = mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = 'Template:Userbox/styles.css' }
	}

	-- Render the div tag html.
	local root = mw.html.create('div')
	root:addClass('userbox')

	-- Only add CSS properties if they have values
	if data.float then root:css('float', data.float) end
	if data.borderWidth then 
		root:css('border-width', data.borderWidth)
	end
	if data.borderColor then 
		root:css('border-color', data.borderColor)
		-- Set border style if we have a color but potentially no width set
		if not data.borderWidth then
			root:css('border-width', '1px')  -- default border width
		end
		root:css('border-style', 'solid')
	end
	if data.width then root:css('width', data.width) end
	if data.bodyClass then root:addClass(data.bodyClass) end

	-- Render the table tag html.
	local tableroot = root:tag('table')
	tableroot:attr('role', 'presentation')

	-- Only add CSS if values exist
	if data.width then tableroot:css('width', data.width) end
	if data.backgroundColor then tableroot:css('background', data.backgroundColor):css('color', 'inherit') end

	local tablerow = tableroot:tag('tr')

	-- Create cells based on what should actually be shown
	if data.showId == false then
		-- userbox-r: info cell first, then id2 cell (if showId2 is true)
		local infoCell = tablerow:tag('td')
		infoCell:addClass('userbox-info')
		if data.infoTextAlign then infoCell:css('text-align', data.infoTextAlign) end
		if data.infoFontSize then infoCell:css('font-size', data.infoFontSize) end
		if data.infoPadding then infoCell:css('padding', data.infoPadding) end
		if data.infoHeight then infoCell:css('height', data.infoHeight) end
		if data.infoLineHeight then infoCell:css('line-height', data.infoLineHeight) end
		if data.infoColor then infoCell:css('color', data.infoColor) end
		if data.infoOtherParams then infoCell:cssText(data.infoOtherParams) end
		if data.infoClass then infoCell:addClass(data.infoClass) end
		if data.info then infoCell:wikitext(data.info) end
		
		-- Create id2 cell only if showId2 is true
		if data.showId2 then
			local id2Cell = tablerow:tag('td')
			id2Cell:addClass('userbox-id2')
			if data.id2Width then id2Cell:css('width', data.id2Width) end
			if data.id2Height then id2Cell:css('height', data.id2Height) end
			if data.id2BackgroundColor then id2Cell:css('background', data.id2BackgroundColor) end
			if data.id2TextAlign then id2Cell:css('text-align', data.id2TextAlign) end
			if data.id2FontSize then id2Cell:css('font-size', data.id2FontSize .. 'pt') end
			if data.id2Color then id2Cell:css('color', data.id2Color) else id2Cell:css('color', 'inherit') end
			if data.id2Padding then id2Cell:css('padding', data.id2Padding) end
			if data.id2LineHeight then id2Cell:css('line-height', data.id2LineHeight) end
			if data.id2OtherParams then id2Cell:cssText(data.id2OtherParams) end
			if data.id2 then id2Cell:wikitext(data.id2) end
		end
	else
		-- userbox and userbox-2: create id cell only if showId is true
		if data.showId then
			local idCell = tablerow:tag('td')
			idCell:addClass('userbox-id')
			if data.idWidth then idCell:css('width', data.idWidth) end
			if data.idHeight then idCell:css('height', data.idHeight) end
			if data.idBackgroundColor then idCell:css('background', data.idBackgroundColor) end
			if data.idTextAlign then idCell:css('text-align', data.idTextAlign) end
			if data.idFontSize then idCell:css('font-size', data.idFontSize .. 'pt') end
			if data.idColor then idCell:css('color', data.idColor) else idCell:css('color', 'inherit') end
			if data.idPadding then idCell:css('padding', data.idPadding) end
			if data.idLineHeight then idCell:css('line-height', data.idLineHeight) end
			if data.idOtherParams then idCell:cssText(data.idOtherParams) end
			if data.idClass then idCell:addClass(data.idClass) end
			if data.id then idCell:wikitext(data.id) end
		end
		
		-- Always create info cell for userbox and userbox-2
		local infoCell = tablerow:tag('td')
		infoCell:addClass('userbox-info')
		if data.infoTextAlign then infoCell:css('text-align', data.infoTextAlign) end
		if data.infoFontSize then infoCell:css('font-size', data.infoFontSize) end
		if data.infoPadding then infoCell:css('padding', data.infoPadding) end
		if data.infoHeight then infoCell:css('height', data.infoHeight) end
		if data.infoLineHeight then infoCell:css('line-height', data.infoLineHeight) end
		if data.infoColor then infoCell:css('color', data.infoColor) end
		if data.infoOtherParams then infoCell:cssText(data.infoOtherParams) end
		if data.infoClass then infoCell:addClass(data.infoClass) end
		if data.info then infoCell:wikitext(data.info) end
		
		-- Create id2 cell only for userbox-2 and only if showId2 is true
		if data.showId2 then
			local id2Cell = tablerow:tag('td')
			id2Cell:addClass('userbox-id2')
			if data.id2Width then id2Cell:css('width', data.id2Width) end
			if data.id2Height then id2Cell:css('height', data.id2Height) end
			if data.id2BackgroundColor then id2Cell:css('background', data.id2BackgroundColor) end
			if data.id2TextAlign then id2Cell:css('text-align', data.id2TextAlign) end
			if data.id2FontSize then id2Cell:css('font-size', data.id2FontSize .. 'pt') end
			if data.id2Color then id2Cell:css('color', data.id2Color) else id2Cell:css('color', 'inherit') end
			if data.id2Padding then id2Cell:css('padding', data.id2Padding) end
			if data.id2LineHeight then id2Cell:css('line-height', data.id2LineHeight) end
			if data.id2OtherParams then id2Cell:cssText(data.id2OtherParams) end
			if data.id2 then id2Cell:wikitext(data.id2) end
		end
	end

	return templateStyles .. tostring(root)
end

function p.categories(args)
	-- Simple category handling - supports up to 5 user categories
	-- No namespace filtering or complex category handler logic
	if args.nocat then
		return ''
	end
	
	local cats = ''
	
	-- Add up to 5 user categories
	if args.usercategory then
		cats = cats .. makeCat(args.usercategory)
	end
	if args.usercategory2 then
		cats = cats .. makeCat(args.usercategory2)
	end
	if args.usercategory3 then
		cats = cats .. makeCat(args.usercategory3)
	end
	if args.usercategory4 then
		cats = cats .. makeCat(args.usercategory4)
	end
	if args.usercategory5 then
		cats = cats .. makeCat(args.usercategory5)
	end
	
	return cats
end

return p