Module:All areas

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

-- Module:All_areas
-- Lists all areas as sidebar tiles with article counts.
-- Uses Module:Allowed values for area list (DFT-compatible).
local p = {}

function p.list(frame)
    local ok_req, allowed = pcall(require, 'Module:Allowed values')
    if not ok_req then
        allowed = nil
    end
    local property = 'Area'
    -- Call the new API: allowed.list takes a frame with args[1] = property name
    -- But we can also call the internal function directly
    local areas
    if type(allowed) == 'table' and type(allowed.list) == 'function' then
        -- Try calling with a synthetic frame
        local synthFrame = {
            args = { property },
            getParent = function() return { args = { property } } end
        }
        -- p.list may expect frame:getParent().args, so try both
        local ok, result = pcall(allowed.list, synthFrame)
        if ok and type(result) == 'table' then
            areas = result
        else
            -- Fallback: call with the real frame
            areas = allowed.list(frame) or {}
        end
    else
        -- Fallback: try parser function #q or raw SMW query if available
        local q_val = frame:callParserFunction('#q', 'allowedValues.of', property)
        if q_val and q_val ~= '' then
            areas = {}
            for a in q_val:gmatch("[^;]+") do
                table.insert(areas, mw.text.trim(a))
            end
        elseif mw and mw.smw and mw.smw.ask then
            areas = mw.smw.ask {
                '[[Property:' .. property .. ']]',
                'mainlabel=-',
                '?' .. property .. '=' .. property,
                'format=plainlist',
                'limit=500'
            } or {}
        else
            areas = {}
        end
    end

    local showbadges = false
    local html = mw.html.create()

    local sideblock = html:tag('div')
        :attr('id', 'article-sources')
        :css('flex', '0 0 280px')
        :wikitext()

    local tiles = sideblock:tag('div')
        :addClass('observatory-tile-deck')

    for _, area in ipairs(areas) do
        -- area may be a string or a table with the area name
        local areaName = area
        if type(area) == 'table' then
            areaName = area[property] or area[1] or area.Area or ''
        end
        areaName = tostring(areaName or '')

        if areaName ~= '' then
            local count = frame:callParserFunction(
                '#ask',
                '[[Category:Articles]][[Area::' .. areaName .. ']]',
                'format=count'
            ) or 0

            if tonumber(count) > 0 then
                local item = tiles:tag('div')
                    :addClass('tile d-flex align-items-center gap-3')

                local item_label = item:tag('div')
                    :addClass('tile-caption d-flex justify-content-between align-items-center w-100')

                item_label:tag('div')
                    :wikitext('[[' .. areaName .. ']]')

                if showbadges then
                    item_label:tag('div')
                        :addClass('badge badge-light')
                        :wikitext(count)
                end
            end
        end
    end

    return html
end

return p