Module:Current events calendar

-- This module renders the calendar seen on [[Portal:Current events]].

--[[
	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.
--]]

	local lang = mw.language.getContentLanguage()
	local firstOfMonth = lang:formatDate('01-m-Y', argsDate)
	return {
		argsDate = argsDate,
		year = tonumber(lang:formatDate('Y', argsDate)),
		month = lang:formatDate('F', argsDate),
		monthAndYear = lang:formatDate('F Y', argsDate),
		previousMonthAndYear = lang:formatDate('F Y', firstOfMonth .. ' -1 month'),
		nextMonthAndYear = lang:formatDate('F Y', firstOfMonth .. ' +1 month'),
		day = tonumber(lang:formatDate('j', argsDate)),
		daysInMonth = tonumber(lang:formatDate('j', firstOfMonth .. ' +1 month -1 day')),
		-- Weekday of the first day of the month
		-- Make compatible with Lua tables so we add 1. Sunday = 1, Saturday = 7.
		firstWeekday = tonumber(lang:formatDate('w', firstOfMonth)) + 1
	}
end

local function isLinkworthy(day, currentDay)
	-- Returns true if the calendar day should be linked, and false if not. Days
	-- should be linked if they are the current day or if they are within the six
	-- preceding days, as that is the number of items on the current events page.
	return currentDay - 6 <= day and day <= currentDay
end

local function makeDayStrings(dateStuff)
	local calStrings = {}
	local currentDay = dateStuff.day
	local currentMonth = dateStuff.month
	local currentYear = dateStuff.year
	for day = 1, dateStuff.daysInMonth do
		if dateStuff.argsDate or isLinkworthy(day, currentDay) then
			table.insert(calStrings, string.format(
				"[[#%d %s %d|%d]]",
				currentYear,
				currentMonth,
				day,
				day
			))
		else
			table.insert(calStrings, tostring(day))
		end
	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')
		-- Make the table-layout-based Archive pages look good. When the Archives
		-- have been converted to a grid-based layout, this logic can be removed,
		-- and the corressponding CSS margin attribute can be simplified.
		:addClass(dateStuff.argsDate and 'current-events-calendar-archive')
		-- Headings
		:tag('caption')
			:tag('span')
				:addClass('noprint')
				:wikitext(makeWikilink(
					'Portal:Current events/' .. dateStuff.previousMonthAndYear,
					'◀'
				))
				:done()
			:tag('span')
				:wikitext(makeWikilink(
					'Portal:Current events/' .. monthAndYear,
					monthAndYear
				))
				:done()
			:tag('span')
				:addClass('noprint')
				:wikitext(makeWikilink(
					'Portal:Current events/' .. dateStuff.nextMonthAndYear,
					'▶'
				))

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

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

	-- Footer
	if not dateStuff.argsDate then -- No footer necessary on Archive pages.
		root:tag('tr')
			:addClass('current-events-calendar-footer')
		    :addClass('noprint')
			:tag('td')
				:attr('colspan', '7')
				:wikitext(makeWikilink(
					'Portal:Current events/' .. monthAndYear,
					'More ' .. monthAndYear .. ' events...&nbsp;&nbsp;&nbsp;'
				))
	end
	
	return 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
		-- Construct a date, YYY-M-DD format.
		argsDate = frame.args.year .. "-" .. frame.args.month .. "-01"
	end
	local dateStuff = getDateStuff(argsDate)
	return frame:extensionTag{
		name = 'templatestyles',
		args = { src = 'Module:Current events calendar/styles.css' }
	} .. export(makeDayStrings(dateStuff), dateStuff)
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.