Permanently protected module
From Wikipedia, the free encyclopedia


local yesno = require('Module:Yesno')

local mMessageBox = require('Module:Message box')

local TEMPLATE_PAGE = 'Template:Old XfD multi'



-------------------------------------------------------------------------------

-- Helper functions

-------------------------------------------------------------------------------



local function exists(page)

	local success, exists = pcall(function ()

		local title = mw.title.new(page)

		return title.exists

	end)

	return success and exists

end



local function getAfdPage(page)

	if page and mw.title.new(page) then

		if mw.title.new(page).namespace ~= 0 then

			return page

		else

			return 'Wikipedia:Articles for deletion/' .. page

		end

	else return nil

	end

end



local function getVfdPage(page)

	if page and mw.title.new(page) then

		if mw.title.new(page).rootPageTitle.fullText == 'Wikipedia:Votes for deletion' then

			return page

		else

			return 'Wikipedia:Votes for deletion/' .. page

		end

	else return nil

	end

end



local function makeWikilink(page, display)

	display = display or 'discussion'

	if page then

		return string.format('[[%s|%s]]', page, display)

	else

		return display --probably a bad title

	end

end



local function makeUrlLink(page, display)

	display = display or 'discussion'

	return string.format('[%s %s]', page, display)

end



local function pageTypeName(title)

	local display = mw.ustring.lower(title.subjectNsText)

	local pageTypes = {

		'' = 'article',

		'user' = 'user page',

		'wikipedia' = 'project page',

		'mediawiki' = 'interface page',

		'help' = 'help page'

	}

	if pageTypesdisplay then display = pageTypesdisplay end

	return display

end



local function cleanupTitle(title)

	if not title then return title end

	title = mw.uri.decode(title, 'PATH')

	title = string.gsub(title, '|.*', '')

	title = string.gsub(title, '[%[%]{}]', '')

	return title

end



-------------------------------------------------------------------------------

-- OldAfdMulti class

-------------------------------------------------------------------------------



local OldAfdMulti = {}

OldAfdMulti.__index = OldAfdMulti



function OldAfdMulti.new(args)

	local self = setmetatable({}, OldAfdMulti)

	self.currentTitle = mw.title.getCurrentTitle()



	-- Preprocess the row args for easier looping.

	self.rowData = {}

	for k, v in pairs(args) do

		if type(k) == 'string' then

			local prefix, num = k:match('^(.-)([1-9][0-9]*)$')

			if prefix and num then

				num = tonumber(num)

				if prefix == 'result' or

					prefix == 'date' or

					prefix == 'page' or

					prefix == 'link' or

					prefix == 'caption' or

					prefix == 'votepage' or

					prefix == 'merge'

				then

					self.rowDatanum = self.rowDatanum or {}

					self.rowDatanum][prefix = v

					if v and v ~= '' and prefix=='merge' then

						self.isMerge = true

					end

				end

			end

		end

	end

	-- Set aliases for parameters ending in "1".

	if self.rowData1 then

		self.rowData1].result = self.rowData1].result or args.result

		self.rowData1].date = self.rowData1].date or args.date

		self.rowData1].page = self.rowData1].page or args.page

		self.rowData1].votepage = self.rowData1].votepage or args.votepage

		self.rowData1].link = self.rowData1].link or args.link

		self.rowData1].caption = self.rowData1].caption or args.caption

		self.rowData1].merge = self.rowData1].merge or args.merge

	elseif args.result or

		args.date or

		args.page or

		args.votepage or

		args.link or

		args.caption or

		args.merge

	then

		self.rowData1 = {

			result = args.result,

			date = args.date,

			page = args.page,

			votepage = args.votepage,

			link = args.link,

			caption = args.caption,

			merge = args.merge

		}

	end

	-- Remove any gaps in the array we made.

	local function compressSparseArray(t)

		local ret, nums = {}, {}

		for num, data in pairs(t) do

			nums#nums + 1 = num

		end

		table.sort(nums)

		for i, num in ipairs(nums) do

			reti = tnum

		end

		return ret

	end

	self.rowData = compressSparseArray(self.rowData)

	-- Set aliases that apply to all of the data tables.

	for i, data in ipairs(self.rowData) do

		data.page = data.page or data.votepage

		data.page = cleanupTitle(data.page)

		data.votepage = nil

	end



	-- Set collapsedness

	self.collapse = tonumber(args.collapse)

	if not self.collapse then

		self.collapse = yesno(args.collapse)

	end



	-- Set other properties

	self.isNumbered = yesno(args.numbered)

	self.isSmall = yesno(args.small)

	self.pageType = args.type or pageTypeName(self.currentTitle)

	if args.merge and args.merge ~= '' then

		self.isMerge = true

	end

	self.deletion = args.deletion

	

	return self

