Module:UtilsPage

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search
This module exports the following functions.

dpl

dpl(args)

This function is wrapper for the DPL parser function.

When constructing queries, keep in mind DPL's configured limits.

  • A single query can return no more than 500 results. (maxResultCount)
  • A single query using category selection may contain no more than 4 categories. (maxCategoryCount)

Returns

  • Array of results.

Examples

#InputOutputResult
1
dpl({
  namespace = "Category",
  titlematch = "Link|Zelda",
})
{"Category:Link", "Category:Zelda"}
Repeating arguments
2
dpl({
  category = "Lynels",
  notcategory = {
    "Sub-Bosses",
    "Enemies in Hyrule Warriors: Age of Calamity",
  },
})
Expected
{"Blue Lynel", "Red Lynel"}
Actual
{
  "Red Lynel",
  "Silver Lynel",
  "White-Maned Lynel",
  "Blue Lynel",
  "Blue-Maned Lynel",
}

exists

exists(fullPageName, [noRedirect])

Checks whether a page exists using the _pageData Cargo table. Unlike mw.title this function does not register a link in Special:WantedPages or Special:WhatLinksHere, nor does it count as an "expensive parser function."

Parameters

Returns

  • Boolean indicating whether the page exists.

Examples

#InputOutputResult
3
exists("OoT")
true
4
exists("OoT", true)
false
Works for files and file redirects too
5
exists("File:OoT Bomb Bag Model.png")
true
6
exists("File:MM Bomb Bag Model.png")
true
7
exists("File:MM Bomb Bag Model.png", true)
false
Ignores section anchors
8
exists("Impa#Biography")
true

fullUrl

fullUrl(fullPageName, [queryParams])

A performant alternative to mw.uri.fullUrl. Unlike mw.uri.fullUrl, it cannot translate interwiki links. To format the link as an internal link, see Module:UtilsMarkup#link.

Parameters

Returns

  • The url for the specified wiki page.

Examples

#InputOutputResultStatus
9
fullUrl("Mipha's Grace")
"//zeldawiki.wiki/Mipha%27s_Grace"
//zeldawiki.wiki/Mipha%27s_Grace
10
fullUrl(
  "Special:Upload",
  {
    wpDestFile = "TWWHD Great Fairy Figurine Model.png",
  }
)
"//zeldawiki.wiki/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png"
//zeldawiki.wiki/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png
11
fullUrl(
  "New Page",
  {
    action = "edit",
    redlink = 1,
  }
)
"//zeldawiki.wiki/New_Page?action=edit&redlink=1"
//zeldawiki.wiki/New_Page?action=edit&redlink=1

getSubpages

getSubpages([fullPageName])

Parameters

  • [fullPageName]
    A full page name with namespace prefix. If nil, mw.title.getCurrentTitle() is used.

Returns

  • A list of subpages

Examples

#InputOutput
12
getSubpages("Module:Constants")
{
  "Module:Constants/Data",
  "Module:Constants/Documentation",
  "Module:Constants/category/deprecatedParams",
  "Module:Constants/category/deprecatedParams/Documentation",
  "Module:Constants/category/invalidArgs",
  "Module:Constants/category/invalidArgs/Documentation",
  "Module:Constants/category/templateErrors",
  "Module:Constants/class/noexcerpt",
  "Module:Constants/class/noexcerpt/Documentation",
  "Module:Constants/class/pixelArt",
  "Module:Constants/class/pixelArt/Documentation",
  "Module:Constants/class/tooltip",
  "Module:Constants/class/tooltip/Documentation",
  "Module:Constants/number/maxImageArea",
  "Module:Constants/number/maxImageArea/Documentation",
  "Module:Constants/number/maxNavboxPartitionSize",
  "Module:Constants/number/maxNavboxPartitionSize/Documentation",
  "Module:Constants/url/discord",
  "Module:Constants/url/discord/Documentation",
}
13
getSubpages("Module:UtilsPage")
{"Module:UtilsPage/Documentation"}

