Module:Userbox/sandbox
Appearance
From Meta, a Wikimedia project coordination wiki
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing.
Implements {{Userbox}}
, {{Userbox-r}}
, and {{Userbox-2}}
.
Usage
[edit ]- See Module:Userbox/doc .
The above documentation is transcluded from Module:Userbox/doc. (edit | history)
Editors can experiment in this module’s sandbox (edit | diff) and testcases (create) pages.
Please add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module’s sandbox (edit | diff) and testcases (create) pages.
Please add categories to the /doc subpage. Subpages of this module.
-- This module implements {{userbox}}. local yesno = require('Module:Yesno') 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 local function initTemplateStyles(data, args) local additionalTStyles = args.templateStyles local additionalTStylesTable = {} if additionalTStyles then for s in mw.text.gsplit(additionalTStyles, '|', true) do s = mw.text.trim(s) if #s > 0 then additionalTStylesTable[#additionalTStylesTable + 1] = s end end end data.extraTStyles = additionalTStylesTable 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 = {} initTemplateStyles(data, args) -- Get div tag values. data.float = args.float local borderWidthNum = checkNum(args['border-width'] or args['border-s']) -- Used to calculate width. data.borderWidth = addSuffix(borderWidthNum, 'px') data.borderColor = args['border-color'] or args[1] or args['border-c'] or args['id-c'] data.width = borderWidthNum and 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'] -- Get info values. data.info = args.info or args[4] or "{{{info}}}" 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 = checkNumAndAddSuffix(args['logo-size'] or args[5] or args['id-s'], nil, 'pt') data.idColor = args['logo-color'] or args['id-fc'] 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 = {} initTemplateStyles(data, args) -- Get div tag values. data.float = args.float local borderWidthNum = checkNum(args[9] or args['border-s']) -- Used to calculate width. data.borderWidth = addSuffix(borderWidthNum, 'px') data.borderColor = args[1] or args['border-c'] or args['id1-c'] data.width = borderWidthNum and addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag. data.bodyClass = args.bodyclass -- Get table tag values. data.backgroundColor = args[2] or args['info-c'] -- Get info values. data.info = args[4] or args.info or "{{{info}}}" data.infoTextAlign = args['info-a'] data.infoFontSize = checkNumAndAddSuffix(args['info-s'], nil, 'pt') data.infoColor = args[8] or args['info-fc'] 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[1] or args['id1-c'] data.idFontSize = checkNumAndAddSuffix(args['id1-s'], nil, 'pt') data.idLineHeight = args['id1-lh'] data.idColor = args['id1-fc'] 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[7] or args['id2-c'] or args[1] data.id2FontSize = checkNumAndAddSuffix(args['id2-s'], nil, 'pt') data.id2LineHeight = args['id2-lh'] data.id2Color = args['id2-fc'] 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 = {} initTemplateStyles(data, args) -- Get div tag values. data.float = args.float local borderWidthNum = checkNum(args['border-width'] or args['border-s']) -- Used to calculate width. data.borderWidth = addSuffix(borderWidthNum, 'px') data.borderColor = args['border-color'] or args[1] or args['border-c'] or args['id-c'] data.width = borderWidthNum and 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'] -- Get id values. data.showId = false -- We only show id2 in userbox-r. -- Get info values. data.info = args.info or args[4] or "{{{info}}}" 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 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 = checkNumAndAddSuffix(args['logo-size'] or args[5] or args['id-s'], nil, 'pt') data.id2Color = args['logo-color'] or args['id-fc'] 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. -- Render the div tag html. local root = mw.html.create('div') local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = 'Module:Userbox/styles.css' }, }) for i, v in ipairs(data.extraTStyles) do root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = v }, }) end root :addClass('userbox') :addClass(data.bodyClass) :css('float', data.float) :css('border-color', data.borderColor) :css('border-width', data.borderWidth) :css('line-height', data.infoLineHeight) :css('color', data.infoColor) :css('width', data.width) -- Render the table tag html. local tableroot = root:tag('table') :css('background', data.backgroundColor) -- Render the id html. local tablerow = tableroot:tag('tr') if data.showId then tablerow:tag('th') :addClass('id id-left') :addClass(data.idClass) :css('width', data.idWidth) :css('height', data.idHeight) :css('background', data.idBackgroundColor) :css('text-align', data.idTextAlign) :css('font-size', data.idFontSize) :css('color', data.idColor) :css('padding', data.idPadding) :css('line-height', data.idLineHeight) :cssText(data.idOtherParams) :wikitext(data.id) end -- Render the info html. tablerow:tag('td') :addClass('info') :addClass(data.infoClass) :css('text-align', data.infoTextAlign) :css('font-size', data.infoFontSize) :css('padding', data.infoPadding) :css('height', data.infoHeight) :cssText(data.infoOtherParams) :wikitext(data.info) -- Render the second id html. if data.showId2 then tablerow:tag('th') :addClass('id id-right') :css('width', data.id2Width) :css('height', data.id2Height) :css('background', data.id2BackgroundColor) :css('text-align', data.id2TextAlign) :css('font-size', data.id2FontSize) :css('color', data.id2Color) :css('padding', data.id2Padding) :css('line-height', data.id2LineHeight) :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 check_constrast(color1, color2) if (not color1 or not color2) then return true end return contrast { color1, color2, error = 0 } >= 4.5 end 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 not check_constrast(data.infoColor, data.backgroundColor) then legible = false end if data.showId and not check_constrast(data.idColor, data.idBackgroundColor) then if has_text(data.id or "") then legible = false end end if data.showId2 and not check_constrast(data.id2Color, data.id2BackgroundColor) then if has_text(data.id2 or "") then legible = false end end if not legible then root:wikitext('[[Category:Potentially illegible userboxes]]') 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 if #cats > 0 then -- 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 misplaced templates]]' 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) else return nil end end return p