Jump to content

Module:Current events calendar: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
noprint arrow links
templatestyles, some cleaning of styles and whatnot
 
Line 17: Line 17:
end
end


function p.main(frame)
local function getDateStuff(argsDate)
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 = p.getDateStuff(argsDate)
local dayStrings = p.makeDayStrings(dateStuff)
return p.export(dayStrings, dateStuff)
end

function p.getDateStuff(argsDate)

--[[
--[[
Note: This function takes advantage of the formatDate's second argument to
Note: This function takes advantage of the formatDate's second argument to
Line 37: Line 24:
--]]
--]]


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


function p.makeDayStrings(dateStuff)
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 calStrings = {}
local currentDay = dateStuff.day
local currentDay = dateStuff.day
local isLinkworthy = p.isLinkworthy
local currentMonth = dateStuff.month
local currentMonth = dateStuff.month
local currentYear = dateStuff.year
local currentYear = dateStuff.year
local makeDayLink = p.makeDayLink
for day = 1, dateStuff.daysInMonth do
for day = 1, dateStuff.daysInMonth do
if dateStuff.argsDate or isLinkworthy(day, currentDay) then
if dateStuff.argsDate or isLinkworthy(day, currentDay) then
table.insert(calStrings, string.format(
calStrings[#calStrings + 1] = makeDayLink(day, currentMonth, currentYear)
"[[#%d %s %d|%d]]",
currentYear,
currentMonth,
day,
day
))
else
else
calStrings[#calStrings + 1] = tostring(day)
table.insert(calStrings, tostring(day))
end
end
end
end
Line 89: Line 69:
end
end


function p.isLinkworthy(day, currentDay)
local function export(dayStrings, dateStuff)
-- 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.
if currentDay - 6 <= day and day <= currentDay then
return true
else
return false
end
end

function p.makeDayLink(day, month, year)
return string.format("'''[[#%d %s %d|&nbsp;&nbsp;%d&nbsp;&nbsp;]]'''", year, month, day, day)
end

function p.export(dayStrings, dateStuff)
-- Generates the calendar HTML.
-- Generates the calendar HTML.
local monthAndYear = dateStuff.monthAndYear
local monthAndYear = dateStuff.monthAndYear
local root = mw.html.create('table')
local root = mw.html.create('table')
-- The next two lines help to 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.
local temporaryMarginAdjustment = "auto !important"
if dateStuff.argsDate then temporaryMarginAdjustment = "8px 0 0 8px" end
root
root
:addClass('infobox')
:addClass('current-events-calendar')
-- Make the table-layout-based Archive pages look good. When the Archives
:css{
-- have been converted to a grid-based layout, this logic can be removed,
display = 'table',
-- and the corressponding CSS margin attribute can be simplified.
width = '100%',
:addClass(dateStuff.argsDate and 'current-events-calendar-archive')
float = 'initial',
['max-width'] = '350px',
margin = temporaryMarginAdjustment,
['text-align'] = 'center',
['background-color'] = '#f5faff',
border = '1px solid #cedff2'
}
-- Headings
-- Headings
:tag('tr')
:tag('caption')
:css('background-color', '#cedff2')
:tag('span')
:tag('th')
:addClass('noprint')
:wikitext(makeWikilink(
:css{['text-align'] = 'center'}
'Portal:Current events/' .. dateStuff.previousMonthAndYear,
:tag('span')
:addClass('noprint')
''
))
:wikitext(makeWikilink('Portal:Current events/' .. dateStuff.previousMonthAndYear, '◀'))
:done()
:done()
:done()
:tag('th')
:tag('span')
:wikitext(makeWikilink(
:attr('colspan', '5')
'Portal:Current events/' .. monthAndYear,
:css{['text-align'] = 'center'}
monthAndYear
:wikitext(makeWikilink('Portal:Current events/' .. monthAndYear, monthAndYear))
))
:done()
:done()
:tag('th')
:tag('span')
:addClass('noprint')
:css{['text-align'] = 'center'}
:wikitext(makeWikilink(
:tag('span')
'Portal:Current events/' .. dateStuff.nextMonthAndYear,
:addClass('noprint')
'▶'
:wikitext(makeWikilink('Portal:Current events/' .. dateStuff.nextMonthAndYear, '▶'))
))


-- Day of week headings
-- Day of week headings
local dayHeadingRow = root:tag('tr')
local dayHeadingRow = root:tag('tr')
local weekdays = {'S', 'M', 'T', 'W', 'T', 'F', 'S'}
local weekdays = {'S', 'M', 'T', 'W', 'T', 'F', 'S'}
for i, weekday in ipairs(weekdays) do
for _, weekday in ipairs(weekdays) do
dayHeadingRow:tag('th')
dayHeadingRow:tag('th'):wikitext(weekday)
:css{['width'] = '14%', ['text-align'] = 'center'}
:wikitext(weekday)
end
end


-- Days
-- Days
local cellCount = 1 - dateStuff.firstWeekday -- Tracks the number of day cells. Negative values used for initial blank cells.
-- Tracks the number of day cells. Negative values used for initial blank cells.
local cellCount = 1 - dateStuff.firstWeekday
while cellCount < #dayStrings do -- Weekly rows
while cellCount < #dayStrings do -- Weekly rows
local weeklyRow = root:tag('tr')
local weeklyRow = root:tag('tr')
for i = 1, 7 do -- Always make 7 cells.
for i = 1, 7 do -- Always make 7 cells.
cellCount = cellCount + 1
cellCount = cellCount + 1
local dayString = dayStrings[cellCount] or "&nbsp;" -- Use a blank cell if there is no corresponding dateString
-- Use a blank cell if there is no corresponding dateString
local dayString = dayStrings[cellCount] or ''
weeklyRow:tag('td')
weeklyRow:tag('td'):wikitext(dayString)
:css{['text-align'] = 'center'}
:wikitext(dayString)
end
end
end
end
Line 171: Line 124:
if not dateStuff.argsDate then -- No footer necessary on Archive pages.
if not dateStuff.argsDate then -- No footer necessary on Archive pages.
root:tag('tr')
root:tag('tr')
:addClass('current-events-calendar-footer')
:addClass('noprint')
:addClass('noprint')
:tag('td')
:tag('td')
:attr('colspan', '7')
:attr('colspan', '7')
:wikitext(makeWikilink(
:css{['padding-top'] = '3px', ['padding-bottom'] = '5px', ['font-size'] = '78%', ['text-align'] = 'right'}
:wikitext(makeWikilink('Portal:Current events/' .. monthAndYear, 'More ' .. monthAndYear .. ' events...&nbsp;&nbsp;&nbsp;'))
'Portal:Current events/' .. monthAndYear,
'More ' .. monthAndYear .. ' events...&nbsp;&nbsp;&nbsp;'
))
end
end
return tostring(root)
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
end



Latest revision as of 16:07, 2 November 2021

-- 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