Module:CurrentEventsCalendar: Difference between revisions
From Landrace.Wiki - The Landrace Cannabis Wiki
More actions
Eloise Zomia (talk | contribs) Created page with "local p = {} local function pad2(n) n = tonumber(n) or 0 if n < 10 then return "0" .. tostring(n) end return tostring(n) end local function ymd(y, m, d) return string.format("%04d-%02d-%02d", y, m, d) end local function month_name(m) local names = { "January","February","March","April","May","June", "July","August","September","October","November","December" } return names[m] or tostring(m) end local function days_in_month(y, m) local t = os.t..." |
Eloise Zomia (talk | contribs) No edit summary |
||
| Line 42: | Line 42: | ||
end | end | ||
local function get_today( | local function get_today() | ||
local | local t = os.date("*t") | ||
local | return t.year, t.month, t.day | ||
end | |||
local function smw_available() | |||
return mw and mw.smw and type(mw.smw.ask) == "function" | |||
end | end | ||
local function collect_event_days(y, m, category) | local function collect_event_days(y, m, category) | ||
local days = {} | |||
if not smw_available() then | |||
return days | |||
end | |||
local start = ymd(y, m, 1) | local start = ymd(y, m, 1) | ||
local ny, nm = next_month(y, m) | local ny, nm = next_month(y, m) | ||
| Line 63: | Line 71: | ||
local res = mw.smw.ask(query) or {} | local res = mw.smw.ask(query) or {} | ||
for _, row in ipairs(res) do | for _, row in ipairs(res) do | ||
local po = row.printouts or {} | local po = row.printouts or {} | ||
local vals = po.eventdate or {} | local vals = po.eventdate or {} | ||
for _, v in ipairs(vals) do | for _, v in ipairs(vals) do | ||
-- SMW date values may come through as strings or tables depending on config | |||
local s = v | local s = v | ||
if type(v) == "table" | if type(v) == "table" then | ||
if v.value then s = v.value | |||
elseif v.raw then s = v.raw | |||
elseif v.timestamp then | |||
-- timestamp is usually in seconds | |||
s = os.date("%Y-%m-%d", tonumber(v.timestamp)) | |||
end | |||
end | |||
if type(s) == "string" then | if type(s) == "string" then | ||
local yy, mm, dd = s:match("^(%d%d%d%d)%-(%d%d)%-(%d%d)") | local yy, mm, dd = s:match("^(%d%d%d%d)%-(%d%d)%-(%d%d)") | ||
| Line 86: | Line 103: | ||
function p.render(frame) | function p.render(frame) | ||
local args = frame.args or {} | local args = frame.args or {} | ||
local y = tonumber(args.year) or | |||
local m = tonumber(args.month) or | local nowY, nowM, nowD = get_today() | ||
local y = tonumber(args.year) or nowY | |||
local m = tonumber(args.month) or nowM | |||
local base = args.base or "Portal:Current_Events/Archive" | local base = args.base or "Portal:Current_Events/Archive" | ||
local category = args.category or "News Item" | local category = args.category or "News Item" | ||
| Line 94: | Line 115: | ||
local ny, nm = next_month(y, m) | local ny, nm = next_month(y, m) | ||
local firstWday = weekday_of_first(y, m) -- 1..7 (Sun..Sat) | local firstWday = weekday_of_first(y, m) -- 1..7 (Sun..Sat) | ||
local dim = days_in_month(y, m) | local dim = days_in_month(y, m) | ||
| Line 130: | Line 150: | ||
for d = 1, dim do | for d = 1, dim do | ||
local cell = grid:tag("div"):addClass("calendar-day") | local cell = grid:tag("div"):addClass("calendar-day") | ||
if hasEvents[d] then cell:addClass("has-events") end | if hasEvents[d] then cell:addClass("has-events") end | ||
if y == | if y == nowY and m == nowM and d == nowD then cell:addClass("today") end | ||
local link = string.format("[[%s/%04d/%02d/%02d|%d]]", base, y, m, d, d) | local link = string.format("[[%s/%04d/%02d/%02d|%d]]", base, y, m, d, d) | ||
Revision as of 08:15, 16 January 2026
Documentation for this module may be created at Module:CurrentEventsCalendar/doc
local p = {}
local function pad2(n)
n = tonumber(n) or 0
if n < 10 then return "0" .. tostring(n) end
return tostring(n)
end
local function ymd(y, m, d)
return string.format("%04d-%02d-%02d", y, m, d)
end
local function month_name(m)
local names = {
"January","February","March","April","May","June",
"July","August","September","October","November","December"
}
return names[m] or tostring(m)
end
local function days_in_month(y, m)
local t = os.time({ year = y, month = m + 1, day = 0 })
return tonumber(os.date("%d", t))
end
local function weekday_of_first(y, m)
local t = os.time({ year = y, month = m, day = 1 })
-- Lua: 1=Sunday .. 7=Saturday
return tonumber(os.date("*t", t).wday)
end
local function next_month(y, m)
m = m + 1
if m == 13 then return y + 1, 1 end
return y, m
end
local function prev_month(y, m)
m = m - 1
if m == 0 then return y - 1, 12 end
return y, m
end
local function get_today()
local t = os.date("*t")
return t.year, t.month, t.day
end
local function smw_available()
return mw and mw.smw and type(mw.smw.ask) == "function"
end
local function collect_event_days(y, m, category)
local days = {}
if not smw_available() then
return days
end
local start = ymd(y, m, 1)
local ny, nm = next_month(y, m)
local finish = ymd(ny, nm, 1)
local query = {
string.format("[[Category:%s]]", category),
string.format("[[Has event date::>=%s]]", start),
string.format("[[Has event date::<%s]]", finish),
"?Has event date=eventdate",
"limit=500"
}
local res = mw.smw.ask(query) or {}
for _, row in ipairs(res) do
local po = row.printouts or {}
local vals = po.eventdate or {}
for _, v in ipairs(vals) do
-- SMW date values may come through as strings or tables depending on config
local s = v
if type(v) == "table" then
if v.value then s = v.value
elseif v.raw then s = v.raw
elseif v.timestamp then
-- timestamp is usually in seconds
s = os.date("%Y-%m-%d", tonumber(v.timestamp))
end
end
if type(s) == "string" then
local yy, mm, dd = s:match("^(%d%d%d%d)%-(%d%d)%-(%d%d)")
if yy and mm and dd then
local daynum = tonumber(dd)
if daynum then days[daynum] = true end
end
end
end
end
return days
end
function p.render(frame)
local args = frame.args or {}
local nowY, nowM, nowD = get_today()
local y = tonumber(args.year) or nowY
local m = tonumber(args.month) or nowM
local base = args.base or "Portal:Current_Events/Archive"
local category = args.category or "News Item"
local py, pm = prev_month(y, m)
local ny, nm = next_month(y, m)
local firstWday = weekday_of_first(y, m) -- 1..7 (Sun..Sat)
local dim = days_in_month(y, m)
local hasEvents = collect_event_days(y, m, category)
local html = mw.html.create("div"):addClass("portal-events-calendar")
local nav = mw.html.create("div"):addClass("calendar-month-nav")
nav:tag("span")
:addClass("calendar-nav-link")
:wikitext(string.format("[[%s_%04d-%02d|‹ %s]]", base, py, pm, month_name(pm)))
nav:tag("span")
:addClass("calendar-current-month")
:wikitext(string.format("%s %04d", month_name(m), y))
nav:tag("span")
:addClass("calendar-nav-link")
:wikitext(string.format("[[%s_%04d-%02d|%s ›]]", base, ny, nm, month_name(nm)))
html:node(nav)
local headers = mw.html.create("div"):addClass("calendar-week-headers")
local names = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}
for i = 1, 7 do
headers:tag("div"):addClass("calendar-weekday"):wikitext(names[i])
end
html:node(headers)
local grid = mw.html.create("div"):addClass("calendar-month-grid")
local leading = firstWday - 1
for _ = 1, leading do
grid:tag("div"):addClass("calendar-day"):addClass("empty")
end
for d = 1, dim do
local cell = grid:tag("div"):addClass("calendar-day")
if hasEvents[d] then cell:addClass("has-events") end
if y == nowY and m == nowM and d == nowD then cell:addClass("today") end
local link = string.format("[[%s/%04d/%02d/%02d|%d]]", base, y, m, d, d)
cell:wikitext(link)
end
html:node(grid)
return tostring(html)
end
return p