{{i}} Документація модуля[перегляд] [редагувати] [історія] [очистити кеш]

This is a meta-module that provides various functions for making hatnotes. It implements the {{hatnote}} template, for use in hatnotes at the top of pages, and the {{format link}} template, which is used to format a wikilink for use in hatnotes. It also contains a number of helper functions for use in other Lua hatnote modules.

Use from wikitext

The functions in this module cannot be used directly from #invoke, and must be used through templates instead. Please see Template:Hatnote and Template:Format link for documentation.

Use from other Lua modules

To load this module from another Lua module, use the following code.

local mHatnote = require('Module:Hatnote')

You can then use the functions as documented below.


mHatnote._hatnote(s, options)

Formats the string s as a hatnote. This encloses s in the tags <div class="hatnote">...</div>. Options are provided in the options table. Options include:

  • options.extraclasses - a string of extra classes to provide
  • options.selfref - if this is not nil or false, adds the class "selfref", used to denote self-references to Wikipedia (see Template:Selfref))

The CSS of the hatnote class is defined in MediaWiki:Common.css.

Example 1
mHatnote._hatnote('This is a hatnote.')

Produces: <div class="hatnote">This is a hatnote.</div>

Displays as:

Example 2
mHatnote._hatnote('This is a hatnote.', {extraclasses = 'boilerplate seealso', selfref = true})

Produces: <div class="hatnote boilerplate seealso selfref">This is a hatnote.</div>

Displayed as:

Format link

mHatnote._formatLink(link, display)

Formats link as a wikilink for display in hatnote templates, with optional display value display. Categories and files are automatically escaped with the colon trick, and links to sections are automatically formatted as page § section, rather than the MediaWiki default of page#section.

