Module:Userbox
This Lua module is used on approximately 306,000 pages, or roughly 4437% of all pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
Lua error in Module:Lua_banner at line 112: attempt to index field 'edit' (a nil value).
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. | Template:Userbox |
{{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.
<syntaxhighlight lang="lua"> local userbox = require('Module:Userbox') </syntaxhighlight>
You can then run any of the three templates with the code:
<syntaxhighlight lang="lua"> userbox.main(functionName, args) </syntaxhighlight>
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
- Category:Userboxes with insufficient color contrast (0)
- Category:Pages with templates in the wrong namespace (0)
-- 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 = checkNum(args['logo-size'] or args[5] or args['id-s'], 14) 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 = checkNum(args['id1-s'], 14) 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 = checkNum(args['id2-s'], 14) 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 = checkNum(args['logo-size'] or args[5] or args['id-s'], 14) 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 .. 'pt') :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 .. 'pt') :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) wikitext = wikitext:gsub("]]", "|]]") wikitext = wikitext:gsub("%[%[%s*[Mm][Ee][Dd][Ii][Aa]%s*:[^|]-(|.-)]]", "") wikitext = wikitext:gsub("%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:[^|]-(|.-)]]", "") wikitext = wikitext:gsub("%[%[%s*[Ff][Ii][Ll][Ee]%s*:[^|]-(|.-)]]", "") return mw.text.trim(wikitext) ~= "" end if contrast { data.infoColor, data.backgroundColor, error = 0 } < 4.5 then legible = false end -- For bold text >= 14pt, requirement is only 3. local idContrastThreshold = 4.5 local id2ContrastThreshold = 4.5 if (data.idFontSize or 0) >= 14 then idContrastThreshold = 3 end if (data.id2FontSize or 0) >= 14 then id2ContrastThreshold = 3 end if data.showId and contrast { data.idColor, data.idBackgroundColor, error = 0 } < idContrastThreshold then if has_text(data.id or "") then legible = false end end if data.showId2 and contrast { data.id2Color, data.id2BackgroundColor, error = 0 } < id2ContrastThreshold 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