Jump to content

Module:Signpost

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Mr. Stradivarius (talk | contribs) at 06:14, 19 March 2015 (start work on processing the index data). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local INDEX_MODULE = 'Module:Signpost/index'
local lang = mw.language.getContentLanguage()

--------------------------------------------------------------------------------
-- Article class
--------------------------------------------------------------------------------

local Article = {}
Article.__index = Article

function Article.new(data)
	local self = setmetatable({}, Article)
	self.data = data
	return self
end

function Article:getPage()
	return self.data.page
end

function Article:getDate(format)
	local date = self.data.date
	if format then
		return lang:formatDate(format, date)
	else
		return date
	end
end

function Article:getTitle()
	return self.data.title
end

function Article:getSubpage()
	return self.data.subpage
end

function Article:getTags()
	return self.data.tags
end

--------------------------------------------------------------------------------
-- List class
--------------------------------------------------------------------------------

local List = {}
List.__index = List

function List.new(args, index)
	local self = setmetatable({}, List)
	self.index = index or mw.loadData(INDEX_MODULE)
	local articles = {}
	if args.page then
		articles[1] = self.index.pages[args.page]
		if not articles[1] then
			error(string.format('[[%s]] is not an indexed Signpost article', 2))
		end
	else
		local unfiltered
		local tags = self.parseTagString(args.tags)
		if #tags > 1 then
			-- We need to check for duplicates.
			local pages = {}
			for i, tag in ipairs(tags) do
				for j, data in self:getTagData(tag) do
					pages[data.page] = data
				end
			end
			unfiltered = {}
			for page, data in pairs(pages) do
				table.insert(unfiltered, data)
			end
		elseif #tags == 1 then
			unfiltered = self:getTagData(tags[1])
		else
			unfiltered = self.index.dates
		end
		local startDate = self.normalizeDate(args.startdate) or '2005-01-01'
		local endDate = self.normalizeDate(args.enddate) or lang:formatDate('Y-m-d')
		for i, data in unfiltered do
			if data.date >= startDate and data.date <= endDate then
				table.insert(articles, data)
			end
		end
		table.sort(articles, function(t1, t2)
			return t1.date < t2.date
		end)
	end
	self.articles = articles
	return self
end

-- Static methods

function List.parseTagString(s)
	if not s then
		return {}
	end
	local tags = mw.text.split(s, '%s*,%s')
	local ret = {}
	for i, tag in ipairs(tags) do
		if tag ~= '' then
			table.insert(ret, tag)
		end
	end
	return ret
end

function List.normalizeDate(date)
	if not date then
		return nil
	end
	return lang:formatDate('Y-m-d', date)
end

-- Normal methods

function List:getTagData(tag)
	local data = self.index.tags[tag]
	if not data then
		error(string.format("'%s' is not a valid tag", tag), 2)
	end
end

--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------

local p = {}

function p._tag(tag)
	local data = mw.loadData(INDEX_MODULE)
	if not tag then
		return nil
	end
	local articles = data.tags[tag]
	if not articles then
		return nil
	end
	local ret = {}
	ret[#ret + 1] = '<ul>'
	for i, t in ipairs(articles) do
		ret[#ret + 1] = string.format(
			'<li>%s, %s: [[%s|%s]]</li>',
			t.date, t.subpage, t.page, t.title
		)
	end
	ret[#ret + 1] = '</ul>'
	return table.concat(ret, '\n')
end

function p.tag(frame)
	local tag = frame.args[1]
	return p._tag(tag)
end

return p