Module:Redirect hatnote: Difference between revisions

From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Content added Content deleted
(Added category tracking for unusual early termination behaviour when first use is "other uses")
m (Tweaked last edit: didn't mean to catch pages where there's termination but no early termination)
Line 135: Line 135:
text[#text + 1] = formatUseTable(data[i] or {}, false, redirect)
text[#text + 1] = formatUseTable(data[i] or {}, false, redirect)
end
end
elseif #data > 1 then
else
text[#text] = text[#text] .. '[[Category:Hatnote templates using unusual parameters]]'
text[#text] = text[#text] .. '[[Category:Hatnote templates using unusual parameters]]'
end
end

Revision as of 15:34, April 19, 2016

This module produces a hatnote for disambiguating a page that is linked to by a given redirect. It implements the {{redirect}} hatnote template.

Usage from wikitext

This module cannot be used directly from wikitext. Please use the {{redirect}} or {{redirect2}} templates instead.

Usage from Lua

To use this module from Lua, first load the module.

local mRedirectHatnote = require('Module:Redirect hatnote')

The module can then be used with the following syntax:

mRedirectHatnote._redirect(redirect, data, options, titleObj)

See also


--[[
-- This module produces a "redirect" hatnote. It looks like this:
-- '"X" redirects here. For other uses, see Y.'
-- It implements the {{redirect}} template.
--]]

local mHatnote = require('Module:Hatnote')
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti

local p = {}

local function getTitle(...)
	local success, titleObj = pcall(mw.title.new, ...)
	if success then
		return titleObj
	else
		return nil
	end
end

function p.redirect(frame)
	-- Get the args table and work out the maximum arg key.
	local origArgs = frame:getParent().args
	local args = {}
	local maxArg = 0
	for k, v in pairs(origArgs) do
		if type(k) == 'number' and k > maxArg then
			maxArg = k
		end
		v = v:match('^%s*(.-)%s*$') -- Trim whitespace
		if v ~= '' then
			args[k] = v
		end
	end

	--Get table of redirects
	local numRedirects = tonumber(frame.args[1]) or 1
	local redirect = {}
	for i = 1, numRedirects do
		-- Return an error if no redirect was specified.
		if not args[i] then
			return mHatnote.makeWikitextError(
				'no redirect specified',
				'Template:Redirect#Errors',
				args.category
			)
		end
		redirect[i] = args[i]
	end


	-- Create the data table.
	local data = {}
	local iArg = numRedirects - 1
	local iData = 1
	repeat
		iArg = iArg + 2
		local useTable = data[iData] or {}
		local pages = useTable.pages or {}
		local use = args[iArg]
		local page = args[iArg + 1]
		local nextUse = args[iArg + 2]
		pages[#pages + 1] = page
		useTable.pages = pages
		if use ~= 'and' then
			useTable.use = use
		end
		data[iData] = useTable
		if nextUse ~= 'and' then
			iData = iData + 1
		end
	until iArg >= maxArg - 1

	-- Create the options table.
	local options = {}
	options.selfref = args.selfref
		
	return p._redirect(redirect, data, options)
end

local function formatUseTable(useTable, isFirst, redirect)
	-- Formats one use table. Use tables are the tables inside the data array.
	-- Each one corresponds to one use. (A use might be the word "cats" in the
	-- phrase "For cats, see [[Felines]]".)
	-- Returns a string, or nil if no use was specified.
	-- The isFirst parameter is legacy, but partly maintained for its effect of
	-- cancelling empty use items.
	useTable = useTable or {}
	local use
	if not (useTable.use or isFirst) then
		return nil
	end
	use = useTable.use or 'other uses'
	local pages = useTable.pages or {}
	redirect = redirect[1] or error(
		'no redirect was supplied',
		2
	)
	pages[1] = pages[1] or redirect .. ' (disambiguation)'
	pages = mHatnote.formatPages(unpack(pages))
	pages = mw.text.listToText(pages)
	return string.format(
		'For %s, see %s.',
		use,
		pages
	)
end

function p._redirect(redirect, data, options, currentTitle, redirectTitle, targetTitle)
	-- Validate the input. Don't bother checking currentTitle, redirectTitle or
	-- targetTitle, as they are only used in testing.
	checkTypeMulti('_redirect', 1, redirect, {'string', 'table'})
	-- String type can stay valid until extant use-cases are checked-for and
	-- updated, but we'll coerce them to table for now
	if type(redirect) == 'string' then redirect = {redirect} end
	checkType('_redirect', 2, data, 'table', true)
	checkType('_redirect', 3, options, 'table', true)
	data = data or {}
	options = options or {}
	currentTitle = currentTitle or mw.title.getCurrentTitle()

	-- Generate the text.
	local text = {}
	local formattedRedirect = {}
	for k,v in pairs(redirect) do
		formattedRedirect[k] = '"' .. v .. '"'
	end
	text[#text + 1] = mw.text.listToText(formattedRedirect) .. ' ' .. (#redirect == 1 and 'redirects' or 'redirect') .. ' here.'
	text[#text + 1] = formatUseTable(data[1] or {}, true, redirect)
	if data[1] and data[1].use then
		if data[1].use ~= 'other uses' then
			for i = 2, #data do
				text[#text + 1] = formatUseTable(data[i] or {}, false, redirect)
			end
		elseif #data > 1 then
			text[#text] = text[#text] .. '[[Category:Hatnote templates using unusual parameters]]'
		end
	end
	text = table.concat(text, ' ')
	
	local categoryTable = {}
	--add categories to a table by index, so we don't get duplicates
	function addCategory(cat)
		if cat and cat ~= '' then
			categoryTable[string.format('[[Category:%s]]', cat)] = true
		end
	end

	local mhOptions = {}
	for k,v in pairs(redirect) do
		-- Generate the tracking category.
		-- We don't need a tracking category if the template invocation has been
		-- copied directly from the docs, or if we aren't in main- or category-space.
		if not v:find('^REDIRECT%d*$') and v ~= 'TERM' -- 
			and currentTitle.namespace == 0 or currentTitle.namespace == 14
		then
			redirectTitle = redirectTitle or getTitle(v)
			if not redirectTitle or not redirectTitle.exists then
				addCategory('Missing redirects')
			elseif not redirectTitle.isRedirect then
				addCategory('Articles with redirect hatnotes needing review')
			else
				local mRedirect = require('Module:Redirect')
				local target = mRedirect.getTarget(redirectTitle)
				targetTitle = targetTitle or target and getTitle(target)
				if targetTitle and targetTitle ~= currentTitle then
					addCategory('Articles with redirect hatnotes needing review')
				end
			end
		end

		-- Generate the options to pass to [[Module:Hatnote]].
		if currentTitle.namespace == 0 and not mhOptions.selfref
			and redirectTitle and redirectTitle.namespace ~= 0
		then
			-- We are on a mainspace page, and the hatnote starts with something
			-- like "Wikipedia:Foo redirects here", so automatically label it as
			-- a self-reference.
			mhOptions.selfref = true
		else
			mhOptions.selfref = options.selfref
		end
	end
	--concatenate all the categories
	local category = ''
	for k,v in pairs(categoryTable) do
		category = category .. k
	end

	return mHatnote._hatnote(text, mhOptions) .. category
end
 
return p