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 00:12, 20 March 2015 (fixes for Article.new, other tweaks). 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()
	return self.data.date
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

List.rowParams = {
	PAGE = 'getPage',
	DATE = 'getDate',
	TITLE = 'getTitle',
	SUBPAGE = 'getSubpage',
}

function List.new(args, index)
	local self = setmetatable({}, List)
	self.index = index or mw.loadData(INDEX_MODULE)
	self.rowtemplate = args.rowtemplate
	self.rowformat = args.rowformat
	
	-- Get article objects, filtered by page, date and tag.
	local articles = {}
	if args.page then
		local data = self.index.pages[args.page]
		if not data then
			error(string.format('[[%s]] is not an indexed Signpost article', 2))
		end
		articles[1] = Article.new(data)
	else
		local filtered
		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
			filtered = {}
			for page, data in pairs(pages) do
				table.insert(filtered, data)
			end
			table.sort(filtered, function(t1, t2)
				return t1.date < t2.date
			end)
		elseif #tags == 1 then
			filtered = self:getTagData(tags[1])
		else
			filtered = 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 filtered do
			if data.date >= startDate and data.date <= endDate then
				table.insert(articles, Article.new(data))
			end
		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, mw.ustring.lower(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