Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Labelled list hatnote

From Hacks Guide Wiki
This is the approved revision of this page, as well as being the most recent.

Documentation for this module may be created at Module:Labelled list hatnote/doc

--------------------------------------------------------------------------------
--                               Labelled list                                --
--                                                                            --
-- This module does the core work of creating a hatnote composed of a list    --
-- prefixed by a colon-terminated label, i.e. "LABEL: [andList of pages]",    --
-- for {{see also}} and similar templates.                                    --
--------------------------------------------------------------------------------

local mHatnote = require('Module:Hatnote')
local mHatlist = require('Module:Hatnote list')
local mArguments --initialize lazily
local yesno --initialize lazily
local p = {}

-- Defaults global to this module
local defaults = {
	label = 'See also', --Final fallback for label argument
	labelForm = '%s: %s',
	prefixes = {'label', 'label ', 'l'},
	template = 'Module:Labelled list hatnote'
}

-- Localizable message strings
local msg = {
	errorSuffix = '#Errors',
	noInputWarning = 'no page names specified',
	noOutputWarning =
		"'''[[%s]] — no output: none of the target pages exist.'''"
}

-- Helper function that pre-combines display parameters into page arguments.
-- Also compresses sparse arrays, as a desirable side-effect.
function p.preprocessDisplays (args, prefixes)
	-- Prefixes specify which parameters, in order, to check for display options
	-- They each have numbers auto-appended, e.g. 'label1', 'label 1', & 'l1'
	prefixes = prefixes or defaults.prefixes
	local indices = {}
	local sparsePages = {}
	for k, v in pairs(args) do
		if type(k) == 'number' then
			indices[#indices + 1] = k
			local display
			for i = 1, #prefixes do
				display = args[prefixes[i] .. k]
				if display then break end
			end
			sparsePages[k] = display and
				string.format('%s|%s', string.gsub(v, '|.*$', ''), display) or v
		end
	end
	table.sort(indices)
	local pages = {}
	for k, v in ipairs(indices) do pages[#pages + 1] = sparsePages[v] end
	return pages
end

--Helper function to get a page target from a processed page string
--e.g. "Page|Label" → "Page" or "Target" → "Target"
local function getTarget(pagename)
 	local pipe = string.find(pagename, '|')
	return string.sub(pagename, 0, pipe and pipe - 1 or nil)
end

-- Produces a labelled pages-list hatnote.
-- The main frame (template definition) takes 1 or 2 arguments, for a singular
-- and (optionally) plural label respectively:
-- * {{#invoke:Labelled list hatnote|labelledList|Singular label|Plural label}}
-- The resulting template takes pagename & label parameters normally.
function p.labelledList (frame)
	mArguments = require('Module:Arguments')
	yesno = require('Module:Yesno')
	local labels = {frame.args[1] or defaults.label}
	labels[2] = frame.args[2] or labels[1]
	labels[3] = frame.args[3] --no defaulting
	labels[4] = frame.args[4] --no defaulting
	local template = frame:getParent():getTitle()
	local args = mArguments.getArgs(frame, {parentOnly = true})
	local pages = p.preprocessDisplays(args)
	local options = {
		category = yesno(args.category),
		extraclasses = frame.args.extraclasses,
		ifexists = yesno(frame.args.ifexists),
		namespace = frame.args.namespace or args.namespace,
		selfref = yesno(frame.args.selfref or args.selfref),
		template = template
	}
	return p._labelledList(pages, labels, options)
end

function p._labelledList (pages, labels, options)
	if options.ifexists then
		for k = #pages, 1, -1 do --iterate backwards to allow smooth removals
			local v = pages[k]
			local title = mw.title.new(getTarget(v), namespace)
			if (v == '') or title == nil or not title.exists then
				table.remove(pages, k)
			end
		end
	end
	labels = labels or {}
	label = (#pages == 1 and labels[1] or labels[2]) or defaults.label
	for k, v in pairs(pages) do 
		if mHatnote.findNamespaceId(v) ~= 0 then
			label =
				(
					#pages == 1 and
					(labels[3] or labels[1] or defaults.label) or
					(labels[4] or labels[2] or defaults.label)
				) or defaults.label
		end
	end
	if #pages == 0 then
		if options.ifexists then
			mw.addWarning(
				string.format(
					msg.noOutputWarning, options.template or defaults.template
				)
			)
			return ''
		else
			return mHatnote.makeWikitextError(
				msg.noInputWarning,
				(options.template or defaults.template) .. msg.errorSuffix,
				options.category
			)
		end
	end
	local text = string.format(
		options.labelForm or defaults.labelForm,
		label,
		mHatlist.andList(pages, true)
	)
	local hnOptions = {
		extraclasses = options.extraclasses,
		selfref = options.selfref
	}
	return mHatnote._hatnote(text, hnOptions)
end

return p