Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Join the Playtest on Steam Now: SpiritVale

Module:Definitions: Difference between revisions

From SpiritVale Wiki
Created page with "-- Module:Definitions -- Core resolver + renderer for {{def|Domain|Key}} (Definitions v1). -- -- Data source (static): -- Module:Definitions/Definitions.json -- -- JSON shape (dynamic): -- { -- "Schema": 1, -- "UpdatedAt": "YYYY-MM-DD", -- "Stat": { "Vit": { "Name":"...", "Definition":"...", "Icon":"", "Link":"" }, ... }, -- "Target": { ... }, -- ... -- } -- -- Notes: -- - Domains + keys are discovered from JSON (no hardcoded domain lists). -- - CSS namespa..."
 
No edit summary
Tags: Mobile edit Mobile web edit
 
(18 intermediate revisions by 2 users not shown)
Line 4: Line 4:
-- Data source (static):
-- Data source (static):
--  Module:Definitions/Definitions.json
--  Module:Definitions/Definitions.json
--
-- JSON shape (dynamic):
-- {
--  "Schema": 1,
--  "UpdatedAt": "YYYY-MM-DD",
--  "Stat":  { "Vit": { "Name":"...", "Definition":"...", "Icon":"", "Link":"" }, ... },
--  "Target": { ... },
--  ...
-- }
--
--
-- Notes:
-- Notes:
-- - Domains + keys are discovered from JSON (no hardcoded domain lists).
-- - Domains + keys are discovered from JSON (no hardcoded domain lists).
-- - CSS namespace: ONLY "sv-def" (plus sv-def--* modifiers). No other CSS prefixes.
-- - CSS namespace: ONLY "sv-def" (plus sv-def--* modifiers).
-- - Output classes: sv-def, sv-def-icon, sv-def-icon-img, sv-def-text.
-- - Tooltip/link behavior is handled by Universal Popups (Common.js).


local p = {}
local p = {}
Line 23: Line 16:


-- =============================================================================
-- =============================================================================
-- Small helpers
-- Helpers
-- =============================================================================
-- =============================================================================


Line 33: Line 26:
local function lc(s)
local function lc(s)
return string.lower(tostring(s or ""))
return string.lower(tostring(s or ""))
end
local function truthy(v)
v = lc(mw.text.trim(tostring(v or "")))
return v == "1" or v == "true" or v == "yes" or v == "y"
end
end


Line 101: Line 99:
end
end


-- Case-insensitive match across top-level keys, skipping meta keys
-- Case-insensitive match across top-level keys that are tables
local want = lc(domain)
local want = lc(domain)
for k, v in pairs(db) do
for k, v in pairs(db) do
if type(v) == "table" and lc(k) == want then
if type(v) == "table" and lc(k) == want then
-- ignore meta containers if any ever appear
return k
if k ~= "Schema" and k ~= "UpdatedAt" then
return k
end
end
end
end
end
Line 122: Line 117:


-- =============================================================================
-- =============================================================================
-- Icon rendering (missing/file-not-found => "?")
-- Icon rendering
-- - Blank icon: render nothing
-- - Missing file: render "?" badge (no redlink image)
-- =============================================================================
-- =============================================================================


Line 129: Line 126:


if icon == "" then
if icon == "" then
return '<span data-sv-def-part="icon" aria-hidden="true">?</span>'
return ""
end
end


Line 139: Line 136:
local t = mw.title.new(fileTitle)
local t = mw.title.new(fileTitle)
if not t or not t.exists then
if not t or not t.exists then
return '<span data-sv-def-part="icon" aria-hidden="true">?</span>'
return '<span class="sv-def-icon sv-def-icon--missing" aria-hidden="true">?</span>'
end
end


-- No extra CSS classes; styling should target .sv-def and descendants.
return '<span class="sv-def-icon-img">[[' .. fileTitle .. '|14px|link=]]</span>'
return '<span data-sv-def-part="icon">[[' .. fileTitle .. '|16px|link=]]</span>'
end
end


Line 150: Line 146:
-- =============================================================================
-- =============================================================================


local function render(domain, key)
local function render(domain, key, opts)
opts = opts or {}
local noicon = truthy(opts.noicon)
local pill  = truthy(opts.pill)
local fill  = truthy(opts.fill)
 
