Module:Infobox
From Piñata Journal
More actions
Documentation for this module may be created at Module:Infobox/doc
-- Utility: Title Case (capitalize every word)
local function titleCase(s)
if not s then return nil end
local lang = mw.language.getContentLanguage()
s = s:gsub("(%S+)", function(word)
return lang:ucfirst(word)
end)
return s
end
local p = {}
local journalLabels = {
journal_tip = "Trouble in Paradise",
journal_pp = "Pocket Paradise",
journal_vp1 = "Viva Piñata"
}
-- Utility: trim whitespace
local function trim(s)
if not s then return nil end
s = mw.text.trim(s)
if s == "" then return nil end
return s
end
-- Utility: escape HTML
local function esc(s)
return mw.text.nowiki(s)
end
-- Render journal section
local function renderJournal(args, frame)
local journals = {}
for k, v in pairs(args) do
if type(k) == "string" and k:match("^journal_") then
local val = trim(v)
if val then
table.insert(journals, {
label = journalLabels[k] or titleCase(
k:gsub("^journal_", ""):gsub("_", " ")
),
text = val
})
end
end
end
if #journals == 0 then
return nil
end
-- SINGLE
if #journals == 1 then
return frame:preprocess(journals[1].text)
end
-- MULTI (emit wikitext!)
local out = {}
for i, j in ipairs(journals) do
table.insert(out, string.format([[
<details class="vp-journal-block"%s>
<summary>%s</summary>
<div class="vp-journal-text">
%s
</div>
</details>
]], i == 1 and " open" or "", j.label, j.text))
end
return frame:preprocess(table.concat(out, "\n"))
end
-- Main renderer
function p.render(frame)
local args = frame:getParent().args
local name = trim(args.name) or mw.title.getCurrentTitle().text
local image = trim(args.image)
-- reserved params
local reserved = {
name = true,
image = true,
journal = true
}
for k, _ in pairs(args) do
if type(k) == "string" and k:match("^journal_") then
reserved[k] = true
end
end
-- build table
local tableNode = mw.html.create('table')
tableNode:addClass('infobox')
tableNode:addClass('infobox-generic')
-- header
tableNode:tag('tr')
:tag('th')
:attr('colspan', 2)
:addClass('infobox-header')
:wikitext(name)
-- image
if image then
tableNode:tag('tr')
:tag('td')
:attr('colspan', 2)
:addClass('infobox-image')
:wikitext(string.format('[[File:%s|250px|center|%s]]', image, name))
end
-- journal
local journalHTML = renderJournal(args, frame)
if journalHTML then
tableNode:tag('tr')
:tag('td')
:attr('colspan', 2)
:addClass('infobox-section')
:addClass('infobox-journal-cell')
:node(journalHTML)
end
-- FIXED ORDER KEYS
local fixedOrder = {
"level",
"base_value",
"animal",
"candy",
"attack_object",
"role",
"relationships",
"voiced_by"
}
for _, k in ipairs(fixedOrder) do
local v = args[k]
if v then
local val = trim(v)
if val then
local row = tableNode:tag('tr')
row:tag('td')
:addClass('infobox-section')
:addClass('infobox-label-cell')
:tag('span')
:addClass('infobox-label')
:wikitext(titleCase(k:gsub("_", " ")))
row:tag('td')
:addClass('infobox-section')
:addClass('infobox-value-cell')
:wikitext(val)
end
reserved[k] = true
end
end
-- ANY REMAINING ARGS (alphabetical)
local remainingKeys = {}
for k in pairs(args) do
if not reserved[k] then
table.insert(remainingKeys, k)
end
end
table.sort(remainingKeys)
for _, k in ipairs(remainingKeys) do
local val = trim(args[k])
if val then
local row = tableNode:tag('tr')
row:tag('td')
:addClass('infobox-section')
:addClass('infobox-label-cell')
:tag('span')
:addClass('infobox-label')
:wikitext(titleCase(k:gsub("_", " ")))
row:tag('td')
:addClass('infobox-section')
:addClass('infobox-value-cell')
:wikitext(val)
end
end
return tostring(tableNode)
end
return p