Module:Calendar
From Angelina Jordan Wiki
Documentation for this module may be created at Module:Calendar/doc
local p = {}
local function trim(s)
if not s then return nil end
return (tostring(s):gsub("^%s*(.-)%s*$", "%1"))
end
local function escAttr(s)
if not s then return "" end
return tostring(s):gsub("&","&"):gsub('"',"""):gsub("<","<"):gsub(">",">")
end
function p.month(frame)
local args = frame.args or (frame.getParent and frame:getParent().args) or {}
local year = tonumber(trim(args.year))
local month = tonumber(trim(args.month))
if not year or not month then
return "Error: module requires numeric |year= and |month=."
end
if month < 1 or month > 12 then
return "Error: |month must be between 1 and 12."
end
local tableName = trim(args.table) or "DatedEvents"
local dateField = trim(args.datefield) or "Date"
local urlField = trim(args.urlfield) or "Link"
local daysInMonth = tonumber(os.date("*t", os.time{year=year, month=month+1, day=0}).day)
local firstWday = tonumber(os.date("*t", os.time{year=year, month=month, day=1}).wday) -- correct ordering
-- query Cargo (if available)
local function extractDay(dateStr)
if not dateStr then return nil end
local y, m, d = tostring(dateStr):match("^(%d%d%d%d)%-(%d%d)%-(%d%d)")
if d then return tonumber(d) end
return nil
end
local events = {}
if mw and mw.ext and mw.ext.cargo and mw.ext.cargo.query then
local startDate = string.format("%04d-%02d-01", year, month)
local endDate = string.format("%04d-%02d-%02d", year, month, daysInMonth)
local where = string.format("%s >= '%s' AND %s <= '%s'", dateField, startDate, dateField, endDate)
local ok, results = pcall(mw.ext.cargo.query, tableName, dateField .. "," .. urlField, { where = where, limit = 1000 })
if ok and results then
for _, row in ipairs(results) do
local dateVal = row[dateField] or row[1]
local linkVal = row[urlField] or row[2]
local di = extractDay(dateVal)
if di and linkVal then
events[di] = events[di] or {}
-- table.insert(events[di], tostring(linkVal))
table.insert(out, string.format("|- \n| %s || %s", dateVal or "nil", linkVal or "nil")) end
end
end
end
-- build calendar rows safely (cells per row)
local out = {}
table.insert(out, '{| class="wikitable calendar" style="text-align:center;"')
table.insert(out, '!Sun !!Mon !!Tue !!Wed !!Thu !!Fri !!Sat')
local day = 1
while day <= daysInMonth do
local cells = {}
for col = 1, 7 do
if day == 1 and col < firstWday then
table.insert(cells, " ")
elseif day <= daysInMonth then
if events[day] and #events[day] > 0 then
local firstLink = events[day][1]
local tip = escAttr(table.concat(events[day], ", "))
-- put attributes before the cell content
table.insert(cells, string.format('style="color:red;" | [[%s|%d]]', firstLink, day))
else
table.insert(cells, tostring(day))
end
day = day + 1
else
table.insert(cells, " ")
end
end
table.insert(out, "|-")
table.insert(out, "| " .. table.concat(cells, " || "))
end
table.insert(out, "|}")
return table.concat(out, "\n")
end
return p