Zelda Wiki

Want to contribute to this wiki?
Sign up for an account, and get started!

Come join the Zelda Wiki community Discord server!

READ MORE

Zelda Wiki
Advertisement

This submodule provides utility functions for formatting text with wiki markup.

This module exports the following functions.

anchor

anchor(id, [display])

Parameters

Returns

  • A link that refers to itself. Useful for linking to specific sections of a page without necessarily using headings.

Examples

#InputOutputResultStatus
1
anchor("foo")
'<span id="foo">[[#foo|foo]]</span>'
foo
Green check
2
anchor("bar", "Bar")
'<span id="bar">[[#bar|Bar]]</span>'
Bar
Green check
3
anchor("foo bar")
'<span id="foo bar">[[#foo bar|foo bar]]</span>'
foo bar
Green check

category

category(name, [sortKey])

Parameters

  • name
    The name of the category to link to (with or without namespace prefix).
  • [sortKey]
    A custom sort key for the category entry.

Returns

  • A category link—the kind that adds a category to a page. For the other kind that links to the actual category page, use link.

Examples

#InputOutputStatus
Category link from category name
4
category("Items")
"[[Category:Items]]"
Green check
Category link from category name with namespace prefix
5
category("Category:Items")
"[[Category:Items]]"
Green check
Category link with sort key
6
category("Items", "*")
"[[Category:Items|*]]"
Green check

categories

categories(names)

Parameters

  • names
    An array of category names, with or without the namespace prefix.

Returns

  • A concatenated string of category links.

Examples

#InputOutputStatus
7
categories({"Link", "Category:Zelda", "Category:Ganon"})
"[[Category:Link]][[Category:Zelda]][[Category:Ganon]]"
Green check
8
categories({})
""
Green check

containsLink

containsLink(wikitext)

Returns

  • Given a string of wikitext, returns true if it contains an internal or interwiki link, false otherwise.

Examples

#InputOutputResult
9
containsLink("There is a [[Link]]")
true
Green check
10
containsLink("[Link] is not a link but rather an indication of replaced words in a quote.")
false
Green check

file

file(name, [options])

Parameters

Returns

  • A string of wikitext that renders a thumbnail for the file.

Examples

#InputOutputResultStatus
11
file("File:ALttP Ganon Sprite.png")
"[[File:ALttP Ganon Sprite.png]]"
ALttP Ganon Sprite
Green check
12
file(
  "ALttP Ganon Sprite.png",
  {
    caption = "Ganon",
    link = "",
  }
)
"[[File:ALttP Ganon Sprite.png|link=|Ganon]]"
Ganon
Green check
13
file(
  "File:TWW Great Fairy Figurine Model.png",
  {
    size = "100px",
    link = "Great Fairy",
  }
)
"[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy]]"
TWW Great Fairy Figurine Model
Green check
14
file(
  "File:TWW Great Fairy Figurine Model.png",
  {
    noBacklink = true,
    size = "100px",
    link = "Great Fairy",
  }
)
"[[File:TWW Great Fairy Figurine Model.png|100px|link=https://zelda.fandom.com/wiki/Great_Fairy]]"
TWW Great Fairy Figurine Model
Green check
15
file(
  "File:TWW Great Fairy Figurine Model.png",
  {
    class = "notpageimage",
    size = "100px",
    link = "Great Fairy",
  }
)
"[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy|class=notpageimage]]"
TWW Great Fairy Figurine Model
Green check

killBacklinks

killBacklinks(wikitext)

Parameters

Returns

  • The same wikitext but with all the internal links formatted as external links, to avoid additions to Special:WhatLinksHere.

Examples

