Lua error in Module:Lua_banner at line 115: attempt to compare nil with number.

This module implements {{Old XfD multi}}. This template is for listing the results of one or more deletion discussions of articles (or other pages) on talk pages. This template is fully compatible with the options of the old Template:Oldafdfull, which now redirects here, allowing additions when more AfD discussions have taken place.

Usage

{{Old XfD multi
<!-- 1st -->
|date     = 
|result   = 
|page     = 
|link     = 
|caption  = 
<!-- 2nd -->
|date2    = 
|result2  = 
|page2    = 
|link2    = 
|caption2 = 
<!-- ...  -->
<!-- behavior -->
|small    = <!-- yes/no -->
|collapse = <!-- yes/no/a number value -->
|numbered = <!-- yes/no -->
|type     = <!-- article, template, file, essay, etc. -->
|deletion = <!-- deletion, merging, renaming etc. -->
}}

Parameters

  • date, date2, date3...: Date of nomination, required for listing except for date.
  • result, result2, result3...: Result of AfD, default value is keep.
  • page, page2, page3...: Link to discussion page (defaults to "{{PAGENAME}}" for the first listing, page). If the value is in the article namespace, then it is prefixed by "Wikipedia:Articles for deletion/".
  • votepage, votepage2, votepage3...: Alias for page, needed for compatibility with entries that previously used {{Old VfD}}
  • link, link2, link3...: Alternative to "page". The link should be to a full URL of the discussion, although you may use the {{canonicalurl:}} magic word.
  • merge, merge2, merge3...: Used with merges
  • caption, caption2, caption3...: This defines the caption for the link to the discussion, default is "discussion", mainly useful when linking to other discussions than AfD.
  • small: The option "small = yes" will generate a smaller, right-aligned version without image.
  • collapse: Specifies the number of AfDs that show up collapsed by default, counted from the oldest nomination (date). Alternatively, "collapse = yes" will collapse the entire list by default.
  • numbered: When "numbered = yes" is included, the listed nominations will be numbered, starting with "1." for the first nomination. Using this option is encouraged when collapsing a part of the list by default.
  • type: Use this when using the template for listing other discussions than main space articles. This setting defines the word to replace the word "page" in the first sentence in the box, for example "template", "category" etc...
  • deletion: Replaces the word deletion in the top line of the template.

Numbered options are for the subsequent AfDs, starting with the oldest. Please note that specifying the date is required and specifying the page is highly encouraged. Without date the AfD is not listed and without page, there is no link to the discussion. For reasons of compatibility with {{Oldafdfull}}, date and page are not required for the first AfD and votepage is allowed instead of page.

Examples

Single AfD

{{Old XfD multi
|date   = January 1, 2001
|result = '''keep'''
|page   = Example
}}

Four AfDs, 2 collapsed, numbered

{{Old XfD multi
|date     = January 1, 2001
|result   = '''Keep'''
|page     = One
|date2    = February 2, 2002
|result2  = '''No consensus'''
|page2    = One (2nd nomination)
|date3    = March 3, 2003
|result3  = '''Delete'''
|page3    = One (3rd nomination)
|date4    = April 4, 2004
|result4  = '''Delete'''
|page4    = One (4th nomination)
|collapse = 2
|numbered = yes
}}

Four AfDs, all collapsed, 1 external link, small version

{{Old XfD multi
|date     = January 1, 2001
|result   = '''Keep'''
|page     = One
|date2    = February 2, 2002
|result2  = '''No consensus'''
|page2    = One (2nd nomination)
|date3    = March 3, 2003
|result3  = '''Delete'''
|page3    = One (3rd nomination)
|date4    = April 4, 2004
|result4  = '''Endorse deletion'''
|link4    = http://en.wikipedia.org/wiki/Wikipedia:Deletion_review/Log/2007_February#Deleted_article
|caption4 = DRV
|small    = yes
|collapse = yes
}}

Two TfDs

