Module:Region: Difference between revisions

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search
mNo edit summary
m (Protected "Module:Region": site-wide usage ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)))
 
(6 intermediate revisions by the same user not shown)
Line 10: Line 10:


function p.Flag(frame)
function p.Flag(frame)
local args, err = utilsArg.parse(frame:getParent().args, p.Templates.Flag)
local frameArgs = frame:getParent().args
frameArgs[1] = string.upper(frameArgs[1])
local args, err = utilsArg.parse(frameArgs, p.Templates.Flag)
if err then
if err then
return err.categoryText
return err.categoryText
Line 26: Line 28:
local enum = {}
local enum = {}
for k, v in pairs(Data.regions) do
for k, v in pairs(Data.regions) do
if k ~= "jp" and k ~= "us" then
if k ~= "JP" and k ~= "US" then
table.insert(enum, {
table.insert(enum, {
code = k,
code = k,
Line 43: Line 45:
enum[i] = v.code
enum[i] = v.code
end
end
table.insert(enum, 1, "jp")
table.insert(enum, 1, "JP")
table.insert(enum, 1, "us")
table.insert(enum, 1, "US")
enum.reference = "[[Module:Region/Data]]"
enum.reference = "[[Module:Region/Data]]"
Line 50: Line 52:
end
end


--cache Template:Exp results for performance
local exp = {}
function p.getRegion(code, options)
function p.getRegion(code, options)
code = string.upper(code)
options = options or {}
options = options or {}
local flagSize = options.flagSize or DEFAULT_FLAG_SIZE
local flagSize = options.flagSize or DEFAULT_FLAG_SIZE
Line 67: Line 72:
tooltip = flagTooltip,
tooltip = flagTooltip,
})
})
result.abbr = mw.getCurrentFrame():expandTemplate({
result.abbr = exp[code] or mw.getCurrentFrame():expandTemplate({
title = "Exp",
title = "Exp",
args = {region.name, region.abbr}
args = {region.name, region.abbr}
})
})
exp[code] = result.abbr
return result, ""
return result, ""
end
end
Line 76: Line 82:


