Module:Redirect hatnote: Difference between revisions

From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Content added Content deleted
(Updated module from sandbox with support for multiple redirect arguments.)
(Added hack to categorize pages using odd edge-case behaviour)
Line 107: Line 107:
pages[1] = pages[1] or redirect .. ' (disambiguation)'
pages[1] = pages[1] or redirect .. ' (disambiguation)'
else
else
pages[1] = pages[1] or useTable.use .. ' (disambiguation)'
--pages[1] = pages[1] or useTable.use .. ' (disambiguation)'
--Terrible but temporary hack switches above line to below if to test prevalence of this behaviour:
if not pages[1] then
pages[1] = useTable.use .. ' (disambiguation)'
use = use .. '[[Category:Hatnote templates using unusual parameters]]'
end
end
end
pages = mHatnote.formatPages(unpack(pages))
pages = mHatnote.formatPages(unpack(pages))

Revision as of 18:38, April 12, 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 used to apply special formatting for the first
	-- table in the data array. If isFirst is specified, the redirect parameter
	useTable = useTable or {}
	local use
	if isFirst then
		use = useTable.use or 'other uses'
	elseif not useTable.use then
		return nil
	elseif tonumber(useTable.use) == 1 then
		use = 'other uses'
	else
		use = useTable.use
	end
	local pages = useTable.pages or {}
	if isFirst then
		redirect = redirect[1] or error(
			'isFirst was set in formatUseTable, but no redirect was supplied',
			2
		)
		pages[1] = pages[1] or redirect .. ' (disambiguation)'
	else
		--pages[1] = pages[1] or useTable.use .. ' (disambiguation)'
		--Terrible but temporary hack switches above line to below if to test prevalence of this behaviour:
		if not pages[1] then
			pages[1] = useTable.use .. ' (disambiguation)'
			use = use .. '[[Category:Hatnote templates using unusual parameters]]'
		end
	end
	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 and data[1].use ~= 'other uses' then
		for i = 2, #data do
			text[#text + 1] = formatUseTable(data[i] or {}, false)
		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