inCategory

inCategory(category, fullPageName)

Parameters

  • category
    Category name with or without namespace prefix.
  • fullPageName
    Full page name with namespace prefix.

Returns

  • A boolean indicating whether the given page is a member of the given category.

Examples

#InputOutputResult
Works with or without the namespace prefix.
14
inCategory("Characters in Breath of the Wild", "Link")
true
15
inCategory("Category:Characters", "Link")
true
16
inCategory("Items", "Link")
false
17
inCategory("Fakecategory", "Link")
false
For pages not in the main namespace, the namespace prefix is required.
18
inCategory(
  "Characters by Game",
  "Characters in Breath of the Wild"
)
false
19
inCategory(
  "Characters by Game",
  "Category:Characters in Breath of the Wild"
)
Expected
true
Actual
false

inNamespace

inNamespace(namespaces, [fullPageName])

Parameters

Returns

  • true if and only if fullPageName (or the current page) has a namespace prefix that is one of namespaces, regardless of whether the page actually exists.

Examples

#InputOutputResult
Main namespace is the empty string.
20
inNamespace("", "Link")
true
21
inNamespace("Category", "Link")
false
22
inNamespace("Category", "Category:Link")
true
Can evaluate to true even when page does not exist.
23
inNamespace("Category", "Category:Flippityfloppityfloo")
true
Current page
24
inNamespace("Module")
true
Multiple namespaces
25
inNamespace({"User", "MediaWiki"}, "Princess Zelda")
false
26
inNamespace({"User", "MediaWiki"}, "User:Abdullah")
true

isRedirect

isRedirect(page)

Checks whether a page is a redirect using the _pageData Cargo table. Unlike mw.title this function does not register a link in Special:WantedPages or Special:WhatLinksHere, nor does it count as an "expensive parser function."

Returns

  • true if the page is a redirect, false otherwise.

Examples

#InputOutputResult
27
isRedirect("OoT")
true
28
isRedirect("The Legend of Zelda: Ocarina of Time")
false
29
isRedirect("Notapage")
false

stripNamespace

stripNamespace(page, [namespace])

Parameters

  • page
    Pagename to strip namespace prefix from.
  • [namespace]
    Namespace to strip. If nil, any namespace will be stripped.

Returns

  • page with namespace prefix stripped off.

Examples

#InputOutputStatus
30
stripNamespace("Category:Items in Breath of the Wild", "Category")
"Items in Breath of the Wild"
31
stripNamespace("Items in Breath of the Wild", "Category")
"Items in Breath of the Wild"
32
stripNamespace("Category:Items in Breath of the Wild", "File")
"Category:Items in Breath of the Wild"
33
stripNamespace("File:TWWHD Tingle Model.png", "File")
"TWWHD Tingle Model.png"
34
stripNamespace("File:TWWHD Tingle Model.png")
"TWWHD Tingle Model.png"
35
stripNamespace(":Category:Items in Breath of the Wild")
"Items in Breath of the Wild"

local p = {}
local h = {}

local utilsCargo = require("Module:UtilsCargo")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")

local SEPARATOR = "#"
function p.dpl(args)
	local dplArgs = ""
	for k, v in pairs(args) do
		if k == "format" or type(v) == "table" and v.value == "format" then
			mw.addWarning("<code>format</code> argument cannot be used here. Format the resulting Lua table instead.")
		elseif type(v) == "table" then
			for _, andedValue in ipairs(v) do
				dplArgs = dplArgs .. h.appendArg(k, andedValue)
			end
		else
			dplArgs = dplArgs .. h.appendArg(k, v)
		end
	end
	dplArgs = dplArgs .. h.appendArg("format", SEPARATOR..",,%PAGE%" .. SEPARATOR .. ",")
	local result = mw.getCurrentFrame():preprocess("{{#dpl:" .. dplArgs .. "}}")
	if not utilsString.endsWith(result, SEPARATOR) then
		return {}
	end
	result = string.gsub(result, SEPARATOR .. ":", SEPARATOR) -- strip : prefix from Category results
	result = utilsString.trim(result, SEPARATOR)
	result = utilsString.split(result, SEPARATOR)
	return result
