Module:Infobox: Difference between revisions
From Piñata Journal
More actions
Admin Jeremy (talk | contribs) No edit summary |
Admin Jeremy (talk | contribs) No edit summary |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 33: | Line 33: | ||
-- Render journal section | -- Render journal section | ||
local function renderJournal(args) | 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) | |||
end | -- 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 | end | ||
return p | return p | ||
Latest revision as of 12:47, 6 February 2026
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