Jump to content

Module:Current events calendar with day links

From Wikipedia, the free encyclopedia

-- This module renders the calendars seen on [[Portal:Current events/Calendars]].
-- The code is based on [[Module:Current events calendar]].

--[[
	Incoming expected variables:
		frame.args.year = Integer value for year
		frame.args.month = Integer value for month, 1 based.
--]]

local p = {}

local function makeWikilink(link, display)
	if display then
		return string.format('[[%s|%s]]', link, display)
	else
		return string.format('[[%s]]', link)
	end
end

local function getDateStuff(argsDate)

--[[
	Note: This function takes advantage of the formatDate's second argument to
	create data for the archival calendars. If the second arg (argsDate) is nil,
	then formatDate assumes the current date/time.
--]]

	-- Gets date data.
	local dateStuff = {}
	local lang = mw.language.getContentLanguage()
	dateStuff.argsDate = argsDate
	--Year
	local year = lang:formatDate('Y', argsDate)
	year = tonumber(year)
	dateStuff.year = year
	-- Month
	local month = lang:formatDate('F', argsDate)
	dateStuff.month = month
	-- Month and year
	local monthAndYear = lang:formatDate('F Y', argsDate)
	local firstOfMonth = lang:formatDate('01-m-Y', argsDate)
	dateStuff.monthAndYear = monthAndYear
	-- Previous month and year
	dateStuff.previousMonthAndYear = lang:formatDate('F Y', firstOfMonth .. ' -1 month')
	-- Next month and year
	dateStuff.nextMonthAndYear = lang:formatDate('F Y', firstOfMonth .. ' +1 month')
	-- Day
	local day = lang:formatDate('j', argsDate)
	day = tonumber(day)
	dateStuff.day = day
	-- Days in month
	local daysInMonth = lang:formatDate('j', firstOfMonth .. ' +1 month -1 day')
	daysInMonth = tonumber(daysInMonth)
	dateStuff.daysInMonth = daysInMonth
	-- Weekday of the first day of the month
	local firstWeekday = lang:formatDate('w', firstOfMonth) -- Sunday = 0, Saturday = 6
	firstWeekday = tonumber(firstWeekday)
	firstWeekday = firstWeekday + 1 -- Make compatible with Lua tables. Sunday = 1, Saturday = 7.
	dateStuff.firstWeekday = firstWeekday
	return dateStuff
end

local function makeDayStrings(dateStuff)
	local format = string.format
	local calStrings = {}
	local currentDay = dateStuff.day
	local currentMonth = dateStuff.month
	local currentYear = dateStuff.year
	for day = 1, dateStuff.daysInMonth do
		table.insert(calStrings, format(
			"[[Portal:Current events/%d %s %d| %d ]]",
			currentYear,
			currentMonth,
			day,
			day
		))
	end
	return calStrings
end

local function export(dayStrings, dateStuff)
	-- Generates the calendar HTML.
	local monthAndYear = dateStuff.monthAndYear
	local root = mw.html.create('table')
	root
		:addClass('current-events-calendar-days')

		-- Headings
		:tag('caption')
			:wikitext(makeWikilink('Portal:Current events/' .. monthAndYear, monthAndYear))
			:done()

	-- Day of week headings
	local dayHeadingRow = root:tag('tr')
	local weekdays = {'S', 'M', 'T', 'W', 'T', 'F', 'S'}
	for i, weekday in ipairs(weekdays) do
		dayHeadingRow:tag('th')
			:wikitext(weekday)
	end

	-- Days
	local cellCount = 1 - dateStuff.firstWeekday -- Tracks the number of day cells. Negative values used for initial blank cells.
	while cellCount < #dayStrings do -- Weekly rows
		local weeklyRow = root:tag('tr')
		for i = 1, 7 do -- Always make 7 cells.
			cellCount = cellCount + 1
			local dayString = dayStrings[cellCount] or '' -- Use a blank cell if there is no corresponding dateString
			weeklyRow:tag('td')
				:wikitext(dayString)
		end
	end

	return mw.getCurrentFrame():extensionTag{
		name = 'templatestyles',
		args = { src = 'Module:Current events calendar with day links/styles.css' }
	} .. tostring(root)
end

function p.main(frame)
	local argsDate = nil
	if (frame and frame.args and frame.args.year and frame.args.month) then
		-- If a date is passed in, assume that the display page is an Archive page.
		-- If no date passed in, assume that the display page is the current Current Events page
		argsDate = frame.args.year .. "-" .. frame.args.month .. "-01" -- Construct a date, YYY-M-DD format.
	end
	local dateStuff = getDateStuff(argsDate)
	local dayStrings = makeDayStrings(dateStuff)
	return export(dayStrings, dateStuff)
end

return p