end
function h.appendArg(param, value)
	value = tostring(value)
	value = string.gsub(value, "\|", "{{!}}")
	if param and value then
		return "|" .. param .. "=" .. value .. "\n"
	else
		return ""
	end
end

function p.exists(fullPageName, noRedirect)
	local anchorStart = string.find(fullPageName, "#")
	if anchorStart then
		fullPageName = string.sub(fullPageName, 1, anchorStart - 1)
	end
	local queryResults = utilsCargo.query("_pageData", "_pageName, _isRedirect", {
		where = utilsCargo.allOf({
			_pageName = fullPageName
		})	
	})
	return #queryResults > 0 and (not noRedirect or queryResults[1]._isRedirect == "0")
end

function p.fullUrl(page, queryParams)
	local baseUrl = mw.site.server .. "/"
	local pageUrl = baseUrl ..  mw.uri.encode(page, "WIKI")
	if queryParams then
		local encodedParams = {}
		for k, v in pairs(queryParams) do
			local param = k .. "=" .. mw.uri.encode(tostring(v), "QUERY")
			table.insert(encodedParams, param) 
		end
		local queryStr = "?" .. table.concat(encodedParams, "&")
		pageUrl = pageUrl .. queryStr
	end
	return pageUrl
end

function p.getSubpages(fullPageName)
	local title = fullPageName and mw.title.new(fullPageName) or mw.title.getCurrentTitle()
	local pages = p.dpl({
		namespace= title.nsText,
		titlematch= '%' .. title.text .. '/%',
	})
	table.sort(pages)
	return pages
end

function p.inCategory(category, fullPageName)
	if (not category) or (not fullPageName) then
		return false
	end
	local title = mw.title.new(fullPageName)
	local dplResult = p.dpl({
		category= p.stripNamespace(category),
		namespace= title.nsText,
		title= title.text,
		skipthispage= "no",
	})
	return #dplResult ~= 0
end

function p.inNamespace(namespaces, fullPageName)
	if type(namespaces) == "string" then
		namespaces = {namespaces}
	end
	local title = fullPageName and mw.title.new(fullPageName) or mw.title.getCurrentTitle()
	return utilsTable.includes(namespaces, title.nsText)
end

function p.isRedirect(page)
	local anchorStart = string.find(page, "#")
	if anchorStart then
		page = string.sub(page, 1, anchorStart - 1)
	end
	local queryResults = utilsCargo.query("_pageData", "_pageName, _isRedirect", {
		where = utilsCargo.allOf({
			_pageName = page
		})	
	})
	return #queryResults > 0 and queryResults[1]._isRedirect == "1"
end

function p.stripNamespace(page, namespace)
	if not namespace then
		namespace = "[^:]*"
	end
	return string.gsub(page, ":?".. namespace..":", "")
end