#InputOutputResultStatus
Escapes basic article links - unfortunately non-existent pages are not rendered as red links for performance reasons
16
killBacklinks("[[Link]], [[Princess Zelda|Zelda]], and [[Jean-Guy Rubber Boots]]")
'<span class="plainlinks">[https://zelda.fandom.com/Link Link]</span>, <span class="plainlinks">[https://zelda.fandom.com/Princess_Zelda Zelda]</span>, and <span class="plainlinks">[https://zelda.fandom.com/Jean-Guy_Rubber_Boots Jean-Guy Rubber Boots]</span>'
Link, Zelda, and Jean-Guy Rubber Boots
Green check
Does not escape file links or category links
17
killBacklinks("[[Category:Link]] and [[File:SS Blessed Butterfly Icon.png]]")
"[[Category:Link]] and [[File:SS Blessed Butterfly Icon.png]]"
and SS Blessed Butterfly Icon
Green check
Escapes visible file and category links
18
killBacklinks("[[:Category:Link]], [[:Category:Princess Zelda|Zelda]], and [[:File:SS Blessed Butterfly Icon.png]]")
'<span class="plainlinks">[https://zelda.fandom.com/Category:Link Category:Link]</span>, <span class="plainlinks">[https://zelda.fandom.com/Category:Princess_Zelda Zelda]</span>, and <span class="plainlinks">[https://zelda.fandom.com/File:SS_Blessed_Butterfly_Icon.png File:SS Blessed Butterfly Icon.png]</span>'
Category:Link, Zelda, and File:SS Blessed Butterfly Icon.png
Green check
Does not affect interwiki links
19
killBacklinks("[[metroidwiki:Chozo|Chozo]]")
"[[metroidwiki:Chozo|Chozo]]"
Chozo
Green check

link

link(page, [display], [noBacklink])

Parameters

  • page
    The link target. Can be the name of a page on the wiki or an external URL.
  • [display="page"]
    The text to display for the link.
  • [noBacklink]
    When true, renders an internal link such that it does not register on the Special:WhatLinksHere of the target page.

    Use only when certain that the page exists. This method cannot render red-links (i.e. distinguish non-existent pages).

Returns

  • A string of wikitext that evaluates to a link. Will display a red link if the target is an internal link to a page that doesn't exist.

Examples

#InputOutputResultStatus
Internal link
20
link("Princess Zelda")
"[[Princess Zelda]]"
Princess Zelda
Green check
Piped link
21
link("Princess Zelda", "Zelda")
"[[Princess Zelda|Zelda]]"
Zelda
Green check
Category link
22
link("Category:Items")
"[[:Category:Items]]"
Category:Items
Green check
Category link without prefix
23
link("Category:Items", "")
"[[:Category:Items|Items]]"
Items
Green check
Category link with display text
24
link(
  "Category:Items in Breath of the Wild",
  "Items in ''Breath of the Wild''"
)
"[[:Category:Items in Breath of the Wild|Items in ''Breath of the Wild'']]"
Items in Breath of the Wild
Green check
File link (to file description)
25
link("File:MM Deku Butler Artwork.png")
"[[:File:MM Deku Butler Artwork.png]]"
File:MM Deku Butler Artwork.png
Green check
External link
26
link("https://www.mariowiki.com/Thwomp", "Thwomp")
"[https://www.mariowiki.com/Thwomp Thwomp]"
Thwomp
Green check
Looks like an internal link, but it's actually an external link. This is to avoid Special:WhatLinksHere
27
link("Princess Zelda", "Zelda", true)
'<span class="plainlinks">[https://zelda.fandom.com/Princess_Zelda Zelda]</span>'
Zelda
Green check
When noBacklink is set to true, red links are not rendered for pages which do not exist, for performance reasons.
28
link("Flippityfloppityfloo", nil, true)
'<span class="plainlinks">[https://zelda.fandom.com/Flippityfloppityfloo Flippityfloppityfloo]</span>'
Flippityfloppityfloo
Green check

sectionLink

sectionLink(page, [section], [display])

Parameters

Returns

  • A string of wikitext rendering a section link.

Examples

#InputOutputResultStatus
29
sectionLink("Link", "Ocarina of Time", "Hero of Time")
"[[Link#Ocarina of Time|Hero of Time]]"
Hero of Time
Green check
30
sectionLink("Link", nil, "Hero of Time")
"[[Link|Hero of Time]]"
Hero of Time
Green check
31
sectionLink("Link", "")
"[[Link#]]"
Link#
Green check

stripCategories

