Module:SegmentQuery

From Bodhicitta
Revision as of 22:57, 3 March 2026 by Jeremi (talk | contribs) (VSCode edit)

Documentation for this module may be created at Module:SegmentQuery/doc

-- Module:SegmentQuery
-- Dynamically emits SegmentQuery calls sized appropriately
-- for the chapter's content weight.
-- Invoked from Template:DisplayTmSection as:
--   {{#invoke:SegmentQuery|renderChunks|{{{ TranslationChapter | }}}}}

local p = {}

local CHUNK_SIZE_NORMAL = 20
local CHUNK_SIZE_LARGE  = 3   -- smaller chunks for chapters with "Large content" segments
local MAX_SEGMENTS      = 500 -- absolute safety cap

function p.renderChunks(frame)
    local currentTitle = mw.title.getCurrentTitle()

    -- Mirror SegmentQuery's fallback: if TranslationChapter not passed, use SUBPAGENAME
    local chapter = mw.text.trim(frame.args[1] or '')
    local hasChapter = chapter ~= ''
    if not hasChapter then
        chapter = currentTitle.subpageText  -- equivalent to {{SUBPAGENAME}}
    end

    -- Resolve TransMemID from the base page (mirrors {{#show:{{BASEPAGENAME}}|?TransMemID}})
    -- BASEPAGENAME strips the subpage, so for "Foo/Bar/18" we query "Foo/Bar"
    local baseName = currentTitle.baseText  -- equivalent to {{BASEPAGENAME}}
    local transMemID = mw.text.trim(frame.args[2])

    local baseConditions =
        '[[TransMemID::' .. transMemID .. ']]' ..
        (hasChapter and '[[TranslationChapter::' .. chapter .. ']]' or '') ..
        '[[SegmentFormat::!Deprecated]]'

    -- 1. Count total segments (synchronous, no text fields — just need the count)
    local countResult = mw.smw.ask(
        baseConditions ..
        '|?SegmentOrder' ..
        '|limit=' .. MAX_SEGMENTS ..
        '|link=none'
    )
    local totalSegments = countResult and #countResult or 0
    if totalSegments == 0 then return '<!-- SegmentQuery: 0 segments found for TransMemID=' .. transMemID .. ' chapter=' .. chapter .. ' -->' end

    -- 2. Check for any "Large content" flag in this chapter (synchronous, limit=1 — cheap)
    local largeCheck = mw.smw.ask(
        baseConditions ..
        '[[Flag::Large content]]' ..
        '|?SegmentOrder' ..
        '|limit=1' ..
        '|link=none'
    )
    local chunkSize = (largeCheck and #largeCheck > 0) and CHUNK_SIZE_LARGE or CHUNK_SIZE_NORMAL

    -- 3. Emit one deferred SegmentQuery call per batch.
    --    Chunks are sorted by SegmentOrder within SegmentQuery, so
    --    segments appear in correct order across chunks as they load.
    --    Each chunk manages its own intro/outro filterableContent wrapper.
    local parts = {}
    local offset = 0
    while offset < totalSegments do
        table.insert(parts, frame:expandTemplate{
            title = 'SegmentQuery',
            args  = { chapter, limit = tostring(chunkSize), offset = tostring(offset), TransMemID = transMemID }
        })
        offset = offset + chunkSize
    end

    return table.concat(parts)
end

return p