Module:PadUtils: Difference between revisions
Appearance
GlifterPad (talk | contribs) No edit summary |
GlifterPad (talk | contribs) No edit summary |
||
| Line 80: | Line 80: | ||
-- showcount : "1"/"true" -> append (N) after each dungeon name | -- showcount : "1"/"true" -> append (N) after each dungeon name | ||
-- limit : max rows to fetch (default 5000) | -- limit : max rows to fetch (default 5000) | ||
-- Renders: | |||
-- <a href="/wiki/Dungeon">Dungeon</a> | |||
-- <ul> | |||
-- <li><a href="/wiki/Dungeon/Floor">Floor</a></li> | |||
-- ... | |||
-- </ul> | |||
-- (repeats for each dungeon) | |||
function p.dungeonIndex(frame) | function p.dungeonIndex(frame) | ||
local args | local args = frame.args | ||
local | local where = nil | ||
if args.type and args.type ~= "" then | |||
where = string.format("Type = '%s'", tostring(args.type):gsub("'", "''")) | |||
where = string.format("Type = '%s'", | |||
end | end | ||
-- Pull rows, sorted by Dungeon then Name | |||
local rows = mw.ext.cargo.query( | local rows = mw.ext.cargo.query( | ||
'dungeon_floors', | 'dungeon_floors', | ||
'Dungeon, Name', | |||
{ where = where, orderBy = | { where = where, orderBy = 'Dungeon, Name', limit = 5000 } | ||
) | ) | ||
if not rows or #rows == 0 then | if not rows or #rows == 0 then | ||
return "''No results''" | return "''No results''" | ||
end | end | ||
-- | local root = mw.html.create('div') -- container | ||
local | local currentDungeon = nil | ||
local ulForDungeon = nil | |||
local | |||
local function urlFor(titleText) | |||
local t = mw.title.new(titleText) | |||
return t and t:localUrl() or ("/wiki/" .. mw.uri.encode(titleText)) | |||
end | end | ||
for _, r in ipairs(rows) do | |||
-- New dungeon group? | |||
for _, | if r.Dungeon ~= currentDungeon then | ||
currentDungeon = r.Dungeon | |||
if | -- Dungeon header link | ||
root:tag('a') | |||
:attr('href', urlFor(currentDungeon)) | |||
:wikitext(currentDungeon) | |||
:done() | |||
-- Start a <ul> for its floors | |||
ulForDungeon = root:tag('ul') | |||
end | |||
-- Floor item link: Dungeon/Floor | |||
local target = currentDungeon .. "/" .. r.Name | |||
ulForDungeon:tag('li') | |||
:tag('a') | |||
:attr('href', urlFor(target)) | |||
:wikitext(r.Name) | |||
:done() | |||
:done() | |||
end | end | ||
return | return tostring(root) | ||
end | end | ||
-- Build a list of floor links under the current dungeon (or a given base). | -- Build a list of floor links under the current dungeon (or a given base). | ||
-- Usage from template/page: | -- Usage from template/page: | ||
Revision as of 05:38, 22 August 2025
Documentation for this module may be created at Module:PadUtils/doc
-- Module:PadUtils
local p = {}
-- split "A;B;C" safely (ignores empty pieces)
local function split(text, delim)
local out = {}
if not text or text == "" then return out end
for part in mw.text.gsplit(text, delim, true) do
part = mw.text.trim(part)
if part ~= "" then table.insert(out, part) end
end
return out
end
-- Accept any of:
-- "Floor Name"
-- "Floor_Target|Floor Label"
-- "[[Dungeon/Floor_Target|Floor Label]]"
-- "[[Floor_Target|Floor Label]]"
local function parseItem(item)
local inner = item:match("^%[%[(.*)%]%]$")
if inner then item = inner end
local t, l = item:match("^(.-)|(.*)$")
local target = mw.text.trim(t or item)
local label = mw.text.trim(l or item)
return target, label
end
-- Always normalize to "base/floor" for the link target.
-- If target already starts with "base/", strip that prefix first.
local function normalizeTarget(base, target)
target = mw.text.trim(target)
local withSlash = base .. "/"
if target:sub(1, #withSlash) == withSlash then
target = target:sub(#withSlash + 1)
end
return base .. "/" .. target
end
function p.dungeonFloors(frame)
local args = frame.args
local base = args.base and mw.text.trim(args.base) or mw.title.getCurrentTitle().fullText
local floors = split(args.floors or "", ";")
local ordered = (args.ol == "1" or args.ol == "true")
local before = args.before or ""
local after = args.after or ""
if #floors == 0 then return "" end
local lines = {}
for _, raw in ipairs(floors) do
local target, label = parseItem(raw)
local titleText = normalizeTarget(base, target)
local titleObj = mw.title.new(titleText)
local linkTarget = titleObj and titleObj.prefixedText or titleText -- <-- fixed
local bullet = ordered and "#" or "*"
table.insert(lines, string.format("%s [[%s|%s%s%s]]", bullet, linkTarget, before, label, after))
end
return frame:preprocess(table.concat(lines, "\n"))
end
-- Module:PadUtils (append this function)
local p = {}
-- ... (keep your other helpers / functions above)
-- Build a nested list of all dungeons and their floors from Cargo.
-- Optional args:
-- type : filter by Type (e.g., "Daily")
-- ol : "1"/"true" to use <ol> for dungeons; floors are always <ul>
-- order : "name" or "id" (defaults to name)
-- Build a nested list of all dungeons and their floors from Cargo.
-- Args (all optional):
-- type : filter by Type (e.g., "Daily")
-- ol : "1"/"true" -> numbered dungeons; floors stay bulleted
-- order : "name" (default) or "id" -- top-level and floor order
-- showcount : "1"/"true" -> append (N) after each dungeon name
-- limit : max rows to fetch (default 5000)
-- Renders:
-- <a href="/wiki/Dungeon">Dungeon</a>
-- <ul>
-- <li><a href="/wiki/Dungeon/Floor">Floor</a></li>
-- ...
-- </ul>
-- (repeats for each dungeon)
function p.dungeonIndex(frame)
local args = frame.args
local where = nil
if args.type and args.type ~= "" then
where = string.format("Type = '%s'", tostring(args.type):gsub("'", "''"))
end
-- Pull rows, sorted by Dungeon then Name
local rows = mw.ext.cargo.query(
'dungeon_floors',
'Dungeon, Name',
{ where = where, orderBy = 'Dungeon, Name', limit = 5000 }
)
if not rows or #rows == 0 then
return "''No results''"
end
local root = mw.html.create('div') -- container
local currentDungeon = nil
local ulForDungeon = nil
local function urlFor(titleText)
local t = mw.title.new(titleText)
return t and t:localUrl() or ("/wiki/" .. mw.uri.encode(titleText))
end
for _, r in ipairs(rows) do
-- New dungeon group?
if r.Dungeon ~= currentDungeon then
currentDungeon = r.Dungeon
-- Dungeon header link
root:tag('a')
:attr('href', urlFor(currentDungeon))
:wikitext(currentDungeon)
:done()
-- Start a <ul> for its floors
ulForDungeon = root:tag('ul')
end
-- Floor item link: Dungeon/Floor
local target = currentDungeon .. "/" .. r.Name
ulForDungeon:tag('li')
:tag('a')
:attr('href', urlFor(target))
:wikitext(r.Name)
:done()
:done()
end
return tostring(root)
end
-- Build a list of floor links under the current dungeon (or a given base).
-- Usage from template/page:
-- {{#invoke:PadUtils|dungeonFloors | base={{FULLPAGENAME}} | floors=Floor A;Floor B }}
function p.dungeonFloors(frame)
local args = frame.args
local base = args.base and mw.text.trim(args.base) or mw.title.getCurrentTitle().fullText
local floors = args.floors or ""
local ordered = (args.ol == "1" or args.ol == "true")
local before = args.before or ""
local after = args.after or ""
-- split on semicolons
local list = {}
for part in mw.text.gsplit(floors, ";", true) do
part = mw.text.trim(part)
if part ~= "" then
-- allow [[Target|Label]] or Target|Label or plain Name
local inner = part:match("^%[%[(.*)%]%]$") or part
local t, l = inner:match("^(.-)|(.*)$")
local target = mw.text.trim(t or inner)
local label = mw.text.trim(l or inner)
-- if target already starts with "base/", strip it; always link as base/target
local withSlash = base .. "/"
if target:sub(1, #withSlash) == withSlash then
target = target:sub(#withSlash + 1)
end
local fullTarget = base .. "/" .. target
local titleObj = mw.title.new(fullTarget)
local linkTarget = titleObj and titleObj.prefixedText or fullTarget
local bullet = ordered and "#" or "*"
table.insert(list, string.format("%s [[%s|%s%s%s]]", bullet, linkTarget, before, label, after))
end
end
return frame:preprocess(table.concat(list, "\n"))
end
return p