function p.Schemas() 
	return {
		exists = {
			fullPageName = {
				type = "string",
				required = true,
				desc = "Full page name with namespace prefix.",
			},
			noRedirect = {
				type = "boolean",
				desc = "If true, redirects are not considered."
			},
		},
		fullUrl = {
			fullPageName = {
				type = "string",
				required = true,
				desc = "Full page name with namespace prefix.",
			},
			queryParams = {
				type = "map",
				keys = { type = "string" },
				values = {
					oneOf = {
						{ type = "string" },
						{ type = "number" },
					},
				},
				desc = "{{Wp|Query string|Query parameters}}.",
			},
		},
		getSubpages = {
			fullPageName = {
				type = "string",
				desc = "A full page name with namespace prefix. If nil, <code>mw.title.getCurrentTitle()</code> is used.",
			},
		},
		inCategory = {
			category = {
				type = "string",
				required = true,
				desc = "Category name with or without namespace prefix.",
			},
			fullPageName = {
				type = "string",
				required = true,
				desc = "Full page name with namespace prefix."
			},
		},
		inNamespace = {
			namespaces = {
				desc = "A namespace or array of namespaces.",
				required = true,
				oneOf = {
					{ type = "string" },
					{ type = "array", items = { type = "string" } }
				},
			},
			fullPageName = {
				type = "string",
				desc = "Full pagename. Defaults to the name of the current page."
			}
		},
		stripNamespace = {
			page = {
				required = true,
				type = "string",
				desc = "Pagename to strip namespace prefix from.",
			},
			namespace = {
				type = "string",
				desc = "Namespace to strip. If nil, any namespace will be stripped."
			},
		},
	}
end