stripCategories(wikitext)

Parameters

Returns

  • The string of wiki markup with all the category links removed (not including visual links to category description pages).
  • A table array of direct links to the removed categories.

Examples

#InputOutputStatus
Basic use case
32
stripCategories("<[[Category:Link]][[Category:Princess Zelda]][[Category:Link]]>")
"<>"
Green check
{
  "[[:Category:Link]]",
  "[[:Category:Princess Zelda]]",
}
Green check
Does not affect visual links to category description pages
33
stripCategories("[[:Category:Link]] and [[:Category:Princess Zelda]]")
"[[:Category:Link]] and [[:Category:Princess Zelda]]"
Green check
{}
Green check

local p = {}
local h = {}

local utilsMarkup = require("Module:UtilsMarkup/Format")
local utilsPage = require("Module:UtilsPage")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")

function p.anchor(id, display)
	return string.format('<span id="%s">[[#%s|%s]]</span>', id, id, display or id)
end

function p.category(name, sortKey)
	if not utilsString.startsWith(name, "Category:") then
		name = "Category:" .. name
	end
	return h.internalLink(name, sortKey)
end

function p.categories(categoryNames)
	local categoryLinks = utilsTable.map(categoryNames, p.category)
	return table.concat(categoryLinks)
end

function p.containsLink(wikitext, external)
	return wikitext ~= nil and not not wikitext:find("%[%[.*%]%]")
end

function p.file(name, options)
	options = options or {}
	local size = options.size
	local link = options.link
	local caption = options.caption
	local class = options.class
	local noBacklink = options.noBacklink
	
	if not utilsString.startsWith(name, "File:") then
		name = "File:" .. name
	end
	if link and noBacklink then
		link = tostring(mw.uri.fullUrl(link))
	end
	local linkParts = utilsTable.compact({
		name,
		size,
		link and "link="..link,
		class and "class="..class,
		caption,
	})
	local fileLink = "[[" .. table.concat(linkParts, "|") .. "]]"
	return fileLink
end

function p.killBacklinks(wikitext)
	local link = string.match(wikitext, "%[%[[^%]]*%]%]")
	if not link then
		return wikitext
	end
	local startPos, endPos = string.find(wikitext, link, 1, true)
	local before = string.sub(wikitext, 1, startPos -1)
	local after = string.sub(wikitext, endPos + 1)
	local externalLink = p.killBacklink(link)
	return before .. externalLink .. p.killBacklinks(after)
end

function p.killBacklink(link)
	local linkParts = utilsString.trim(link, "][")
	local pipe = string.find(linkParts, "|")
	local page = string.sub(linkParts, 1, pipe and pipe - 1)
	local display = pipe and string.sub(linkParts, pipe + 1)
	local startsWithColon = utilsString.startsWith(page, ":")
	page = string.gsub(page, "^:", "")
	local title = mw.title.new(page)
	if not title or title.interwiki ~= "" or not startsWithColon and (title.nsText == "Category" or title.nsText == "File") then
		return link
	end
	return p.link(page, display or page, true)
end

-- If backlink == false then this print an external link that looks like an internal one 
-- (useful for creating links that do not appear in Special:WhatLinksHere)
function p.link(link, text, noBacklink)
	if not link then
		return ""
	end
	link = mw.text.trim(link)
	if link:find('http') then
		return h.externalLink(link, text)
	end
	if noBacklink then
		local url = utilsPage.fullUrl(link)
		local externalLink = h.externalLink(url, text or link)
		local formattedLink = utilsMarkup.class("plainlinks", externalLink)
		return formattedLink
	end
	local title = mw.title.new(link) or link
	if title.nsText == "File" or title.nsText == "Category" then
		link = ":" .. link
		if text == "" then
			text = title.text
		end
	end
	return h.internalLink(link, text)
end
function h.internalLink(page, display)
	if not page then
		return ""
	end
	if not display then
		return ("[[%s]]"):format(page)
	end
	return ('[[%s|%s]]'):format(page, display)
end
function h.externalLink(page, display)
	if not page then
		return ""
	end
	if not display then
		return page
	end
	return ('[%s %s]'):format(page, display)
