Module:Happenings

From Soyjak Wiki, the free ensoyclopedia
Jump to navigationJump to search
This module handles the Recent Events section on the main page! DO NOT EDIT THE CODE IF YOU DON'T KNOW WHAT YOU ARE DOING!


Along with transcluding entries on the main page, this module can be used for portals.

Usage

{{invoke:Happenings|main

|source=

|limit=

|month=

|order=

}}

Parameters

  • source - Page containing happenings entries. Required
  • limit - Maximum number of recent entries to display. Default is 5
  • month - Month from which entries are retrieved. Default is current, which automatically uses {{CURRENTMONTHNAME}}.
  • all - entries from every month, do not use this without good reason
  • order - Display order for selected recent entries. Default is newest, other option is oldest

some other stuff I don't have time to write now



local p = {}
local parser = require('Module:WikitextParser')
local monthsTable = {
	january = 'January',
	february = 'February',
	march = 'March',
	april = 'April',
	may = 'May',
	june = 'June',
	july = 'July',
	august = 'August',
	september = 'September',
	october = 'October',
	november = 'November',
	december = 'December',
}

local function makeError(message)
	return '<strong class="error">Happenings retrieve error: ' .. message .. '</strong>'
end
local function escapePattern(text)
	return text:gsub('([%^%$%(%)%%%.%[%]%*%+%-%?])', '%%%1')
end

local function removeRefs(text)
	for _, reference in ipairs(parser.getReferences(text)) do
		text = text:gsub(escapePattern(reference), '')
	end
	return text
end

function p.main(frame)
	local source = mw.text.trim(frame.args.source or '')
	local limit = tonumber(frame.args.limit) or 5
	local requestedMonth = mw.ustring.lower(mw.text.trim(frame.args.month or 'current'))
	local order = mw.ustring.lower(mw.text.trim(frame.args.order or 'newest'))
	local grace = tonumber(frame.args.grace) or 0
	if source == '' then return makeError('No source page specified') end
	if limit < 1 then return '' end
	if order ~= 'newest' and order ~= 'oldest' then return makeError('invalid order') end
	if grace < 0 then return makeError('invalid grace') end
	local title = mw.title.new(source)
	if not title then return makeError('invalid source page') end
	local content = title:getContent()
	if not content then return makeError('source page does not exist') end

	local monthFilter
	local gracePeriod
	local monthDisplay

	if requestedMonth == 'current' then
		monthDisplay = mw.text.trim(frame:preprocess('{{CURRENTMONTHNAME}}'))
		monthFilter = mw.ustring.lower(monthDisplay)
		if grace > 0 then
			local graceMonth = mw.ustring.lower(mw.getContentLanguage():formatDate('F', '-' .. grace .. 'days'))
			if graceMonth ~= monthFilter then gracePeriod = graceMonth end
		end
	elseif requestedMonth ~= 'all' then
		monthDisplay = monthsTable[requestedMonth]
		if not monthDisplay then return makeError('invalid month') end
		monthFilter = requestedMonth
	end
	local entries = {}

	for line in mw.text.gsplit(content, '\n', true) do
		local entryMonth = line:match('^%s*%*%s*([A-Z][a-z]+)%s+%d%d?%s*%-')
		if entryMonth then
			local normalizedMonth = mw.ustring.lower(entryMonth)
			if
				monthsTable[normalizedMonth]
				and (not monthFilter or normalizedMonth == monthFilter or normalizedMonth == gracePeriod)
			then
				entries[#entries + 1] = line
			end
		end
	end

	if #entries == 0 then
		if monthDisplay then return makeError('no entries found for ' .. monthDisplay) end
		return makeError('no entries found')
	end
	local output = {}
	local first = math.max(1, #entries - limit + 1)
	if order == 'newest' then
		for i = #entries, first, -1 do
			output[#output + 1] = entries[i]
		end
	else
		for i = first, #entries do
			output[#output + 1] = entries[i]
		end
	end

	local text = table.concat(output, '\n')
	text = removeRefs(text)
	return frame:preprocess(text)
end

return p