Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

// request.cf · coarse context

A page that knows where it met you.

Only coarse request metadata is shown. This demo does not display or persist visitor IP addresses.

Country
US
Cloudflare location
CMH
Connection
HTTP/2
Language
Not provided

Ray ID: a401a51abbdc8043

Jump to content

Module:Badge display

From Wikipedia, the free encyclopedia

--- Badge display module.
-- Initial code by John Dovey (19 April 2023) [[User:BoonDock]].
-- Rationalised 10 September 2026: template wrappers / nil-safe fields / CSS + error markup fixes /
-- sorted BadgeTable / dropped unused globals.
-- @module badge display

require('strict')
local p = {}
local data = mw.loadData('Module:Badge display/data')
local getArgs = require('Module:Arguments').getArgs

local DEFAULT_IMAGE = 'Ribbon - Question mark.png'
local ERROR_CATEGORY = '[[Category:Pages with Module:Badge display errors]]'

local function trim(s)
	return mw.text.trim(tostring(s or ''))
end

local function field(rec, name)
	local v = rec and rec[name]
	if v == nil then
		return ''
	end
	return tostring(v)
end

local function errorBox(message)
	return '<strong class="error">(Badge display module error: ' .. message .. ')</strong>' .. ERROR_CATEGORY
end

local function resolveCode(args)
	local code = trim(args[1])
	if code == '' then
		code = trim(args.code)
	end
	return code
end

local function resolveSize(args)
	-- Prefer named size=, then positional 2, then a modest default matching the template docs.
	local size = trim(args.size)
	if size == '' then
		size = trim(args[2])
	end
	if size == '' then
		size = '40px'
	end
	return size
end

local function floatClass(float)
	float = string.lower(trim(float))
	if float == 'left' then
		return 'floatleft'
	elseif float == 'right' then
		return 'floatright'
	end
	return ''
end

local function imageName(rec)
	local image = field(rec, 'Image')
	if image == '' then
		return DEFAULT_IMAGE
	end
	return image
end

local function safeDomId(code)
	-- IDs must not contain spaces/odd filename characters; use the lookup code.
	return 'badge-display-' .. (code:gsub('[^%w%-_]', '-'))
end

function p.DisplayImage(frame)
	local args = getArgs(frame, {
		wrappers = {
			'Template:Badge display',
		},
	})

	local code = resolveCode(args)
	if code == '' then
		return errorBox('missing badge code')
	end
	local rec = data[code]
	if not rec then
		return errorBox('<code>' .. code .. '</code> code not found')
	end

	local size = resolveSize(args)
	local description = field(rec, 'Description')
	local pageLink = field(rec, 'PageLink')
	local className = field(rec, 'Class')
	local variation = field(rec, 'Variation')
	local note = field(rec, 'Note')
	local typeName = field(rec, 'Type')
	local image = imageName(rec)

	-- NoTable=yes: image only
	if trim(args.NoTable) ~= '' then
		-- |center so images sit centred in table cells
		return '[[File:' .. image .. '|' .. size .. '|center|' .. description .. ']]'
	end

	-- DescOnly=yes or DescOnly=custom text: image + linked description
	local descOnly = args.DescOnly
	if descOnly ~= nil and trim(descOnly) ~= '' then
		if string.lower(trim(descOnly)) ~= 'yes' then
			description = tostring(descOnly)
		end
		local linkTarget = pageLink ~= '' and pageLink or description
		return '[[File:' .. image .. '|' .. size .. ']] [[' .. linkTarget .. '|' .. description .. ']]'
	end

	local float = floatClass(args.float)
	local domId = safeDomId(code)
	local caption = description
	if pageLink ~= '' then
		caption = '[[' .. pageLink .. '|' .. description .. ']]'
	end
	if #typeName > 1 then
		caption = caption .. ' (' .. typeName .. ')'
	end

	local details = {}
	if #className > 1 then
		table.insert(details, className .. '.')
	end
	if #variation > 1 then
		table.insert(details, variation .. '.')
	end
	if #note > 1 then
		table.insert(details, '<i>' .. note .. '</i>')
	end

	local wikitext = {}
	table.insert(wikitext, '{| class="wikitable ' .. float .. '" style="max-width: 18em; width: auto; margin: 4px; border: none;"')
	table.insert(wikitext, '|+ ' .. caption)
	table.insert(wikitext, '|-')
	table.insert(wikitext, '|aria-describedby="' .. domId .. '" style="text-align: center; border: none; padding-bottom: 10px;" | [[File:' .. image .. '|' .. size .. '|alt=]]')
	table.insert(wikitext, '|-')
	table.insert(wikitext, '|id="' .. domId .. '" style="text-align: center; border: 0; border-top: 1px solid var(--border-color-subtle); padding-top: 4px; margin-top: 4px; text-wrap-style: pretty;"|' .. table.concat(details, ' '))
	table.insert(wikitext, '|-')
	table.insert(wikitext, '|}')
	return table.concat(wikitext, '\n')
end

function p.BadgeTable(frame)
	local codes = {}
	for code, _ in pairs(data) do
		table.insert(codes, code)
	end
	table.sort(codes, function(a, b)
		local da = field(data[a], 'Description')
		local db = field(data[b], 'Description')
		if da == db then
			return a < b
		end
		return da < db
	end)

	local rows = {
		'{| class="wikitable sortable"',
		'|+ List of badges available',
		'|-',
		'! Code !! Type !! Description !! Class !! Variation !! Image !! Note !! Country',
	}
	for _, code in ipairs(codes) do
		local rec = data[code]
		local description = field(rec, 'Description')
		local pageLink = field(rec, 'PageLink')
		local image = imageName(rec)
		local descCell
		if pageLink == '' then
			descCell = description
		else
			descCell = '[[' .. pageLink .. '|' .. description .. ']]'
		end
		table.insert(rows, '|-')
		table.insert(rows, '|' .. code)
		table.insert(rows, '| ' .. field(rec, 'Type'))
		table.insert(rows, '| ' .. descCell)
		table.insert(rows, '| ' .. field(rec, 'Class'))
		table.insert(rows, '| ' .. field(rec, 'Variation'))
		table.insert(rows, '| [[File:' .. image .. '|80px]]')
		table.insert(rows, '| style="text-align: left;" | ' .. field(rec, 'Note'))
		table.insert(rows, '| ' .. field(rec, 'Country'))
	end
	table.insert(rows, '|}')
	return table.concat(rows, '\n')
end

return p