function p.Documentation()
	return {
		exists = {
			desc = 'Checks whether a page exists using the [[Special:CargoTables/_pageData|_pageData]] Cargo table. Unlike {{Scribunto Manual|lib=mw.title}} this function does not register a link in [[Special:WantedPages]] or [[Special:WhatLinksHere]], nor does it count as an "expensive parser function."',
			params = {"fullPageName", "noRedirect"},
			returns = "Boolean indicating whether the page exists.",
			cases = {
				{
					args = {"OoT"},
					expect = true,
				},
				{
					args = {"OoT", true},
					expect = false,
				},
				{
					desc = "Works for files and file redirects too",
					args = {"File:OoT Bomb Bag Model.png"},
					expect = true,
				},
				{
					args = {"File:MM Bomb Bag Model.png"},
					expect = true,
				},
				{
					args = {"File:MM Bomb Bag Model.png", true},
					expect = false,
				},
				{
					desc = "Ignores section anchors",
					args = {"Impa#Biography"},
					expect = true,
				},
			},
		},
		getSubpages = {
			params = {"fullPageName"},
			returns = "A list of subpages",
			cases = {
				outputOnly = true,
				{
					args = {"Module:Constants"},
				},
				{
					args = {"Module:UtilsPage"},
				},
			},
		},
		fullUrl = {
			desc = "A performant alternative to {{Scribunto Manual|lib=mw.uri.fullUrl}}. Unlike <code>mw.uri.fullUrl</code>, it cannot translate interwiki links. To format the link as an internal link, see [[Module:UtilsMarkup#link]].",
			params = {"fullPageName", "queryParams"},
			returns = "The url for the specified wiki page.",
			cases = {
				{
					args = {"Mipha's Grace"},
					expect = "//zeldawiki.wiki/Mipha%27s_Grace",
				},
				{
					args = {"Special:Upload", { wpDestFile = "TWWHD Great Fairy Figurine Model.png" } },
					expect = "//zeldawiki.wiki/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png"
				},
				{
					args = {"New Page", {
						action = "edit",
						redlink = 1,
					}},
					expect = "//zeldawiki.wiki/New_Page?action=edit&redlink=1",
				},
			},
		},
		dpl = {
			desc = "<p>This function is wrapper for the [[gphelp:Extension:DPL3/Manual|DPL]] parser function.</p>"
				.. "<p>When constructing queries, keep in mind DPL's [https://www.mediawiki.org/wiki/Extension:DynamicPageList3#Configuration configured limits].</p>"
				.. "<ul>"
				..   "<li>A single query can return no more than 500 results. (<code>maxResultCount</code>)</li>"
				..   "<li>A single query using <code>category</code> selection may contain no more than 4 categories. (<code>maxCategoryCount</code>)</li>"
				.. "</ul>",
			params = {"args"},
			returns = "Array of results.",
			cases = {
				{
					args = { {titlematch = "Link|Zelda", namespace = "Category"} },
					expect = {"Category:Link", "Category:Zelda"}
				},
				{
					desc = "Repeating arguments",
					args = {
						{
							category = "Lynels",
							notcategory = {
								"Sub-Bosses",
								"Enemies in Hyrule Warriors: Age of Calamity",
							},
						},
					},
					expect = {"Blue Lynel", "Red Lynel"},
				},
			},
		},
		inCategory = {
			params = {"category", "fullPageName"},
			returns = "A boolean indicating whether the given page is a member of the given category.",
			cases = {
				{
					desc = "Works with or without the namespace prefix.",
					args = {"Characters in Breath of the Wild", "Link"},
					expect = true,
				},
				{
					args = {"Category:Characters", "Link"},
					expect = true,
				},
				{
					args = {"Items", "Link"},
					expect = false,
				},
				{
					args = {"Fakecategory", "Link"},
					expect = false,
				},
				{
					desc = "For pages not in the main namespace, the namespace prefix is required.",
					args = {"Characters by Game", "Characters in Breath of the Wild"},
					expect = false,
				},
				{
					args = {"Characters by Game", "Category:Characters in Breath of the Wild"},
					expect = true,
				},
			},
		},
		inNamespace = {
			params = {"namespaces", "fullPageName"},
			returns = "<code>true</code> if and only if <code>fullPageName</code> (or the current page) has a namespace prefix that is one of <code>namespaces</code>, regardless of whether the page actually exists.",
			cases = {
				{
					desc = "Main namespace is the empty string.",
					args = {"", "Link"},
					expect = true,
				},
				{
					args = {"Category", "Link"},
					expect = false,
				},
				{
					args = {"Category", "Category:Link"},
					expect = true,
				},
				{
					desc = "Can evaluate to true even when page does not exist.",
					args = {"Category", "Category:Flippityfloppityfloo"},
					expect = true,
				},
				{
					desc = "Current page",
					args = {"Module"},
					expect = true,
				},
				{
					desc = "Multiple namespaces",
					args = {{"User", "MediaWiki"}, "Princess Zelda"},
					expect = false,
				},
				{
					args = {{"User", "MediaWiki"}, "User:Abdullah"},
					expect = true,
				},
			},
		},
		isRedirect = {
			desc = 'Checks whether a page is a redirect using the [[Special:CargoTables/_pageData|_pageData]] Cargo table. Unlike {{Scribunto Manual|lib=mw.title}} this function does not register a link in [[Special:WantedPages]] or [[Special:WhatLinksHere]], nor does it count as an "expensive parser function."',
			params = {"page"},
			returns = "<code>true</code> if the page is a redirect, <code>false</code> otherwise.",
			cases = {
				{
					args = {"OoT"},
					expect = true,
				},
				{
					args = {"The Legend of Zelda: Ocarina of Time"},
					expect = false,
				},
				{
					args = {"Notapage"},
					expect = false,
				},
			},
		},
		stripNamespace = {
			params = {"page", "namespace"},
			returns = "<code>page</code> with namespace prefix stripped off.",
			cases = {
				outputOnly = true,
				{
					args = {"Category:Items in Breath of the Wild", "Category"},
					expect = "Items in Breath of the Wild",
				},
				{
					args = {"Items in Breath of the Wild", "Category"},
					expect = "Items in Breath of the Wild",
				},
				{
					args = {"Category:Items in Breath of the Wild", "File"},
					expect = "Category:Items in Breath of the Wild",
				},
				{
					args = {"File:TWWHD Tingle Model.png", "File"},
					expect = "TWWHD Tingle Model.png",
				},
				{
					args = {"File:TWWHD Tingle Model.png"},
					expect = "TWWHD Tingle Model.png",
				},
				{
					args = {":Category:Items in Breath of the Wild"},
					expect = "Items in Breath of the Wild",
				}
			}
		}
	}
end

return p