end



function OldAfdMulti:renderResult(result)

	return result or "'''Keep'''"

end



function OldAfdMulti:renderDate(date)

	if date then

		return date

	else

		self.hasMissingDate = true

		return string.format(

			'<sup>%s[[%s|date missing]]%s</sup>',

			mw.text.nowiki('['),

			TEMPLATE_PAGE,

			mw.text.nowiki(']')

		)

	end

end



function OldAfdMulti:renderPageText(linkFunc, page, caption)

	return string.format(', see %s.', linkFunc(page, caption))

end



function OldAfdMulti:renderRow(result, date, link, merge)

	local result = self:renderResult(result)

	local date = self:renderDate(date)

	local mergeText = ''

	if merge and merge ~= '' then

		mergeText = string.format('Merge with [[:%s]]: ', merge)

	end

	if link then

		return string.format('%s%s, %s, see %s.', mergeText, result, date, link)

	else

		return string.format('%s%s, %s', mergeText, result, date)

	end

end



function OldAfdMulti:renderFirstRow(data)

	local link

	if data.link then

		link = makeUrlLink(data.link, data.caption)

	else

		local page = data.page or self.currentTitle.text

		link = makeWikilink(getAfdPage(page), data.caption)

	end

	return self:renderRow(data.result, data.date, link, data.merge)

end



function OldAfdMulti:renderSubsequentRow(data)

	local link

	if data.page then

		link = makeWikilink(getAfdPage(data.page), data.caption)

	elseif data.link then

		link = makeUrlLink(data.link, data.caption)

	end

	return self:renderRow(data.result, data.date, link, data.merge)

end



function OldAfdMulti:renderRows()

	local root = mw.html.create()

	local nRows = #self.rowData

	local i = nRows



	local nCollapsedRows

	if type(self.collapse) == 'number' then

		nCollapsedRows = self.collapse

	elseif self.collapse then

		nCollapsedRows = nRows

	else

		nCollapsedRows = 0

	end

	local hasNormalRows = nRows - nCollapsedRows > 0



	local function makeList(isCollapsed, header)

		local tableRoot = root:tag('table')

		tableRoot

			:addClass(isCollapsed and 'mw-collapsible mw-collapsed' or nil)

			:css('width', '100%')

			:css('background-color', '#f8eaba')

		if header then

			tableRoot

				:tag('tr')

					:tag('th')

						:wikitext(header)

		end

		return tableRoot

			:tag('tr')

				:tag('td')

					:tag(self.isNumbered and 'ol' or 'ul')

	end



	local function renderRow(html, method, data)

		html

			:tag('li')

				:attr('value', self.isNumbered and i or nil)

				:wikitext(selfmethod](self, data))

	end



	-- Render normal rows

	if hasNormalRows then

		local normalList = makeList(false)

		while i > 1 and i > nCollapsedRows do

			renderRow(normalList, 'renderSubsequentRow', self.rowDatai])

			i = i - 1

		end

		if i == 1 and i > nCollapsedRows then

			renderRow(normalList, 'renderFirstRow', self.rowDatai])

			i = i - 1

		end

	end



	-- Render collapsed rows

	if nCollapsedRows > 0 then

		local header

		if hasNormalRows then

			header = 'Older deletion discussions:'

		elseif nRows > 1 then

			header = 'Deletion discussions:'

		else

			header = 'Deletion discussion:'

		end

		local collapsedList = makeList(true, header)

		while i > 1 do

			renderRow(collapsedList, 'renderSubsequentRow', self.rowDatai])

			i = i - 1

		end

		renderRow(collapsedList, 'renderFirstRow', self.rowDatai])

	end



	return tostring(root)

end