end

function p.sectionLink(page, section, display)
	local target = page
	if section then
		target = target .. "#" .. section
	end
	return p.link(target, display)
end

local categoryPattern = "%[%[Category:[^%]]*%]%]"
function p.stripCategories(wikitext)
	local categories = {}
	for category in string.gmatch(wikitext, categoryPattern) do
		local categoryWithoutSortKey = string.gsub(category, "|[^%]]*%]%]", "]]")
		local categoryLink = string.gsub(categoryWithoutSortKey, "Category", ":Category")
		if not utilsTable.keyOf(categories, categoryLink) then
			table.insert(categories, categoryLink)
		end
	end
	return string.gsub(wikitext, categoryPattern, ""), categories
end

function p.Schemas() 
	return {
		anchor = {
			id = {
				type = "string",
				required = true,
			},
			display = {
				type = "string",	
			},
		},
		link = {
			page = {
				type = "string",
				required = true,
				desc = "The link target. Can be the name of a page on the wiki or an external URL.",
			},
			display = {
				type = "string",
				default = "page",
				desc = "The text to display for the link.",
			},
			noBacklink = {
				type = "boolean",
				desc = [[
					When <code>true</code>, renders an internal link such that it does not register on the]] .. " [[Special:WhatLinksHere]] " .. [[of the target page.
					
					'''Use only when certain that the page exists'''.  This method cannot render red-links (i.e. distinguish non-existent pages).
				]],
			},
		},
		sectionLink = {
			page = {
				type = "string",
				required = true,
				desc = "The name of a wiki page to target.",
			},
			section = {
				type = "string",
				desc = "The name of the page section to target.",
			},
			display = {
				type = "string",
				default = "page",
				desc = "The text to display for the link.",
			},
		},
		file = {
			name = {
				type = "string",
				required = true,
				desc = "A file name, with or without the <code>File:</code> prefix.",
			},
			options = {
				type = "record",
				properties = {
					{
						name = "size",
						type = "string",
						desc = "Image size in pixels.",
					},
					{
						name = "link",
						type = "string",
						desc = "Name of a page on the wiki or an external URL for the image thumbnail to link to.",
					},
					{
						name = "caption",
						type = "string",
						desc = "[https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img Alt text] for the image.",
					},
					{
						name = "class",
						type = "string",
						desc = "Sets the HTML classes of the image element.",
					},
					{
						name = "noBacklink",
						type = "boolean",
						desc = "When <code>true</code>, the <code>link</code> property is rendered such that it does not register on the [[Special:WhatLinksHere]] of the target page. " 
							 .. "It also does not register on [[Special:WantedPages]] if the page doesn't exist.",
					}
				}
			},
		},
		category = {
			name = {
				type = "string",
				required = true,
				desc = "The name of the category to link to (with or without namespace prefix).",
			},
			sortKey = {
				type = "string",
				desc = "A custom {{mediawiki|Help:Categories#Sort_key|sort key}} for the category entry.",
			}
		},
		categories = {
			names = {
				type = "array",
				required = true,
				items = { type = "string" },
				desc = "An array of category names, with or without the namespace prefix.",
			}
		},
		killBacklinks = {
			wikitext = {
				type = "string",
				required = true,
				desc = "A string of wiki markup.",
			},
		},
		stripCategories = {
			wikitext = {
				type = "string",
				required = true,
				desc = "A string of wiki markup.",
			},
		}
	}
end

