Module:Term

From Zelda Wiki, the Zelda encyclopedia
Revision as of 10:57, 27 June 2020 by PhantomCaleb (talk | contribs) (ignore # if used in page name)
Jump to: navigation, search

Lua error in package.lua at line 80: module 'Module:UtilsGame' not found.


local p = {}
local h = {}

local utilsArg = require("Module:UtilsArg")
local utilsCargo = require("Module:UtilsCargo")
local utilsError = require("Module:UtilsError")
local utilsGame = require("Module:UtilsGame")
local utilsMarkup = require("Module:UtilsMarkup")
local utilsPage = require("Module:UtilsPage")
local utilsString = require('Module:UtilsString')
local utilsTable = require('Module:UtilsTable')

local CARGO_TABLE = "Terminologies"

function p.Singular(frame)
	local args, err = utilsArg.parse(frame:getParent().args, p.Templates.Term)
	local printErrorCategories = not utilsPage.inNamespace({"User", "MediaWiki"}) -- MediaWiki namespace is listed here to prevent a weird bug with MediaWiki:Gadget-EditToolbarButtons.js
	local result = p.printTerm(args, false, printErrorCategories)
	if err and printErrorCategories then 
		result = result .. utilsMarkup.categories(err.categories)
	end
	return result
end

function p.Plural(frame)
	local args, err = utilsArg.parse(frame:getParent().args, p.Templates.Plural)
	local printErrorCategories = not utilsPage.inNamespace({"User", "MediaWiki"})
	local result = p.printTerm(args, true, printErrorCategories)
	if err and printErrorCategories then
		result = result .. utilsMarkup.categories(err.categories)
	end
	return result
end

function p._fetchTerm(frame)
	local args = frame.args
	args = utilsTable.mapValues(args, utilsString.trim)
	args = utilsTable.mapValues(args, utilsString.nilIfEmpty)
	return p.fetchTerm(args.term, args.game)
end

function p.printTerm(args, plural, printErrorCategories)
	local term, fetchErrors = p.fetchTerm(args.page, args.game, plural or args.plural)
	
	local errorCategories = ""
	if printErrorCategories then
		local errors = utilsTable.concat(validationErrors or {}, fetchErrors or {})
		errorCategories = utilsMarkup.categories(errors)
	end
	local result = ""
	if not term then
		local errLink = utilsMarkup.sectionLink(args.page, args.section, args.display)
		result = utilsMarkup.inline(errLink, {
			class = "facelift-term-invalid",
			tooltip = "Invalid or missing term",
		})
	elseif args.link == "link" then
		local gameSub = utilsGame.AbbToBaseGame(args.game, true)
		if not args.section and gameSub ~= "Unknown" and args.game ~= "Series" then
			args.section = gameSub
		end
		result = utilsMarkup.sectionLink(args.page, args.section, args.display or term)
	else
		result = utilsMarkup.class("term", args.display or term)
	end
	return result .. errorCategories
end

function p.fetchTerm(page, game, plural)
	if not page then
		return nil
	end
	
	-- Cargo queries don't allow # and it's impossible to have a page with # anyway because of section anchors. 
	 -- Ideally, users should input the name of the page where the term is stored (e.g. Swordsman Newsletter 4 instead of Swordsman Newsletter #4)
	page = string.gsub(page, "#", "")
	
	-- Things like {{PAGENAME}} return HTML entities. These have to be removed as the "#" character cannot be used in Cargo queries.
	page = mw.text.decode(page) 
	local rows = utilsCargo.query("Terminologies=terms, Terminologies__games=termGames", "termGames._value=game, terms.term=term, terms.plural=plural", {
		join = "terms._ID=termGames._rowID",
		where = utilsCargo.allOf(
			{ _pageName = page },
			utilsCargo.IN("termGames._value", {"Series", game})
		)
	})
	local termsByGame = utilsTable.keyBy(rows, "game")
	local term = termsByGame[game or "Series"] or termsByGame["Series"]
	local subtitle = utilsGame.AbbToGame(game or "Series")
	local errCategories = {}
	if mw.title.getCurrentTitle().nsText ~= "User" then
		table.insert(errCategories, "Pages with Invalid or Missing Terms")
		if subtitle ~= "Unknown" then
			table.insert(errCategories, string.format("%s Pages with Invalid or Missing Terms", subtitle))
		end
	end
	if not term then
		return nil, errCategories
	elseif plural and utilsString.isEmpty(term.plural) then
		utilsError.warn(string.format("Term <code>%s</code> has no plural form defined. Using singular form.", term.term))
		return term.term, errCategories
	elseif plural then
		return term.plural
	else
		return term.term
	end
end

function p.fetchSubjects(term, game)
	local rows = utilsCargo.query(CARGO_TABLE, "_pageName", {
		where = utilsCargo.allOf(
			{ term = term },
			game and ("games HOLDS '%s'"):format(game)
		)
	})
	return utilsTable.map(rows, "_pageName")
end

p.Schemas = {
	fetchTerm = {
		page = {
			type = "string",
			required = true,
			desc = "The name of a wiki article from which to retrieve a term.",
		},
		game = {
			type = "string",
			default = mw.dumpObject("Series"),
			desc = "A game code. See [[Module:UtilsGame]].",
		},
		plural = {
			type = "boolean",
			desc = "If true, retrieves the plural form."
		},
	},
	fetchSubjects = {
		term = {
			type = "string",
			required = true,
		},
		game = {
			type = "string"
		}
	}
}

p.Documentation = {
	fetchTerm = {
		params = {"page", "game", "plural"},
		returns = {
			"The term for the given article and game, or nil if none found.",
			"An error category if no term was found.",
		},
		cases = {
			outputOnly = true,
			{
				args = {"Dynalfos", "OoT"},
				expect = { "Dinolfos", nil },
			},
			{
				desc = "Defaults to series term.",
				args = {"Dinolfos"},
				expect = {"Dynalfos"},
			},
			{
				desc = "Defaults to series term when term does not exist for specified game.",
				args = {"Dinolfos", "ALttP"},
				expect = {"Dynalfos"},
			},
			{
				desc = "Error when page does store any terms (game specified).",
				args = {"Flippityfloppito", "SS"},
				expect = {nil, {"Pages with Invalid or Missing Terms", "Skyward Sword Pages with Invalid or Missing Terms"}}
			},
			{
				desc = "Error when page does store any terms (no game specified).",
				args = {"Flippityfloppityfloo"},
				expect = {nil, {"Pages with Invalid or Missing Terms", "The Legend of Zelda Series Pages with Invalid or Missing Terms"}}
			},
			{
				desc = "Plural",
				args = {"Bubble", "Series", true},
				expect = {"Bubbles", nil},
			},
			{
				desc = "Returns singular when no plural form exists.",
				args = {"A Brother's Roast", "BotW", true},
				expect = { "A Brother's Roast", {
				  "Pages with Invalid or Missing Terms",
				  "Breath of the Wild Pages with Invalid or Missing Terms",
				}}
			}
		},
	},
	fetchSubjects = {
		params = {"term", "game"},
		returns = "Returns the names of wiki pages that store the given term. If game is specified, the function will only return pages that store the term for that game.",
		cases = {
			{
				args = {"Wood"},
				expect = {"Wood", "Wood (Character)"},
			},
			{
				args = {"Wood", "ST"},
				expect = {"Wood (Character)"},
			},
			{
				args = {"Link", "MM"},
				expect = {"Link", "Link (Goron)"},
			},
			{
				args = {"Fooloo Limpah"},
				expect = {},
			},
		},
	}
}

p.Templates = {
	Term = {
		purpose = "Returns the proper singular form of a term for any given topic in {{TLoZ|Series}}. Terms are stored using [[:Template:Term/Store]].",
		format = "inline",
		params = {
			[1] = {
				name = "game",
				type = "string",
				enum = utilsGame.getEnum(),
				desc = "The game from which to fetch the term of the given subject. Defaults to <code>Series</code>.",
				trim = true,
				nilIfEmpty = true,
			},
			[2] = {
				name = "page",
				type = "wiki-page-name",
				desc = "The name of the page for said subject.",
				trim = true,
				nilIfEmpty = true,
			},
			[3] = {
				name = "link",
				type = "string",
				desc = "Entering anything in this field will output the result as a link. (Enter <code>link</code> for standardization)",
				trim = true,
				nilIfEmpty = true,
			},
			[4] = {
				name = "plural",
				type = "string",
				deprecated = true,
				desc = "Deprecated.",
				trim = true,
				nilIfEmpty = true,
			},
			display = {
				type = "string",
				desc = "Alternative display text for term.",
				trim = true,
				nilIfEmpty = true,
			},
			section = {
				type = "string",
				desc = "Section of <code>page</code> to link to.",
				trim = true,
				nilIfEmpty = true,
			},
		}
	}
}
p.Templates.Plural = p.Templates.Term

return p