Module:SegmentQuery: Difference between revisions

From Bodhicitta
(VSCode edit)
(VSCode edit)
Line 72: Line 72:
         table.insert(parts, frame:expandTemplate{
         table.insert(parts, frame:expandTemplate{
             title = 'SegmentQuery',
             title = 'SegmentQuery',
             args  = { hasChapter and chapter or nil, limit = tostring(chunkSize), offset = tostring(offset), TransMemID = transMemID, LeaveOutArgs = LeaveOutArgs }
             args  = { hasChapter and chapter or nil, limit = tostring(chunkSize), offset = tostring(offset), TransMemID = transMemID, LeaveOutArgs = LeaveOutArgs, SingleLanguage = pargs.SingleLanguage }
         })
         })
         offset = offset + chunkSize
         offset = offset + chunkSize

Revision as of 16:23, 18 March 2026

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()
	local pargs = frame:getParent().args
	local LeaveOutArgs = pargs.LeaveOutArgs
	local DefaultLeft = pargs.DefaultLeft
	local DefaultRight = pargs.DefaultRight

    -- Mirror SegmentQuery's fallback: if TranslationChapter not passed, use SUBPAGENAME
    local chapterRaw = mw.text.trim(frame.args[1] or '')
    local hasChapter = chapterRaw ~= ''

    -- Build chapter condition: semicolon-separated values become [[TranslationChapter::v1||v2||v3]]
    local chapter = chapterRaw  -- used for display/logging only
    local chapterCondition = ''
    if hasChapter then
        local values = {}
        for v in chapterRaw:gmatch('[^;]+') do
            table.insert(values, mw.text.trim(v))
        end
        chapterCondition = '[[TranslationChapter::' .. table.concat(values, '||') .. ']]'
    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( pargs.TransMemID )

    local baseConditions =
        '[[TransMemID::' .. transMemID .. ']]' ..
        chapterCondition ..
        '[[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  = { hasChapter and chapter or nil, limit = tostring(chunkSize), offset = tostring(offset), TransMemID = transMemID, LeaveOutArgs = LeaveOutArgs, SingleLanguage = pargs.SingleLanguage }
        })
        offset = offset + chunkSize
    end

    return table.concat(parts)
end

return p