Module:OpenHistoricalMap/Events

From OpenStreetMap Wiki
Jump to navigation Jump to search

local p = {}
local languages = require("Module:Languages")
local characterTools = require("Module:Char")
local events = mw.loadJsonData("Module:OpenHistoricalMap/Events/data.json")

function p.main(frame)
	local title = mw.title.getCurrentTitle()
	local lang = mw.getLanguage(languages.languageFromTitle(title))
	local langCode = lang:getCode()
	-- MediaWiki abnormally lowercases ISO 3166 and ISO 15924 codes in locales.
	langCode = langCode:gsub("-(%w%w%w%w)", function (script)
		return "-" .. script:sub(1, 1):upper() .. script:sub(2)
	end):gsub("-(%w%w)$", function (country)
		return "-" .. country:upper()
	end)
	
	local dateFormat = frame.args.date_format and #frame.args.date_format > 0 and frame.args.date_format or "F j, Y"
	local historical = frame.args.historical == "yes"

	local sortedEvents = events
	if not historical then
		-- Clone the read-only JSON data in order to manipulate it; mw.clone() requires write permissions.
		sortedEvents = mw.text.jsonDecode(mw.text.jsonEncode(sortedEvents))
		-- Sort the data chronologically.
		table.sort(sortedEvents, function (a, b)
			return a.start_date < b.start_date
		end)
	end
	
	local today = lang:formatDate("c"):match("(.+)T")
	local list = mw.html.create("dl")
	for i, event in ipairs(sortedEvents) do
		-- Omit past events.
		if historical or event.end_date >= today then
			local dateRange = lang:formatDate(dateFormat, event.start_date)
			if event.end_date and event.end_date > event.start_date then
				-- TODO: Make the range format localizable.
				-- TODO: Optimize the range format for ranges within the same year.
				dateRange = dateRange .. " – " .. lang:formatDate(dateFormat, event.end_date)
			end
			list:tag("dt")
				:wikitext(dateRange)
			list:tag("dd")
				:wikitext(frame:preprocess(event.description[langCode] or event.description.en))
		end
	end
	
	return list
end

function p.bycountry(frame)
	local countsByCountry = {}
	for i, event in ipairs(events) do
		local country = event.country
		countsByCountry[country] = (countsByCountry[country] or 0) + 1
	end
	local counts = {}
	for country, count in pairs(countsByCountry) do
		table.insert(counts, {
			country = country,
			count = count,
		})
	end
	table.sort(counts, function (a, b)
		if a.count == b.count then return a.country < b.country end
		return a.count > b.count
	end)
	
	local countryTable = mw.html.create("table"):attr("class", "wikitable sortable")
	local header = countryTable:tag("tr")
	header:tag("th"):wikitext("Country")
	header:tag("th"):wikitext("Events")
	for i, entry in pairs(counts) do
		local row = countryTable:tag("tr")
		local flag = characterTools.flag(frame:newChild {
			args = { entry.country },
		})
		row:tag("td"):wikitext(flag .. " " .. entry.country)
		row:tag("td"):attr("align", "right"):wikitext(entry.count)
	end
	return countryTable
end

return p