function p.Documentation() 
	return {
		anchor = {
			params = {"id", "display"},
			returns = "A link that refers to itself. Useful for linking to specific sections of a page without necessarily using headings.",
			cases = {
				{
					args = {"foo"},
					expect = '<span id="foo">[[#foo|foo]]</span>',
				},
				{
					args = {"bar", "Bar"},
					expect = '<span id="bar">[[#bar|Bar]]</span>',
				},
				{
					args = {"foo bar"},
					expect = '<span id="foo bar">[[#foo bar|foo bar]]</span>',
				},
			},
		},
		link = {
			params = {"page", "display", "noBacklink"},
			returns = "A string of wikitext that evaluates to a link. Will display a red link if the target is an internal link to a page that doesn't exist.",
			cases = {
				{
					desc = "Internal link",
					args = { "Princess Zelda" },
					expect = "[[Princess Zelda]]",
				},
				{
					desc = "Piped link",
					args = { "Princess Zelda", "Zelda" },
					expect = "[[Princess Zelda|Zelda]]",
				},
				{
					desc = "Category link",
					args = { "Category:Items" },
					expect = "[[:Category:Items]]",
				},
				{
					desc = "Category link without prefix",
					args = { "Category:Items", "" },
					expect = "[[:Category:Items|Items]]",
				},
				{
					desc = "Category link with display text",
					args = { "Category:Items in Breath of the Wild", "Items in ''Breath of the Wild''" },
					expect = "[[:Category:Items in Breath of the Wild|Items in ''Breath of the Wild'']]",
				},
				{
					desc = "File link (to file description)",
					args = { "File:MM Deku Butler Artwork.png" },
					expect = "[[:File:MM Deku Butler Artwork.png]]",
				},
				{
					desc = "External link",
					args = { "https://www.mariowiki.com/Thwomp", "Thwomp" },
					expect = "[https://www.mariowiki.com/Thwomp Thwomp]",
				},
				{
					desc = "Looks like an internal link, but it's actually an external link. This is to avoid [[Special:WhatLinksHere]]",
					args = { "Princess Zelda", "Zelda", true },
					expect = [[<span class="plainlinks">[https://zelda.fandom.com/Princess_Zelda Zelda]</span>]],
				},
				{
					-- Doing red links here would require checking page existence, which requires a database read and is considered an "expensive function" by MediaWiki
					-- Given how often this function can be called on any given page, it's probably best to avoid this
					desc = "When <code>noBacklink</code> is set to <code>true</code>, red links are not rendered for pages which do not exist, for performance reasons.",
					args = { "Flippityfloppityfloo", nil, true },
					expect = [[<span class="plainlinks">[https://zelda.fandom.com/Flippityfloppityfloo Flippityfloppityfloo]</span>]],
				},
			},
		},
		sectionLink = {
			params = {"page", "section", "display"},
			returns = "A string of wikitext rendering a section link.",
			cases = {
				{
					args = {"Link", "Ocarina of Time", "Hero of Time"},
					expect = "[[Link#Ocarina of Time|Hero of Time]]",
				},
				{
					args = {"Link", nil, "Hero of Time"},
					expect = "[[Link|Hero of Time]]",
				},
				{
					args = {"Link", ""},
					expect = "[[Link#]]",
				},
			},
		},
		file = {
			params = {"name", "options"},
			returns = "A <code>string</code> of wikitext that renders a thumbnail for the file.",
			cases = {
				{
					args = { "File:ALttP Ganon Sprite.png" },
					expect = "[[File:ALttP Ganon Sprite.png]]",
				},
				{
					args = { "ALttP Ganon Sprite.png", {
						link = "",
						caption = "Ganon"
					}},
					expect = "[[File:ALttP Ganon Sprite.png|link=|Ganon]]",
				},
				{
					args = { "File:TWW Great Fairy Figurine Model.png", {
						link = "Great Fairy",
						size = "100px",
					}},
					expect = "[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy]]",
				},
				{
					args = { "File:TWW Great Fairy Figurine Model.png", {
						link = "Great Fairy",
						size = "100px",
						noBacklink = true,
					}},
					expect = "[[File:TWW Great Fairy Figurine Model.png|100px|link=https://zelda.fandom.com/wiki/Great_Fairy]]",
				},
				{
					args = { "File:TWW Great Fairy Figurine Model.png", {
						link = "Great Fairy",
						size = "100px",
						class = "notpageimage",
					}},
					expect = "[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy|class=notpageimage]]",
				},
			},
		},
		category = {
			params = {"name", "sortKey"},
			returns = "A category link—the kind that adds a category to a page. For the other kind that links to the actual category page, use <code>link</code>.",
			cases = {
				outputOnly = true,
				{
					desc = "Category link from category name",
					args = { "Items" },
					expect = "[[Category:Items]]"
				},
				{
					desc = "Category link from category name with namespace prefix",
					args = { "Category:Items" },
					expect = "[[Category:Items]]",
				},
				{
					desc = "Category link with sort key",
					args = { "Items", "*" },
					expect = "[[Category:Items|*]]",
				},
			},
		},
		categories = {
			params = {"names"},
			returns = "A concatenated string of category links.",
			cases = {
				outputOnly = true,
				{
					args = { {"Link", "Category:Zelda", "Category:Ganon"} },
					expect = "[[Category:Link]][[Category:Zelda]][[Category:Ganon]]"
				},
				{
					args = { {} },
					expect = ""
				},
			},
		},
		containsLink = {
			params = {"wikitext"},
			returns = "Given a string of wikitext, returns <code>true</code> if it contains an internal or interwiki link, false otherwise.",
			cases = {
				{
					args = {"There is a [[Link]]"},
					expect = true,
				},
				{
					args = {"[Link] is not a link but rather an indication of replaced words in a quote."},
					expect = false,
				},
			},
		},
		killBacklinks = {
			params = {"wikitext"},
			returns = "The same wikitext but with all the internal links formatted as external links, to avoid additions to [[Special:WhatLinksHere]].",
			cases = {
				{
					-- See "link" function for peformance reasons
					-- It might still be possible for us to support red links here if the performance requirements aren't as stringent as the "link" function
					-- There doesn't seem to be a pressing need at the moment, though
					desc = "Escapes basic article links - unfortunately non-existent pages are not rendered as red links for performance reasons",
					args = { "[[Link]], [[Princess Zelda|Zelda]], and [[Jean-Guy Rubber Boots]]" },
					expect = '<span class="plainlinks">[https://zelda.fandom.com/Link Link]</span>, <span class="plainlinks">[https://zelda.fandom.com/Princess_Zelda Zelda]</span>, and <span class="plainlinks">[https://zelda.fandom.com/Jean-Guy_Rubber_Boots Jean-Guy Rubber Boots]</span>'
				},
				{
					desc = "Does not escape file links or category links",
					args = { "[[Category:Link]] and [[File:SS Blessed Butterfly Icon.png]]"},
					expect = "[[Category:Link]] and [[File:SS Blessed Butterfly Icon.png]]"
				},
				{
					desc = "Escapes visible file and category links",
					args = { "[[:Category:Link]], [[:Category:Princess Zelda|Zelda]], and [[:File:SS Blessed Butterfly Icon.png]]"},
					expect = 
						'<span class="plainlinks">[https://zelda.fandom.com/Category:Link Category:Link]</span>, '
						.. '<span class="plainlinks">[https://zelda.fandom.com/Category:Princess_Zelda Zelda]</span>, '
						.. 'and <span class="plainlinks">[https://zelda.fandom.com/File:SS_Blessed_Butterfly_Icon.png File:SS Blessed Butterfly Icon.png]</span>'
				},
				{
					desc = "Does not affect interwiki links",
					args = { "[[metroidwiki:Chozo|Chozo]]" },
					expect = "[[metroidwiki:Chozo|Chozo]]"
				}
			},
		},
		stripCategories = {
			params = {"wikitext"},
			returns = {
				 "The string of wiki markup with all the category links removed (not including visual links to category description pages).",
				 "A <code>table</code> array of direct links to the removed categories.",
			},
			cases = {
				outputOnly = true,
				{
					desc = "Basic use case",
					args = {"<[[Category:Link]][[Category:Princess Zelda]][[Category:Link]]>"},
					expect = {
						"<>",
						{"[[:Category:Link]]", "[[:Category:Princess Zelda]]"},
					},
				},
				{
					desc = "Does not affect visual links to category description pages",
					args = {"[[:Category:Link]] and [[:Category:Princess Zelda]]"},
					expect = {
						"[[:Category:Link]] and [[:Category:Princess Zelda]]",
						{},
					}
				}
			}
		}
	}
end

return p
Advertisement