Jump to content

Module:Current events calendar

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Mr. Stradivarius (talk | contribs) at 14:58, 3 February 2014 (reorganise the loop by rows... but it still doesn't work). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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

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

function p.main()
	local dateStuff = p.getDateStuff()
	local dayStrings = p.makeDayStrings(dateStuff)
	return p.export(dayStrings, dateStuff)
end

function p.getDateStuff()
	-- Gets date data.
	local dateStuff = {}
	local lang = mw.language.getContentLanguage()
	--Year
	local year = lang:formatDate('Y')
	year = tonumber(year)
	dateStuff.year = year
	-- Month
	local month = lang:formatDate('F')
	dateStuff.month = month
	-- Month and year
	local monthAndYear = lang:formatDate('F Y')
	dateStuff.monthAndYear = monthAndYear
	-- Previous month and year
	dateStuff.previousMonthAndYear = lang:formatDate('F Y', monthAndYear .. ' -1 month')
	-- Next month and year
	dateStuff.nextMonthAndYear = lang:formatDate('F Y', monthAndYear .. ' +1 month')
	-- Day
	local day = lang:formatDate('j')
	day = tonumber(day)
	dateStuff.day = day
	-- Days in month
	local firstOfMonth = string.format('1 %s %d', month, year)
	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

function p.makeDayStrings(dateStuff)
	local calStrings = {}
	local currentDay = dateStuff.day
	local isLinkworthy = p.isLinkworthy
	local currentMonth = dateStuff.month
	local currentYear = dateStuff.year
	local makeDayLink = p.makeDayLink
	for day = 1, dateStuff.daysInMonth do
		if isLinkworthy(day, currentDay) then
			calStrings[#calStrings + 1] = makeDayLink(day, currentMonth, currentYear)
		else
			calStrings[#calStrings + 1] = tostring(day)
		end
	end
	return calStrings
end

function p.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.
	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|%d]]'''", year, month, day, day)
end

function p.export(dayStrings, dateStuff)
	-- Generates the calendar HTML.
	local monthAndYear = dateStuff.monthAndYear
	local root = mw.html.create('table')
	root
		:addClass('infobox')
		:css{width = '250px', ['text-align'] = 'center', ['background-color'] = '#f5faff', border = '1px solid #cedff2'}
		
		-- Headings
		:tag('tr')
			:css('background-color', '#cedff2')
			:tag('td')
				:css{['padding-top'] = '1px', ['padding-bottom'] = '3px'}
				:wikitext(makeWikilink(dateStuff.previousMonthAndYear, '<<'))
				:done()
			:tag('td')
				:attr('colspan', '5')
				:css{padding = '1px 4px', ['font-weight'] = 'bold'}
				:wikitext(makeWikilink(monthAndYear))
				:done()
			:tag('td')
				:css{['padding-top'] = '1px', ['padding-bottom'] = '3px'}
				:wikitext(makeWikilink(dateStuff.nextMonthAndYear, '>>'))
				:done()
			:done()

		-- Day of week headings
		:tag('tr')
			local weekdays = {'S', 'M', 'T', 'W', 'T', 'F', 'S'}
			for i, weekday in ipairs(weekdays) do
				root:tag('td')
					:wikitext(weekday)
					:done()
			end
			root:done()
		
		-- Days
		local colspan = dateStuff.firstWeekday - 1
		local cellCount = 0 -- Tracks the number of day cells.
		root:tag('tr')
			if colspan > 1 then
				root:tag('td')
					:attr('colspan', tostring(colspan))
					:done()
			elseif colspan == 1 then
				root:tag('td')
					done()
			end
			for i = colspan + 1, 7 do -- Finish the first row
				cellCount = cellCount + 1
				root:tag('td')
					:wikitext(dayStrings[cellCount])
					:done()
			end
			root:done()
		while cellCount <= #dayStrings do -- Second day row onwards
			root:tag('tr')
				for i = 1, 7 do
					cellCount = cellCount + 1
					local dayString = dayStrings[cellCount]
					if not dayString then
						break
					end
					root:tag('td')
						:wikitext(dayString)
						:done()
				end
				root:done()
		end

		-- Footer
		root:tag('tr')
			:tag('td')
				:attr('colspan', '7')
				:css{['padding-top'] = '3px', ['padding-bottom'] = '5px', ['font-size'] = '78%', ['text-align'] = 'left'}
				:wikitext('&nbsp;&nbsp; ' .. makeWikilink(monthAndYear, 'More ' .. monthAndYear .. ' events...'))
	
	return tostring(root)
end

return p