Module:ElectoralCalendarTable

From Elections Wiki
Jump to navigation Jump to search

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

local p = {}

function p.paginate(frame)
    local dataPage = "Data:Election_Data.json"
    local rowsPerPage = 7
    local currentPage = tonumber(frame.args.page) or 1

    local dataTitle = mw.title.new(dataPage)
    if not dataTitle then
        return "could not find data page '" .. dataPage .. "'!"
    end
    
    local dataContent = dataTitle:getContent()
    if not dataContent then
        return "could not retrieve content from '" .. dataPage .. "'!"
    end

    local APIData = mw.text.jsonDecode(dataContent)
    if not APIData then
        return "invalid JSON content in '" .. dataPage .. "'!"
    end

    local currentDate = os.date("!%Y-%m-%dT%H:%M:%S")

    local function isFutureElection(electionDate)
        local formattedElectionDate = mw.ustring.gsub(electionDate, "[-:T]", ""):sub(1, 14)
        local formattedCurrentDate = mw.ustring.gsub(currentDate, "[-:T]", ""):sub(1, 14)
        return formattedElectionDate > formattedCurrentDate
    end

    local allRows = {}
    for region, elections in pairs(APIData) do
        for _, election in ipairs(elections) do
            if isFutureElection(election.date) then
                table.insert(allRows, {
                    region_flag = '[[File:Flag of ' .. string.gsub(region, "_", " ") .. '.svg|100px]]',
                    region = '[[Elections in ' .. string.gsub(region, "_", " ") .. '|' .. string.gsub(region, "_", " ") .. ']]',
                    election_name = '[[' .. election.wiki_url .. '|' .. election.election_name .. ']]',
                    election_type = election.election_type,
                    date = string.sub(election.date, 1, 10),
                    description = election.description
                })
            end
        end
    end

    table.sort(allRows, function(a, b) return a.date < b.date end)

    local totalRows = #allRows
    local totalPages = math.ceil(totalRows / rowsPerPage)
    if currentPage > totalPages then currentPage = totalPages end
    if currentPage < 1 then currentPage = 1 end

    local startRow = (currentPage - 1) * rowsPerPage + 1
    local endRow = math.min(startRow + rowsPerPage - 1, totalRows)

    local html = mw.html.create("table"):addClass("wikitable sortable"):css("width", "100%")
    html:tag("tr")
        :tag("th"):wikitext("  "):done()
        :tag("th"):wikitext("Region"):done()
        :tag("th"):wikitext("Election Name"):done()
        :tag("th"):wikitext("Election Type"):done()
        :tag("th"):wikitext("Date"):done()
        :tag("th"):wikitext("Description"):done()

    for i = startRow, endRow do
        local row = allRows[i]
        html:tag("tr")
            :tag("td"):wikitext(row.region_flag):done()
            :tag("td"):wikitext(row.region):done()
            :tag("td"):wikitext(row.election_name):done()
            :tag("td"):wikitext(row.election_type):done()
            :tag("td"):wikitext(row.date):done()
            :tag("td"):wikitext(row.description):done()
    end

    return tostring(html)
end

return p