local db = load_db()
local db = load_db()
domain = norm_domain(db, domain)
domain = norm_domain(db, domain)
Line 174: Line 175:


local d_lc = lc(domain)
local d_lc = lc(domain)
-- Missing record: visible hint, no tooltip/link attributes.
if rec == nil then
local miss_icon = noicon and "" or '<span class="sv-def-icon sv-def-icon--missing" aria-hidden="true">?</span>'
return
'<span class="sv-def sv-def--missing' ..
(pill and ' sv-def--pill' or '') ..
(fill and ' sv-def--fill' or '') ..
' sv-def--' .. enc_attr(d_lc) .. '"' ..
' data-sv-def-domain="' .. enc_attr(domain) .. '"' ..
' data-sv-def-key="' .. enc_attr(key) .. '"' ..
(pill and ' data-sv-def-pill="1"' or '') ..
(fill and ' data-sv-def-fill="1"' or '') ..
'>' ..
miss_icon ..
'<span class="sv-def-text">' .. mw.text.nowiki(name) .. '</span>' ..
'</span>'
end
local classes = 'sv-def sv-def--' .. enc_attr(d_lc)
if noicon then classes = classes .. ' sv-def--noicon' end
if pill then classes = classes .. ' sv-def--pill' end
if fill then classes = classes .. ' sv-def--fill' end


local attrs = {
local attrs = {
'class="sv-def sv-def--' .. enc_attr(d_lc) .. '"',
'class="' .. classes .. '"',
'data-sv-def-domain="' .. enc_attr(domain) .. '"',
'data-sv-def-domain="' .. enc_attr(domain) .. '"',
'data-sv-def-key="' .. enc_attr(key) .. '"',
'data-sv-def-key="' .. enc_attr(key) .. '"',
}
}


if pill then attrs[#attrs + 1] = 'data-sv-def-pill="1"' end
if fill then attrs[#attrs + 1] = 'data-sv-def-fill="1"' end
-- Only include tooltip/link attributes when populated.
if defn ~= "" then
if defn ~= "" then
attrs[#attrs + 1] = 'data-sv-def-tip="' .. enc_attr(defn) .. '"'
attrs[#attrs + 1] = 'data-sv-def-tip="' .. enc_attr(defn) .. '"'
-- Interactive definitions are focusable for consistent UX.
attrs[#attrs + 1] = 'tabindex="0"'
end
end
if link ~= "" then
if link ~= "" then
Line 188: Line 218:
end
end


local title_attr = (defn ~= "") and (' title="' .. enc_attr(defn) .. '"') or ""
local ico = noicon and "" or icon_html(icon)


local html =
return
'<span ' .. table.concat(attrs, " ") .. title_attr .. '>' ..
'<span ' .. table.concat(attrs, " ") .. '>' ..
icon_html(icon) ..
ico ..
'<span data-sv-def-part="text">' .. mw.text.nowiki(name) .. '</span>' ..
'<span class="sv-def-text">' .. mw.text.nowiki(name) .. '</span>' ..
'</span>'
'</span>'
if rec == nil then
-- Missing record: visible placeholder hint (still styled as sv-def)
html =
'<span class="sv-def sv-def--missing" data-sv-def-domain="' .. enc_attr(domain) ..
'" data-sv-def-key="' .. enc_attr(key) .. '">?</span>'
end
return html
end
end


Line 210: Line 231:
-- =============================================================================
-- =============================================================================


-- Template entrypoint: {{#invoke:Definitions|def|Domain|Key}}
function p.def(frame)
function p.def(frame)
local a = frame.args or {}
local a = frame.args or {}
return render(a[1] or a.Domain or a.domain, a[2] or a.Key or a.key)
local domain = a[1] or a.Domain or a.domain
local key    = a[2] or a.Key or a.key
local noicon = a.noicon or a.NoIcon or a[3]
local pill  = a.pill or a.Pill
local fill  = a.fill or a.Fill
return render(domain, key, { noicon = noicon, pill = pill, fill = fill })
end
end


-- Programmatic: require('Module:Definitions').render('Stat', 'Vit')
function p.render(domain, key, opts)
function p.render(domain, key)
return render(domain, key, opts)
return render(domain, key)
end
end


return p
return p