function OldAfdMulti:renderFirstRowOnly()

	local data = self.rowData1 or {}

	local caption = data.caption or 'the discussion'

	local link

	if data.link then

		link = makeUrlLink(data.link, caption)

	else

		local page = data.page or self.currentTitle.text

		if exists(getAfdPage(page)) then

			link = makeWikilink(getAfdPage(page), caption)

		elseif exists(getVfdPage(page)) then

			link = makeWikilink(getVfdPage(page), caption)

		else

			link = caption -- Make this an error?

		end

	end

	local result = self:renderResult(data.result or "'''keep'''")

	return string.format(

		'The result of %s was %s.',

		link, result

	)

end



function OldAfdMulti:renderBannerText()

	local nRows = #self.rowData

	local ret = {}

	if self.deletion then

		if nRows < 1 or not self.rowData1].date then

			ret#ret + 1 = string.format(

				'This %s was previously nominated for %s.',

				self.pageType,

				self.deletion

			)

		elseif nRows == 1 and self.rowData1].date then

			ret#ret + 1 = string.format(

				'This %s was nominated for %s on %s.',

				self.pageType,

				self.deletion,

				self.rowData1].date

			)

		else

			ret#ret + 1 = string.format(

				'This %s was nominated for %s.',

				self.pageType,

				self.deletion

			)

		end

	elseif self.isMerge then

		if nRows < 1 or not self.rowData1].date then

			ret#ret + 1 = string.format(

				'This %s was considered for [[Wikipedia:Deletion policy#Merging|merging]] with %s.',

				self.pageType,

				self.rowData1].merge

			)

		elseif nRows == 1 and self.rowData1].date then

			ret#ret + 1 = string.format(

				'This %s was considered for [[Wikipedia:Deletion policy#Merging|merging]] with [[:%s]] on %s.',

				self.pageType,

				self.rowData1].merge,

				self.rowData1].date

			)

		else

			ret#ret + 1 = string.format(

				'This %s was nominated for [[Wikipedia:Deletion policy|deletion]] or considered for [[Wikipedia:Deletion policy#Merging|merging]].',

				self.pageType

			)

		end

	else

		if nRows < 1 or not self.rowData1].date then

			ret#ret + 1 = string.format(

				'This %s was previously nominated for [[Wikipedia:Deletion policy|deletion]].',

				self.pageType

			)

		elseif nRows == 1 and self.rowData1].date then

			ret#ret + 1 = string.format(

				'This %s was nominated for [[Wikipedia:Deletion policy|deletion]] on %s.',

				self.pageType,

				self.rowData1].date

			)

		else

			ret#ret + 1 = string.format(

				'This %s was nominated for [[Wikipedia:Deletion policy|deletion]].',

				self.pageType

			)

		end

	end

	

	if nRows > 1 then

		ret#ret + 1 = ' '

		if self.isSmall then

			ret#ret + 1 = 'Review prior discussions if considering re-nomination:'

		else

			ret#ret + 1 = 'Please review the prior discussions if you are considering re-nomination:'

		end

		ret#ret + 1 = '\n'

		ret#ret + 1 = self:renderRows()

	else

		ret#ret + 1 = ' '

		ret#ret + 1 = self:renderFirstRowOnly()

	end

	return table.concat(ret)

end



function OldAfdMulti:renderBanner()

	return mMessageBox.main('tmbox', {

		small = self.isSmall,

		type = 'notice',

		image = '[[File:Clipboard.svg|35px|Articles for deletion]]',

		smallimage = 'none',

		text = self:renderBannerText()

	})

end



function OldAfdMulti:renderTrackingCategories()

	local ret = {}

	if self.hasMissingDate and self.currentTitle.isTalkPage then

		ret#ret + 1 = '[[Category:Old XfD multi templates with errors]]'

	end

	return table.concat(ret)

end



function OldAfdMulti:__tostring()

	return self:renderBanner() .. self:renderTrackingCategories()

end



-------------------------------------------------------------------------------

-- Exports

-------------------------------------------------------------------------------



local p = {}



function p._main(args)

	local afd = OldAfdMulti.new(args)

	return tostring(afd)

end



function p.main(frame)

	local args = require('Module:Arguments').getArgs(frame, {

		wrappers = TEMPLATE_PAGE

	})

	return p._main(args)

end



return p