function h.flags(region, options)
function h.flags(region, options)
options = options or {}
local size = options.size
local tooltip = options.tooltip
if not region then
if not region then
return nil, CATEGORY_INVALID_ARGS
return nil, CATEGORY_INVALID_ARGS
Line 81: Line 91:
local name = region.official or region.name
local name = region.official or region.name
local flagFile = region.flag
local flagFile = region.flag
local size = options.size
tooltip = region[tooltip] or region.name
local tooltip = region[options.tooltip] or region.name
local flag = string.format('<span class="%s" title="%s">[[%s|%s|%s]]</span>', CLASS_TOOLTIP, tooltip, flagFile, size, tooltip)
local flag = string.format('<span class="%s" title="%s">[[%s|%s|%s]]</span>', CLASS_TOOLTIP, tooltip, flagFile, size, tooltip)
return {flag}, ""
return {flag}, ""
Line 88: Line 97:
local flags = {}
local flags = {}
for i, country in ipairs(region.countries) do
for i, country in ipairs(region.countries) do
table.insert(flags, p.getRegion(country).flags[1])
local countryRegion = p.getRegion(country, {
flagSize = size,
flagTooltip = tooltip,
})
table.insert(flags, countryRegion.flags[1])
end
end
return flags, ""
return flags, ""
Line 189: Line 202:
required = true,
required = true,
type = "string",
type = "string",
desc = "Abbreviated name for the region, used by [[Template:Release]]. For countries, this should be the {{Wp|ISO 3166-1 alpha-3}} country code. For multi-country regions, use a 4+ character abbreviation, or else a 3-character abbreviation that is not a reserved ISO 3166-1 alpha-3 code.",
desc = "Abbreviated name for the region, used by [[Template:Release]]. For countries, this should be the {{Wp|ISO 3166-1 alpha-3}} country code. For multi-country regions, use a character abbreviation that is not a reserved ISO 3166-1 code.",
},
},
{
{

Latest revision as of 20:03, 24 January 2023

The source of truth for world region data relevant to The Legend of Zelda series.

This is the main module for the following templates: In addition, this module exports the following functions.

enum

enum([options])

Parameters

  • [options]
    [sortBy=name]
    Region property to sort by. Options are abbr, code, official, and name (default). By exception, USA and Japan are always placed first, as they are the native regions of this wiki and of Nintendo, respectively.

Returns

  • A list of region codes.

Examples

#InputOutput
1
enum()
{
  "US",
  "JP",
  "AR",
  "AU",
  "AUNZ",
  "AT",
  "BE",
  "BR",
  "CA",
  "CL",
  "CN",
  "CO",
  "CZ",
  "DK",
  "EUR",
  "FI",
  "FR",
  "DE",
  "GR",
  "HK",
  "HU",
  "ID",
  "INT",
  "IR",
  "IE",
  "IL",
  "IT",
  "KR",
  "LAT",
  "MO",
  "MY",
  "MX",
  "NL",
  "NZ",
  "NOA",
  "NO",
  "PE",
  "PH",
  "PL",
  "PT",
  "RU",
  "SA",
  "SG",
  "SK",
  "ZA",
  "ES",
  "SE",
  "CH",
  "TW",
  "THM",
  "TH",
  "AE",
  "GB",
  "UK",
  "UKI",
  reference = "[[Module:Region/Data]]",
}
2
enum({ sortBy = "abbr" })
{
  "US",
  "JP",
  "AE",
  "AR",
  "AUNZ",
  "AU",
  "AT",
  "BE",
  "BR",
  "CA",
  "CH",
  "CL",
  "CN",
  "CO",
  "CZ",
  "DE",
  "DK",
  "ES",
  "EUR",
  "FI",
  "FR",
  "UK",
  "GB",
  "GR",
  "HK",
  "HU",
  "ID",
  "INT",
  "IE",
  "IR",
  "IL",
  "IT",
  "KR",
  "LAT",
  "MO",
  "MX",
  "MY",
  "NL",
  "NOA",
  "NO",
  "NZ",
  "PE",
  "PH",
  "PL",
  "PT",
  "RU",
  "SA",
  "SG",
  "SK",
  "SE",
  "TH",
  "THM",
  "TW",
  "UKI",
  "ZA",
  reference = "[[Module:Region/Data]]",
}

getRegion

getRegion(code, [options])

Parameters

Returns

  • An object containing the region's name and flag(s), or nil if no region exists for the given code.
  • An error category if no region exists for the given code.

local p = {}
local h = {}
local Data = mw.loadData("Module:Region/Data")

local utilsArg = require("Module:UtilsArg")

local DEFAULT_FLAG_SIZE = "20px"
local CATEGORY_INVALID_ARGS = "[[Category:"..require("Module:Constants/category/invalidArgs").."]]"
local CLASS_TOOLTIP = require("Module:Constants/class/tooltip")

function p.Flag(frame)
	local frameArgs = frame:getParent().args
	frameArgs[1] = string.upper(frameArgs[1])
	local args, err = utilsArg.parse(frameArgs, p.Templates.Flag)
	if err then
		return err.categoryText
	else
		local region = Data.regions[args.code]
		local flags = h.flags(region, args)
		local result = table.concat(flags, " ")
		return result
	end
end

function p.enum(options)
	local options = options or {}
	local sortBy = options.sortBy or "name"
	local enum = {}
	for k, v in pairs(Data.regions) do
		if k ~= "JP" and k ~= "US" then
			table.insert(enum, {
				code = k,
				name = v.name,
				abbr = v.abbr,
				official = v.official or v.name,
			})
		end
	end
	-- We put the wiki's native region (us) first followed by Nintendo's native region (jp)
	-- followed by every other country ordred by a certain property (name by default)
	table.sort(enum, function(a, b)
		return a[sortBy] < b[sortBy]
	end)
	for i, v in ipairs(enum) do
		enum[i] = v.code
	end
	table.insert(enum, 1, "JP")
	table.insert(enum, 1, "US")
	
	enum.reference = "[[Module:Region/Data]]"
	return enum
end

--cache Template:Exp results for performance
local exp = {}
function p.getRegion(code, options)
	code = string.upper(code)
	options = options or {}
	local flagSize = options.flagSize or DEFAULT_FLAG_SIZE
	local flagTooltip = options.flagTooltip or "official"

	local region = Data.regions[code]
	if not region then
		local utilsError = require("Module:UtilsError")
		utilsError.warn(string.format("Invalid region <code>%s</code>. See [[Module:Region/Data]] for a list of supported regions.", code))
		return nil, CATEGORY_INVALID_ARGS
	else
		local result = {}
		result.name = region.name
		result.flags = h.flags(region, {
			size = flagSize,
			tooltip = flagTooltip,
		})
		result.abbr = exp[code] or mw.getCurrentFrame():expandTemplate({
			title = "Exp",
			args = {region.name, region.abbr}
		})
		exp[code] = result.abbr
		return result, ""
	end
end

function h.flags(region, options)
	options = options or {}
	local size = options.size
	local tooltip = options.tooltip

	if not region then
		return nil, CATEGORY_INVALID_ARGS
	elseif region.flag then
		local name = region.official or region.name
		local flagFile = region.flag
		tooltip = region[tooltip] or region.name
		local flag = string.format('<span class="%s" title="%s">[[%s|%s|%s]]</span>', CLASS_TOOLTIP, tooltip, flagFile, size, tooltip)
		return {flag}, ""
	elseif region.countries then
		local flags = {}
		for i, country in ipairs(region.countries) do
			local countryRegion = p.getRegion(country, {
				flagSize = size,
				flagTooltip = tooltip,
			})
			table.insert(flags, countryRegion.flags[1])
		end
		return flags, ""
	else
		return {""}, ""
	end
end

function p.Documentation(frame)
	return {
		enum = {
			params = {"options"},
			returns = {
				"A list of region codes.",
			},
			cases = {
				outputOnly = true,
				{
					args = {},
				},
				{
					args = {{ sortBy = "abbr" }}
				},
			},
		},
		getRegion = {
			params = {"code", "options"},
			returns = {
				"An object containing the region's name and flag(s), or <code>nil</code> if no region exists for the given code.",
				"An error category if no region exists for the given code.",
			},
		},
	}
end

function p.Schemas(frame)
	return {
		enum = {
			options = {
				type = "record",
				properties = {
					{
						name = "sortBy",
						type = "string",
						default = "name",
						desc = "Region property to sort by. Options are <code>abbr</code>, <code>code</code>, <code>official</code>, and <code>name</code> (default). By exception, USA and Japan are always placed first, as they are the native regions of this wiki and of Nintendo, respectively.",
					},
				},
			},
		},
		getRegion = {
			code = {
				required = true,
				type = "string",
				desc = "A region code from [[Module:Region/Data]]."
			},
			options = {
				type = "record",
				properties = {
					{
						name = "flagSize",
						type = "string",
						default = DEFAULT_FLAG_SIZE,
						desc = "The image size to use for the region's flag(s).",
					},
					{
						name = "flagTooltip",
						type = "string",
						default = "official",
						desc = "<code>name</code> or <code>official</code>. Determines which name is used as the flag's tooltip.",
					},
				},
			},
		},
		Data = {
			type = "record",
			required = true,
			properties = {
				{
					name = "regions",
					required = true,
					type = "map",
					desc = "A list of regions that Nintendo (or other Zelda-related companies) markets to.",
					keyPlaceholder = "code",
					keys = {
						type = "string",
						desc = "An {{Wp|ISO 3166-1 alpha-2}} country code, or a 3+ character code denoting a multi-country region forming a single market segment.",
					},
					values = {
						type = "record",
						properties = {
							{
								name = "name",
								required = true,
								type = "string",
								desc = "The name of the country or region.",
							},
							{
								name = "abbr",
								required = true,
								type = "string",
								desc = "Abbreviated name for the region, used by [[Template:Release]]. For countries, this should be the {{Wp|ISO 3166-1 alpha-3}} country code. For multi-country regions, use a character abbreviation that is not a reserved ISO 3166-1 code.",
							},
							{
								name = "flag",
								type = "string",
								desc = "The file name of the region's flag",
							},
							{
								name = "official",
								type = "string",
								desc = "The official state name of the country, used as the flag's tooltip. Defaults to <code>name</code>.",
							},
							{
								name = "countries",
								type = "array",
								items = { type = "string" },
								desc = "For multi-country regions, a list of country codes that comprise the region.",
							},
						},
					},
				},
			},
		}
	}
end

function p.Data(frame)
	local utilsLayout = require("Module:UtilsLayout")
	local utilsTable = require("Module:UtilsTable")

	local countries = {}
	local multiCountryRegions = {}
	
	for code in pairs(Data.regions) do
		local region = p.getRegion(code)
		local row = {
			id = code,
			cells = {
				"<code>"..code.."</code>",
				table.concat(region.flags, " "),
				region.abbr,
				region.name,
			}
		}
		if code:len() == 2 then
			table.insert(countries, row)
		else
			table.insert(multiCountryRegions, row)
		end
	end
	countries = utilsTable.sortBy(countries, "id")
	multiCountryRegions = utilsTable.sortBy(multiCountryRegions, "id")
	
	
	local countriesTable = utilsLayout.table({
		caption = "Countries",
		sortable = {1, 3, 4},
		headers = {"{{Wp|ISO 3166-1 alpha-2|Code}}", "Flag", "Abbr.", "Name"},
		rows = countries,
	})
	local multiCountryRegionsTable = utilsLayout.table({
		caption = "Multi-Country Regions",
		sortable = {1, 3},
		headers = {"Code", "Flags", "Abbr.", "Name"},
		rows = multiCountryRegions,
	})

	local html = mw.html.create("div")
		:css({
			["display"] = "flex",
			["flex-wrap"] = "wrap",
			["gap"] = "1rem",
		})
		:wikitext(countriesTable)
		:wikitext(multiCountryRegionsTable)

	return tostring(html)
end

p.Templates = {
	["Flag"] = {
		purpose = "Displays a region's [[:Category:Flags|flag(s)]].",
		params = {
			[1] = {
				name = "code",
				required = true,
				type = "string",
				enum = p.enum(),
				desc = "A code representing a region. For countries, this is the {{Wp|ISO 3166-1 alpha-2}} code.",
				trim = true,
				nilIfEmpty = true,
			},
			[2] = {
				name = "size",
				type = "string",
				default = DEFAULT_FLAG_SIZE,
				desc = "An {{MediaWiki|Help:Images#Size_and_frame|image size}}."
			},
		},
	}
}

return p