Module:Region

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search

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