Create a new article
Write your page title here:
We currently have 230 articles on Farthest Frontier. Type your article name above or create one of the articles listed here!

    Farthest Frontier

    Module:Labelled list hatnote

    This module provides a handful of functions that make it easy to implement hatnotes that take the form of a label in front of a list of pages, e.g.

    LABEL: A, B, and C



    Invoking the labelledList() function is enough to implement most such templates:

    {{#invoke:Labelled list hatnote|labelledList|Universal label}}


    {{#invoke:Labelled list hatnote|labelledList|Singular label|Plural label}}

    For example, providing "See also" instead of "Universal label" duplicates the functionality of {{see also}}, while providing "Main article" and "Main articles" instead of "Singular label" and "Plural label" duplicates the (article namespace) functionality of {{main}}.

    If third and fourth labels are provided, they'll be used in the case where any of the target pages are outside the article namespace, so e.g. {{main}} can be implemented thus:

    {{#invoke:Labelled list hatnote|labelledList|Main article|Main articles|Main page|Main pages}}


    The preprocessDisplays() function takes a raw list of arguments and combines in any display arguments. For example, {{see also|1|l1=One}} initially has the arguments table {'1', ['l1'] = 'One'}; this table would combine those into the table {'1|One'}. It overrides manual piping (e.g. {{see also|1{{!}}2|l1=One}}{'1|One'}) and compresses sparse arrays if a parameter is skipped or left empty.


    local mLabelledList = require('Module:Labelled list hatnote')
    local pages = mLabelledList.preprocessDisplays(args)


    For modules that need to modify the functionality slightly while still using it, _labelledList() provides some flexibility. It takes three parameters:

    1. A pages list, preferably preprocessed and compressed by preprocessDisplays
    2. A labels table, where the first item is the singular or universal label, and the second either a plural label or a copy of the first.
    3. An options table, preferably containing:
      • a template string with the full title of the template. Defaults to the title of this module.
      • a category string (or nil) as taken by makeWikitextError from Module:Hatnote, to optionally disable error categories
      • a selfref string (or nil) as taken by _hatnote to enable the selfref option


    local mLabelledList = require('Module:Labelled list hatnote')
    return mLabelledList._labelledList(pages, labels, options)


    This module causes templates based on it to produce an error message if no page names are provided as template parameters. Normally, these should lead back to "Errors" sections in the documentation of those templates. However, if those templates use a module with _labelledList() and don't provide a template item in their options table, that error defaults to leading back here. The error can be solved by providing at least one valid page-name parameter to the template in question; the problem in the template can be fixed by providing some value to the template item of the _labelledList() options table.

    --                               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
    			sparsePages[k] = display and
    				string.format('%s|%s', string.gsub(v, '|.*$', ''), display) or v
    	local pages = {}
    	for k, v in ipairs(indices) do pages[#pages + 1] = sparsePages[v] end
    	return pages
    --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)
    -- 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)
    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)
    	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
    	if #pages == 0 then
    		if options.ifexists then
    					msg.noOutputWarning, options.template or defaults.template
    			return ''
    			return mHatnote.makeWikitextError(
    				(options.template or defaults.template) .. msg.errorSuffix,
    	local text = string.format(
    		options.labelForm or defaults.labelForm,
    		mHatlist.andList(pages, true)
    	local hnOptions = {
    		extraclasses = options.extraclasses,
    		selfref = options.selfref
    	return mHatnote._hatnote(text, hnOptions)
    return p
    Cookies help us deliver our services. By using our services, you agree to our use of cookies.
    Cookies help us deliver our services. By using our services, you agree to our use of cookies.