Module:EquipmentGallery
Jump to navigation
Jump to search
Module:EquipmentGallery
Queries DPL3 for Menu Garments images matching a given item name, parses the filenames into captioned entries, and returns sorted filename~caption lines compatible with Template:Gallery.
This module should not be invoked directly. To add a dynamic image gallery to a Garment page, use Template:EquipmentGallery.
This module provides the following function(s):
main- queries DPL3 for matching garment images, parses the filenames, generates captions, and returns sorted output lines.
Usage
Render a dynamic Equipment gallery
On an Equipment page, via Template:EquipmentGallery:
{{#invoke:EquipmentGallery|main|{{BASEPAGENAME}}}}
Parameters
main
- 1
- string
- The item name used as the parsing anchor within each filename and as the DPL3 query target. Typically passed as
{{BASEPAGENAME}}from the template. - The value is decoded via
mw.text.decode()to handle HTML entities (e.g.'for apostrophes in page titles like'Thopter Pilot Set).
Notes
Filename format
The module expects filenames matching the following structure:
Menu Garments <GENDER> [SWATCH] <ITEM_NAME> [SIDE].jpg
- GENDER
MasculineorFeminine. Required.- SWATCH
- Zero or more words between GENDER and ITEM_NAME. Optional.
- ITEM_NAME
- Must match the item name parameter. Required.
- SIDE
FrontorBack. Optional.
local p = {}
local common = require("Module:Common")
-- ---------- Data ----------
local PREFIX = "Menu Garments "
local GENDERS = { Masculine = 1, Feminine = 2 }
local SIDES = { Front = 1, Back = 2 }
local DPL_QUERY = '{{ #dpl: namespace = File | titlematch = Menu Garments%%%s%% | format = ,%%TITLE%%\\n,, }}'
-- ---------- Processing ----------
function p.parseFilename(filename, itemName)
-- strip prefix
if filename:sub(1, #PREFIX) ~= PREFIX then
return nil
end
local base = filename:sub(#PREFIX + 1)
-- strip file extension
base = base:match("^(.+)%..+$")
-- extract gender
local gender, rest = base:match("^(%S+)%s+(.*)")
if not gender or not GENDERS[gender] then
return nil
end
-- find item name anchor
local itemPos = rest:find(itemName, 1, true)
if not itemPos then
return nil
end
-- extract swatch, if present
local swatch = nil
if itemPos > 1 then
local raw = common.trim(rest:sub(1, itemPos - 1))
if raw ~= "" then
swatch = raw
end
end
-- extract front/back, if present
local afterItem = common.trim(rest:sub(itemPos + #itemName))
local side = nil
if SIDES[afterItem] then
side = afterItem
end
return {
gender = gender,
swatch = swatch,
side = side,
}
end
function p.buildCaption(parsed)
local caption = parsed.swatch and "'''" .. parsed.swatch .. " Swatch'''" or "'''Default Swatch'''"
caption = caption .. "<br>" .. parsed.gender
if parsed.side then
caption = caption .. " (" .. parsed.side .. ")"
end
return caption
end
-- ---------- Interface ----------
function p.main(frame)
local args = frame.args
local itemName = mw.text.decode(common.trim(args[1] or ""))
local input = itemName ~= "" and common.trim(frame:preprocess(string.format(DPL_QUERY, itemName))) or ""
if input == "" then
return "Placeholder.jpg~No matching images"
end
local entries = {}
for line in input:gmatch("[^\r\n]+") do
line = common.trim(line)
if line ~= "" then
local parsed = p.parseFilename(line, itemName)
entries[#entries + 1] = {
filename = line,
parsed = parsed,
}
end
end
-- sort order: swatch (none first) > gender (Masc first) > side (Front first)
table.sort(entries, function(a, b)
local ap, bp = a.parsed, b.parsed
-- unparseable entries go to the end
if not ap then return false end
if not bp then return true end
-- push un-swatched images to the front
local aHas = ap.swatch and 1 or 0
local bHas = bp.swatch and 1 or 0
if aHas ~= bHas then return aHas < bHas end
-- sort swatches alphabetically
if ap.swatch and bp.swatch and ap.swatch ~= bp.swatch then
return ap.swatch < bp.swatch
end
-- gender
local aGender = GENDERS[ap.gender]
local bGender = GENDERS[bp.gender]
if aGender ~= bGender then return aGender < bGender end
-- side (but also account for those that don't have front/back yet)
local aSide = SIDES[ap.side] or 3
local bSide = SIDES[bp.side] or 3
return aSide < bSide
end)
-- build output lines
local lines = {}
for i = 1, #entries do
local e = entries[i]
if e.parsed then
lines[#lines + 1] = e.filename .. "~" .. p.buildCaption(e.parsed)
else
lines[#lines + 1] = e.filename
end
end
return table.concat(lines, "\n")
end
return p