Module:Labelled list hatnote: Difference between revisions

From Xomnipedia
Jump to navigation Jump to search
Content added Content deleted
(Enhanced with the ability to vary the label based on the namespace(s) of the target page(s), from sandbox)
m (1 revision imported from wikipedia:Module:Labelled_list_hatnote)
 
(3 intermediate revisions by 3 users not shown)
Line 10: Line 10:
local mHatlist = require('Module:Hatnote list')
local mHatlist = require('Module:Hatnote list')
local mArguments --initialize lazily
local mArguments --initialize lazily
local yesno --initialize lazily
local p = {}
local p = {}


Line 18: Line 19:
prefixes = {'label', 'label ', 'l'},
prefixes = {'label', 'label ', 'l'},
template = 'Module:Labelled list hatnote'
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.'''"
}
}


Line 26: Line 35:
-- They each have numbers auto-appended, e.g. 'label1', 'label 1', & 'l1'
-- They each have numbers auto-appended, e.g. 'label1', 'label 1', & 'l1'
prefixes = prefixes or defaults.prefixes
prefixes = prefixes or defaults.prefixes
local pages = {}
local indices = {}
local sparsePages = {}
for k, v in pairs(args) do
for k, v in pairs(args) do
if type(k) == 'number' then
if type(k) == 'number' then
indices[#indices + 1] = k
local display
local display
for i = 1, #prefixes do
for i = 1, #prefixes do
Line 34: Line 45:
if display then break end
if display then break end
end
end
local page = display and
sparsePages[k] = display and
string.format('%s|%s', string.gsub(v, '|.*$', ''), display) or v
string.format('%s|%s', string.gsub(v, '|.*$', ''), display) or v
pages[#pages + 1] = page
end
end
end
end
table.sort(indices)
local pages = {}
for k, v in ipairs(indices) do pages[#pages + 1] = sparsePages[v] end
return pages
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
end


Line 49: Line 69:
function p.labelledList (frame)
function p.labelledList (frame)
mArguments = require('Module:Arguments')
mArguments = require('Module:Arguments')
yesno = require('Module:Yesno')
local labels = {frame.args[1] or defaults.label}
local labels = {frame.args[1] or defaults.label}
labels[2] = frame.args[2] or labels[1]
labels[2] = frame.args[2] or labels[1]
Line 57: Line 78:
local pages = p.preprocessDisplays(args)
local pages = p.preprocessDisplays(args)
local options = {
local options = {
category = yesno(args.category),
extraclasses = frame.args.extraclasses,
extraclasses = frame.args.extraclasses,
category = args.category,
ifexists = yesno(frame.args.ifexists),
selfref = frame.args.selfref or args.selfref,
namespace = frame.args.namespace or args.namespace,
selfref = yesno(frame.args.selfref or args.selfref),
template = template
template = template
}
}
Line 66: Line 89:


function p._labelledList (pages, labels, options)
function p._labelledList (pages, labels, options)
if options.ifexists then
labels = labels or {}
for k = #pages, 1, -1 do --iterate backwards to allow smooth removals
if #pages == 0 then
local v = pages[k]
return mHatnote.makeWikitextError(
local title = mw.title.new(getTarget(v), namespace)
'no page names specified',
if (v == '') or title == nil or not title.exists then
(options.template or defaults.template) .. '#Errors',
table.remove(pages, k)
options.category
)
end
end
end
end
labels = labels or {}
label = (#pages == 1 and labels[1] or labels[2]) or defaults.label
label = (#pages == 1 and labels[1] or labels[2]) or defaults.label
for k, v in pairs(pages) do
for k, v in pairs(pages) do
Line 83: Line 108:
(labels[4] or labels[2] or defaults.label)
(labels[4] or labels[2] or defaults.label)
) 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
end
end

Latest revision as of 02:36, 1 July 2022

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