Jump to content

Module:PadUtils: Difference between revisions

From PAD Wiki
No edit summary
No edit summary
Line 88: Line 88:
-- (repeats for each dungeon)
-- (repeats for each dungeon)
function p.dungeonIndex(frame)
function p.dungeonIndex(frame)
     local args   = frame.args
     local args = frame.args
     local where = nil
     local where = nil
     if args.type and args.type ~= "" then
     if args.type and args.type ~= "" then
         where = string.format("Type = '%s'", tostring(args.type):gsub("'", "''"))
         where = string.format("Type = '%s'", tostring(args.type):gsub("'", "''"))
     end
     end


     -- Pull rows, sorted by Dungeon then Name
     -- Query Cargo
     local rows = mw.ext.cargo.query(
     local rows = mw.ext.cargo.query(
         'dungeon_floors',
         'dungeon_floors',
Line 104: Line 104:
     end
     end


     local root = mw.html.create('div')  -- container
     -- helper: strip [[...]] if present, then trim
    local currentDungeon = nil
     local function stripLinks(s)
    local ulForDungeon  = nil
         s = mw.text.trim(s or "")
 
         local inner = s:match("^%[%[(.*)%]%]$")
     local function urlFor(titleText)
        return mw.text.trim(inner or s)
         local t = mw.title.new(titleText)
         return t and t:localUrl() or ("/wiki/" .. mw.uri.encode(titleText))
     end
     end


    local out, current = {}, nil
     for _, r in ipairs(rows) do
     for _, r in ipairs(rows) do
         -- New dungeon group?
         local dungeon = stripLinks(r.Dungeon)
        if r.Dungeon ~= currentDungeon then
        local floor  = stripLinks(r.Name)
            currentDungeon = r.Dungeon
 
            -- Dungeon header link
        -- New dungeon header line (as a wiki link)
            root:tag('a')
        if dungeon ~= current then
                :attr('href', urlFor(currentDungeon))
             if current then table.insert(out, "") end -- blank line between groups
                :wikitext(currentDungeon)
             table.insert(out, string.format('[[%s|%s]]', dungeon, dungeon))
             :done()
            current = dungeon
            -- Start a <ul> for its floors
             ulForDungeon = root:tag('ul')
         end
         end


         -- Floor item link: Dungeon/Floor
         -- Bullet line with floor link: [[Dungeon/Floor|Floor]]
         local target = currentDungeon .. "/" .. r.Name
         local target = dungeon .. '/' .. floor
         ulForDungeon:tag('li')
         table.insert(out, '* [[' .. target .. '|' .. floor .. ']]')
            :tag('a')
                :attr('href', urlFor(target))
                :wikitext(r.Name)
            :done()
        :done()
     end
     end


     return tostring(root)
    -- Parse as wikitext so the links/bullets render
     return frame:preprocess(table.concat(out, "\n"))
end
end



Revision as of 05:40, 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

    -- Query Cargo
    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

    -- helper: strip [[...]] if present, then trim
    local function stripLinks(s)
        s = mw.text.trim(s or "")
        local inner = s:match("^%[%[(.*)%]%]$")
        return mw.text.trim(inner or s)
    end

    local out, current = {}, nil
    for _, r in ipairs(rows) do
        local dungeon = stripLinks(r.Dungeon)
        local floor   = stripLinks(r.Name)

        -- New dungeon header line (as a wiki link)
        if dungeon ~= current then
            if current then table.insert(out, "") end -- blank line between groups
            table.insert(out, string.format('[[%s|%s]]', dungeon, dungeon))
            current = dungeon
        end

        -- Bullet line with floor link: [[Dungeon/Floor|Floor]]
        local target = dungeon .. '/' .. floor
        table.insert(out, '* [[' .. target .. '|' .. floor .. ']]')
    end

    -- Parse as wikitext so the links/bullets render
    return frame:preprocess(table.concat(out, "\n"))
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