{{Old XfD multi
|date    = January 1, 2001
|result  = '''Keep'''
|page    = Wikipedia:Templates for deletion/Log/Not deleted/December 2005#Template:oldafdmulti
|date2   = February 2, 2002
|result2 = '''No consensus'''
|page2   = Wikipedia:Templates for deletion/Log/Not deleted/December 2005#Template:oldafdmulti
|type    = template
}}

Tracking category

See also


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 'Talk:' .. 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 == 'Elite Dangerous Wiki:Articles for deletion' then
			return page
		else
			return 'Talk:' .. page
		end
	else return nil
	end
end

local function makeWikilink(page, display)
	display = display or 'discussion'
	return string.format('[[%s|%s]]', page, display)
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',
		['elite dangerous wiki'] = 'project page',
		['mediawiki'] = 'interface page',
		['help'] = 'help page'
	}
	if pageTypes[display] then display = pageTypes[display] 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.rowData[num] = self.rowData[num] or {}
					self.rowData[num][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.rowData[1] then
		self.rowData[1].result = self.rowData[1].result or args.result
		self.rowData[1].date = self.rowData[1].date or args.date
		self.rowData[1].page = self.rowData[1].page or args.page
		self.rowData[1].votepage = self.rowData[1].votepage or args.votepage
		self.rowData[1].link = self.rowData[1].link or args.link
		self.rowData[1].caption = self.rowData[1].caption or args.caption
		self.rowData[1].merge = self.rowData[1].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.rowData[1] = {
			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
			ret[i] = t[num]
		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%')
		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(self[method](self, data))
	end

	-- Render normal rows
	if hasNormalRows then
		local normalList = makeList(false)
		while i > 1 and i > nCollapsedRows do
			renderRow(normalList, 'renderSubsequentRow', self.rowData[i])
			i = i - 1
		end
		if i == 1 and i > nCollapsedRows then
			renderRow(normalList, 'renderFirstRow', self.rowData[i])
			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.rowData[i])
			i = i - 1
		end
		renderRow(collapsedList, 'renderFirstRow', self.rowData[i])
	end

	return tostring(root)
end

function OldAfdMulti:renderFirstRowOnly()
	local data = self.rowData[1] or {}
	local caption = data.caption or "the discussion"
	local bold = "'''"
	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 = bold .. makeWikilink(getAfdPage(page), caption) .. bold
		elseif exists(getVfdPage(page)) then
			link = bold .. makeWikilink(getVfdPage(page), caption) .. bold
		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.rowData[1].date then
			ret[#ret + 1] = string.format(
				'This %s was previously nominated for %s.',
				self.pageType,
				self.deletion
			)
		elseif nRows == 1 and self.rowData[1].date then
			ret[#ret + 1] = string.format(
				'This %s was nominated for %s on %s.',
				self.pageType,
				self.deletion,
				self.rowData[1].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.rowData[1].date then
			ret[#ret + 1] = string.format(
				'This %s was considered for [[Project:Deletion policy#Merging|merging]] with %s.',
				self.pageType,
				self.rowData[1].merge
			)
		elseif nRows == 1 and self.rowData[1].date then
			ret[#ret + 1] = string.format(
				'This %s was considered for [[Project:Deletion policy#Merging|merging]] with [[:%s]] on %s.',
				self.pageType,
				self.rowData[1].merge,
				self.rowData[1].date
			)
		else
			ret[#ret + 1] = string.format(
				'This %s was nominated for [[Project:Deletion policy|deletion]] or considered for [[Project:Deletion policy#Merging|merging]].',
				self.pageType
			)
		end
	else
		if nRows < 1 or not self.rowData[1].date then
			ret[#ret + 1] = string.format(
				'This %s was previously nominated for [[Project:Deletion policy|deletion]].',
				self.pageType
			)
		elseif nRows == 1 and self.rowData[1].date then
			ret[#ret + 1] = string.format(
				'This %s was nominated for [[Project:Deletion policy|deletion]] on %s.',
				self.pageType,
				self.rowData[1].date
			)
		else
			ret[#ret + 1] = string.format(
				'This %s was nominated for [[Project: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 renomination.'
		else
			ret[#ret + 1] = 'Please review prior discussions if you are considering renomination.'
		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