Module:GameInfo
More actions
Module:GameInfo is the stable entrypoint for SpiritVale “GameInfo” renderers (Phase 4.1).
Contract
Pages are generated/updated by SVWT + pywikibot (compiled artifacts).
This module reads arguments from frame.args only (no parent-frame wrappers).
Submodules are pure renderers and must export render(frame).
Entry points
{{#invoke:GameInfo|Skills|id=...|index=...|notes=...|data=...}}
{{#invoke:GameInfo|Category|name=Skills|...}}
The Category router is allowlist-only. Users cannot force arbitrary require() targets.
Routing
GameInfo routes only to modules listed in the internal allowlist. Currently supported:
- Skills → Module:GameInfo/Skills
TemplateStyles
GameInfo always emits one TemplateStyles tag per invocation. Default CSS:
Module:GameInfo/styles.css
Submodules may override by setting:
STYLE_SRC = "Module:GameInfo/skills.css"
Shared scaffolding
Args helpers
arg(frame, key, fallback)trims and returns a string.int(frame, key, fallback, min, max)clamps integers.bool(frame, key, fallback)supports 1/0, true/false, yes/no.
= Container builder
box(opts) creates the canonical card shell:
- root:
div.sv-gi-card - top:
div.sv-gi-top - bottom:
div.sv-gi-bottom
Data attributes:
data-gi="1"data-gi-phase="4.1"data-level,data-max-level
Optional:
id(orroot_id)variantadds classsv-gi--<variant>
Convenience renderer
render_box(opts) builds the box and fills top/bottom with either HTML nodes or wikitext.
Error handling
If a route cannot be loaded or throws, GameInfo returns TemplateStyles plus a wiki-friendly error box:
div.sv-gi-error
Debug / wiring test
A simple sanity check exists:
{{#invoke:GameInfo|skeleton|id=sv-gi-test-1|level=1|max=10|variant=skills}}
-- Module:GameInfo
-- Base container + shared scaffolding for all GameInfo.* renderers (Phase 4.1).
local p = {}
-- Shared TemplateStyles page (Module space per Phase 4.1).
local DEFAULT_STYLE_SRC = "Module:GameInfo/gameinfo.css"
local function _to_int(v, fallback)
if v == nil then return fallback end
local n = tonumber(v)
if not n then return fallback end
n = math.floor(n + 0.0)
return n
end
local function _is_html_node(x)
-- mw.html nodes are Lua tables with common builder methods.
return type(x) == "table" and type(x.tag) == "function" and type(x.wikitext) == "function"
end
local function _add_content(container, content)
if content == nil then return end
if _is_html_node(content) then
container:node(content)
return
end
container:wikitext(tostring(content))
end
-- Emit TemplateStyles. Submodules should include this once at the top of output.
function p.styles(frame, src)
frame = frame or mw.getCurrentFrame()
local style_src = src or DEFAULT_STYLE_SRC
return frame:extensionTag("templatestyles", "", { src = style_src })
end
-- Core builder: returns { root = <div>, top = <div>, bottom = <div> }
-- Caller fills top/bottom and tostring(root) to return.
function p.new_box(opts)
opts = opts or {}
local root_id = opts.root_id or opts.id
local level = _to_int(opts.level, 1)
local max_level = _to_int(opts.max_level, 1)
if max_level < 1 then max_level = 1 end
if level < 1 then level = 1 end
if level > max_level then level = max_level end
local root = mw.html.create("div")
:addClass("sv-gi-card")
:attr("data-gi", "1")
:attr("data-level", tostring(level))
:attr("data-max-level", tostring(max_level))
if root_id and root_id ~= "" then
root:attr("id", root_id)
end
-- Optional variant class for category modules (e.g. "sv-gi--skills").
if opts.variant and opts.variant ~= "" then
root:addClass("sv-gi--" .. tostring(opts.variant))
end
local top = root:tag("div"):addClass("sv-gi-top")
local bottom = root:tag("div"):addClass("sv-gi-bottom")
return {
root = root,
top = top,
bottom = bottom,
}
end
-- Convenience wrapper: build a full box in one call.
-- opts.top / opts.bottom can be strings or mw.html nodes.
function p.render_box(opts)
local box = p.new_box(opts)
_add_content(box.top, opts and opts.top)
_add_content(box.bottom, opts and opts.bottom)
return tostring(box.root)
end
-- Optional: #invoke test entrypoint to verify box + CSS wiring.
-- {{#invoke:GameInfo|skeleton|id=sv-gi-test-1|level=1|max=10}}
function p.skeleton(frame)
frame = frame or mw.getCurrentFrame()
local args = frame.args or {}
local id = args.id or "sv-gi-skeleton-1"
local level = args.level or args.data_level or 1
local max_level = args.max or args.max_level or 10
local top = mw.html.create("div"):wikitext("GameInfo Top (locked container)")
local bottom = mw.html.create("div"):wikitext("GameInfo Bottom (locked container)")
return p.styles(frame) .. p.render_box({
root_id = id,
level = level,
max_level = max_level,
variant = args.variant,
top = tostring(top),
bottom = tostring(bottom),
})
end
return p