mHatnote._formatLink('Лев') → [[Lion]] → Помилка скрипту: Функції «formatLink» не існує.
mHatnote._formatLink('Лев#Етимологія') → [[Lion#Etymology|Lion § Etymology]] → Помилка скрипту: Функції «formatLink» не існує.
mHatnote._formatLink('Категорія:Леви') → [[:Category:Lions]] → Помилка скрипту: Функції «formatLink» не існує.
mHatnote._formatLink('Лев#Етимологія', 'Етимологія левів') → [[Лев#Етимологія|Етимологія левів]] → Помилка скрипту: Функції «formatLink» не існує.

Форматовані сторінки


Formats a list of pages using the _formatLink function, and returns the result as an array. For example, the code mHatnote.formatPages('Lion', 'Category:Lions', 'Lion#Etymology') would produce an array like {'[[Lion]]', '[[:Category:Lions]]', '[[Lion#Etymology|Lion § Etymology]]'}.

Format page tables


Takes a list of page/display tables, formats them with the _formatLink function, and returns the result as an array. Each item in the list must be a table. The first value in the table is the link, and is required. The second value in the table is the display value, and is optional. For example, the code mHatnote.formatPages({'Lion', 'the Lion article'}, {'Category:Lions'}, {'Lion#Etymology', 'the etymology of lion'}) would produce an array like {'[[Lion|the Lion article]]', '[[:Category:Lions]]', '[[Lion#Etymology|the etymology of lion]]'}.

Find namespace id

mHatnote.findNamespaceId(link, removeColon)

Finds the namespace id of the string link, which should be a valid page name, with or without the section name. This function will not work if the page name is enclosed with square brackets. When trying to parse the namespace name, colons are removed from the start of the link by default. This is helpful if users have specified colons when they are not strictly necessary. If you do not need to check for initial colons, set removeColon to false.

mHatnote.findNamespaceId('Lion') → 0
mHatnote.findNamespaceId('Category:Lions') → 14
mHatnote.findNamespaceId(':Category:Lions') → 14
mHatnote.findNamespaceId(':Category:Lions', false) → 0 (the namespace is detected as ":Category", rather than "Category")

Make wikitext error

mHatnote.makeWikitextError(msg, helpLink, addTrackingCategory)

Formats the string msg as a red wikitext error message, with optional link to a help page helpLink. Normally this function also adds Category:Hatnote templates with errors; however, if addTrackingCategory is not false after being passed through Module:Yesno, then the category is suppressed. This means that the category can be suppressed with addTrackingCategory values including "no", "n", 0, "false", and false.


mHatnote.makeWikitextError('an error has occurred')Error: an error has occurred.
mHatnote.makeWikitextError('an error has occurred', 'Template:Example#Errors')Error: an error has occurred (help).


For examples of how this module is used in other Lua modules, see the following (listed in order of complexity):

WP-TranslationProject TwoFlags.svg

Цей модуль містить код, запозичений з модуля «Hatnote» англійської Вікіпедії.

local get_args = require('Module:Arguments').getArgs
local mError
local yesno = function (v) return require('Module:Yesno')(v, true) end

local p, tr = {}, {}
local current_title = mw.title.getCurrentTitle()
local tracking_categories = {
	no_prefix = 'Вікіпедія:Сторінки з модулем Hatnote без вказання префікса',
	no_links = 'Вікіпедія:Сторінки з модулем Hatnote без посилань',
	red_link = 'Вікіпедія:Сторінки з модулем Hatnote з червоним посиланням',
	bad_format = 'Вікіпедія:Сторінки з модулем Hatnote з некорректно заповненними параметрами',
	unparsable_link = 'Вікіпедія:Сторінки з модулем Hatnote з посиланням, що не читається',
	formatted = 'Вікіпедія:Сторінки з модулем Hatnote з готовим форматуваннням',

local function index(t1, t2)
	return setmetatable(t1, {__index = t2})

local function concat(e1, e2) 
	return tostring(e1) .. tostring(e2)

function tr.define_categories(tracked_cases)
	local categories = setmetatable({}, {
		__tostring = function (self) return table.concat(self) end, 
		__concat = concat

	function categories:add(element, nocat)
		if not nocat then
			local cat_name
			if tracked_cases and tracked_cases[element] then
				cat_name = tracked_cases[element]
				cat_name = element
			table.insert(self, string.format('[[Категорія:%s]]', cat_name))
	return categories

function tr.error(msg, categories, preview_only)
	local current_frame = mw.getCurrentFrame()
	local parent_frame = current_frame:getParent()
	local res_frame_title = parent_frame and parent_frame:getTitle() ~= current_title.prefixedText and
		parent_frame:getTitle() or
	if not preview_only or current_frame:preprocess('{{REVISIONID}}') == '' then
		mError = require('Module:Error')
		return mError.error{
			tag = 'div',
			string.format('Помилка в [[%s]]: %s.' 
				.. (preview_only and '<br><small>Це повідомлення показується тільки під час попереднього перегляду.</small>' or ''), res_frame_title, msg)
		} .. categories
		return categories

function p.parse_link(frame)
	local args = get_args(frame)
	local link = args[1]:gsub('\n', '')
	local label
	link = mw.text.trim(link:match('^%[%[([^%]]+)%]%]$') or link)
	if link:sub(1, 1) == '/' then
		label = link
		link = current_title.prefixedText .. link
	link = link:match(':?(.+)')
	if link:match('|') then
		link, label = link:match('^([^%|]+)%|(.+)$')
	if not mw.title.new(link) then
		return nil, nil
	return link, label

function p.format_link(frame)
	-- {{посилання на розділ}}
	local args = get_args(frame)
	local link, section, label = args[1], args[2], args[3]
	if not link then
		link = current_title.prefixedText
		if section then
			link = '#' .. section
			label = label or '§&nbsp;' .. section
		local parsed_link, parsed_label = p.parse_link{link}
		if parsed_link then
			link = parsed_link
			return link
		if section and not link:match('#') then
			link = link .. '#' .. section
			if parsed_label then
				parsed_label = parsed_label .. '#' .. section
		label = (label or parsed_label or link):gsub('^([^#]-)#(.+)$', '%1 §&nbsp;%2')
	if label and label ~= link then
		return string.format('[[:%s|%s]]', link, label)
		return string.format('[[:%s]]', link)

function p.remove_precision(frame)
	-- {{без уточнення}}
	local args = get_args(frame)
	local title = args[1]
	return title:match('^(.+)%s+%b()$') or title

function p.is_disambig(frame)
	local args = get_args(frame)
	local title = args[1]
	local page = mw.title.new(title)
	if not page or not page.exists or mw.title.equals(page, current_title) then
		return false
	local page_content = page:getContent()
	local mw_list_content = mw.title.new('MediaWiki:Disambiguationspage'):getContent()
	local lang = mw.language.getContentLanguage()
	for template in mw.ustring.gmatch(mw_list_content, '%*%s?%[%[Шаблон:([^%]]+)') do
		if page_content:match('{{' .. template) or page_content:match('{{' .. lang:lcfirst(template)) then 
			return true
	return false

function p.list(frame)
	local args = get_args(frame, {trim = false})
	local list_sep = args.list_sep or args['роздільник списку'] or ', '
	local last_list_sep = yesno(args.natural_join) ~= false and ' і ' or list_sep
	local links_ns = args.links_ns or args['ПІ посилань']
	local bold_links = yesno(args.bold_links or args['посилання болдом'])

	local res_list = {}
	local tracked = {
		red_link = false,
		bad_format = false,
		formatted = false,
		unparsable_link = false
	local i = 1
	while args[i] do
		local link = args[i]
		local label = args['l' .. i]
		local element = ''
		if link:match('<span') then -- TODO: переписати
			tracked.formatted = true
			element = link -- for {{не перекладено}}
			local bad_format = (link:match('|') or link:match('[%[%]]')) ~= nil
			local parsed_link, parsed_label = p.parse_link{link}
			if parsed_link then
				tracked.bad_format = tracked.bad_format or bad_format
				if links_ns then
					parsed_label = parsed_label or parsed_link
					parsed_link = mw.site.namespaces[links_ns].name .. ':' .. parsed_link
				local title = mw.title.new(parsed_link)
				tracked.red_link = tracked.red_link or not (title.isExternal or title.exists)
				element = p.format_link{parsed_link, nil, label or parsed_label}
				tracked.unparsable_link = true
				element = link
		if bold_links then
			element = string.format('<b>%s</b>', element)
		table.insert(res_list, element)
		i = i + 1
	return setmetatable(res_list, {
		__index = tracked,
		__tostring = function (self) return mw.text.listToText(self, list_sep, last_list_sep) end,
		__concat = concat,
		__pairs = function (self) return pairs(tracked) end

function p.hatnote(frame)
	local args = get_args(frame)
	local text = args[1]
	local id = args.id
	local extraclasses = args.extraclasses
	local hide_disambig = yesno(args.hide_disambig)
	local res = mw.html.create('div')
		:attr('id', id)
	if hide_disambig then
	return res

function p.main(frame, _tracking_categories)
	local args = get_args(frame, {trim = false})
	local prefix = args.prefix or args['префікс']
	local prefix_plural = args.prefix_plural or args['префікс множини']
	local sep = args.sep or args['роздільник'] or ' '
	local dot = yesno(args.dot or args['крапка']) and '.' or ''
	local nocat = yesno(args.nocat)
	local preview_error = yesno(args.preview_error)
	local empty_list_message = args.empty_list_message or 'Не вказано жодної сторінки'
	categories = tr.define_categories(index(_tracking_categories or {}, tracking_categories))

	if not prefix then
		categories:add('no_prefix', nocat)
		return tr.error('Не вказано префікс', categories)
	if not args[1] then
		categories:add('no_links', nocat)
		return tr.error(empty_list_message, categories, preview_error)
	if args[2] and prefix_plural then
		prefix = prefix_plural
	local list = p.list(args)
	for k, v in pairs(list) do
		if type(v) == 'boolean' and v then
			categories:add(k, nocat)
	return p.hatnote(index({prefix .. sep .. list .. dot}, args)) .. categories

return index(p, tr)