Module:Badge display
| This module is rated as beta. It is considered ready for widespread use, but as it is still relatively new, it should be applied with some caution to ensure results are as expected. |
Usage
[edit]Please rather use the template I've created to use this data. {{Template:Badge display}}.
Module:Badge display/data
[edit]EDITORS PLEASE NOTE: Be VERY careful that you understand exactly what you are doing if you edit the data in the subpage file. If in doubt, add a topic on the talk page or ping me User:BoonDock with your questions.
Structure
[edit]Note that I have set this up to use the structure:
xx = {Code = "xx", Type = "", Description = "xx", Class="", Variation="", Image="XX", PageLink="XX", Country="ZAR", Note="", Org="SANDF", RecipCat="" },
- xx : the UNIQUE code we use to access this record.
- Description : Description to be used at the top of the display-box, so it will be used when producing the link
- class: intended to be for the class of the badge, it's turning out to be useful for other things as well
- Variation: Mainly whether it's cloth, metal etc. What it's made out of etc
- Image : File name of the file for the badge to be displayed
- PageLink : Name of Wiki Article which the specific badge will link to
- Country. : This should be obvious, but I haven't made a decision whether to use codes or country name
- org: Organisation
- RecipCat: Contents of this field are used as a category name. Not being used at the moment
Examples:
| Black on Thatch beige, Embossed. Scales of Justice surrounded by a Laurel Wreath |
| Musician (SACB). Black on Thatch beige, Embossed. Round badge. Lyre with a wreath |
With different sizes:
| Black on Thatch beige, Embossed. Rectangular bar (upright) with a black dagger and three black lightning flashes angled diagonally across the blade |
| Black on Thatch beige, Embossed. Rectangular bar (upright) with a black dagger and three black lightning flashes angled diagonally across the blade |
You can also float left and right:
| Advanced. Black on Thatch beige, Embossed. Stirrup with a riding crop with a two black circles surrounding the stirrup |
| EOD Badge. Gilt and silver. Gilt metal ring and bomb, facing down, with silver coloured lightning flash |
What this does is it provides the data to various routines which combine it in different ways.
When a template calls one of the routines in the module, the {{{size}}} is replaced with the second un-named parameter when the template is called. That is passed on to this module to set the size of the image.
The "PageLink" provides the name of an article on Wikipedia with no wikilinking. (In theory it could be a URL, but that's not preferred)
The contents of the Description field can be any text which can be used as shown in the examples. Please be careful with this. Using links or curly braces "{}" or inverted commas '' etc can break that entry as well as, potentially, the rest of the entries in the template.
How this works, is that the first unnamed parameter when you call the template is used as the value to look up the corresponding value in this list. Once that value has been found, then the fields in that line are available to the module. These fields are combined in different ways to produce the specific formatting required for the template that called this module.
For this reason, it's very important that this format is not broken or interfered with!
There are now named parameters.
- code: The code for the image
- size: Size of the image
- float: left, right or none
A NOTE ON COUNTRIES
[edit]Separation of countries didn't make sense. It is a lot easier to sort based on a field in the data
Let's please try to keep this as organised as possible. Search the file for your Country's name. If there isn't any mention of it, then create a heading using a comment for your country and add any relevant entries there. Within the country heading, not a bad idea to create sub-headings for different things.
NOTE: the data in this module is now self documenting.
--- 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