Module:Userbox
| This Lua module is used on approximately 347,000 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. |
| This module depends on the following other modules: |
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. |
| |||
| {{userbox-2}} | Makes userboxes with an id on both the left- and right-hand sides. |
| |||
| {{userbox-r}} | Makes userboxes with an id on the right-hand side. |
|
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
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('wikipediauserbox')
-- 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
local title = mw.title.getCurrentTitle()
if (title.namespace == 2) and not title.text:match("/") then
return templateStyles .. tostring(root) -- regular user page
elseif title.namespace == 14 then
return templateStyles .. tostring(root) -- category
elseif title.isTalkPage then
return templateStyles .. tostring(root) -- talk page
end
-- Color contrast checking (simplified for TemplateStyles)
local legible = true
local contrast = require('Module:Color contrast')._ratio
local function has_text(wikitext)
if not wikitext then return false end
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 data.infoColor and data.backgroundColor and 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 data.idColor and data.idBackgroundColor 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 data.id2Color and data.id2BackgroundColor 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 templateStyles .. 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
return categoryHandler(chargs)
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.