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 = {}
-- 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)
-- collect journal_* params
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, {
key = k,
label = k:gsub("^journal_", ""):gsub("_", " "),
text = val
})
end
end
end
-- legacy single journal
if #journals == 0 and trim(args.journal) then
return args.journal
end
if #journals == 0 then
return nil
end
-- single journal: no <details>
if #journals == 1 then
return journals[1].text
end
-- multiple journals: details blocks
local out = {}
table.insert(out, '<div class="vp-journal-multi">')
for i, j in ipairs(journals) do
local open = (i == 1) and " open" or ""
table.insert(out,
string.format(
'<details class="vp-journal-block"%s><summary>%s</summary><div class="vp-journal-text">%s</div></details>',
open,
titleCase(j.label),
j.text
)
)
end
table.insert(out, '</div>')
return table.concat(out)
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)
-- rows: everything except reserved params
local reserved = {
name = true,
image = true,
journal = true
}
for k, _ in pairs(args) do
if k:match("^journal_") then
reserved[k] = true
end
end
local rows = {}
for k, v in pairs(args) do
if not reserved[k] then
local val = trim(v)
if val then
table.insert(rows, {
label = titleCase(k:gsub("_", " ")),
value = val
})
end
end
end
-- Begin table
local html = {}
table.insert(html, '<table class="infobox infobox-generic">')
-- Header
table.insert(html,
string.format(
'<tr><th colspan="2" class="infobox-header">%s</th></tr>',
esc(name)
)
)
-- Image
if image then
table.insert(html,
string.format(
'<tr><td colspan="2" class="infobox-image">[[File:%s|250px|center|%s]]</td></tr>',
image,
esc(name)
)
)
end
-- Journal
local journalHTML = renderJournal(args)
if journalHTML then
table.insert(html,
'<tr><td colspan="2" class="infobox-section infobox-journal-cell">' ..
journalHTML ..
'</td></tr>'
)
end
-- Rows
for _, row in ipairs(rows) do
table.insert(html,
string.format(
'<tr>' ..
'<td class="infobox-section infobox-label-cell"><span class="infobox-label">%s</span></td>' ..
'<td class="infobox-section infobox-value-cell">%s</td>' ..
'</tr>',
esc(row.label),
row.value
)
)
end
table.insert(html, '</table>')
return table.concat(html, "\n")
end
return p