Module:Guide

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search
This is the main module for the following templates:
local p = {}
local h = {}

local utilsArg = require("Module:UtilsArg")
local utilsError = require("Module:UtilsError")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")

local Data = mw.loadData("Module:Guide/Data")
local CATEGORY_INVALID_ARGS = "[[Category:"..require("Module:Constants/category/invalidArgs").."]]"

-- [[Template:eGuide]]
function p.eGuide(frame)
	return p.guide(frame:getParent().args, "eGuide")
end

-- [[Template:Guide]]
function p.Guide(frame)
	return p.guide(frame:getParent().args, "Guide")
end

-- Used by [[Module:Cite]]
function p.guide(frameArgs, template, returnPublisher)
	local guideData
	if template == "eGuide" then
		guideData = Data.eGuides
	else
		guideData = Data.guides
	end
	
	local args, err = utilsArg.parse(frameArgs, p.Templates[template])
	local game, guideId, omitPublisher = args.game, args.guide, args.omitPublisher
	local categories = err and err.categoryText or ""
	
	if utilsString.isBlank(game) then
		return utilsError.error("game required"), categories
	elseif utilsString.isBlank(guideId) then
		return utilsError.error("guide required"), categories
	end
	
	local gameGuides = guideData[game]
	local guide = gameGuides and gameGuides[guideId]
	
	if gameGuides == nil then
		categories = categories..CATEGORY_INVALID_ARGS
		return utilsError.error("invalid game guide", string.format("Invalid game <code>%s</code>. For a list of supported game guides, see [[Template:%s#Supported Guides]].", game, template)), categories
	elseif guide == nil then
		categories = categories..CATEGORY_INVALID_ARGS
		return utilsError.error("invalid game guide", string.format("Guide <code>%s</code> is invalid for game <code>%s</code>. For a list of supported game guides, see [[Template:%s#Supported Guides]].", guideId, game, template)), categories
	end
	
	local result = p.link(guide.guide)
	if not omitPublisher then
		result = result .. " by [["..guide.by.."]]"
	end
	if returnPublisher then
		return result, categories, guide.publisher or guide.by
	else
		return result, categories
	end
end
-- Strips (eGuide) from the link text if the page name ends with it
function p.link(guidePage)
	local endMarker = "endMarker"
	local index = string.find(guidePage..endMarker, " %(eGuide%)"..endMarker)
	local linkText = guidePage
	if index ~= nil then
		linkText = string.sub(guidePage, 1, index-1)
	end
	return string.format("''[[%s|%s]]''", guidePage, linkText)
end

function p.Data(frame)
	local utilsLayout = require("Module:UtilsLayout")
	
	local template = frame:getParent():getTitle()
	if template == "Template:Guide/Documentation" then
		return p.guideTable("Guide", "guides")
	elseif template == "Template:EGuide/Documentation" then
		return p.guideTable("eGuide", "eGuides")
	else
		return utilsLayout.tabs({
			{
				label = "Guides",
				content = p.guideTable("Guide", "guides"),
			},
			{
				label = "eGuides",
				content = p.guideTable("eGuide", "eGuides")
			}
		})
	end
end
function p.guideTable(template, guideType)
	local Franchise = require("Module:Franchise")
	local utilsLayout = require("Module:UtilsLayout")
	
	local games = Franchise.enum({ includeGroups = true })
	local rows = {}
	for i, game in ipairs(games) do
		local gameGuides = Data[guideType][game] or {}
		gameGuides = utilsTable.keys(gameGuides)
		table.sort(gameGuides)
		local gameRows = utilsTable.map(gameGuides, function(guide)
			local input = string.format("<code><nowiki>{{%s|%s|%s}}</nowiki></code>", template, game, guide)
			local output = mw.getCurrentFrame():expandTemplate({
				title = template,
				args = {game, guide}
			})
			return {input, output}
		end)
		rows = utilsTable.concat(rows, gameRows)
	end
	local wikitable = utilsLayout.table({
		headers = {"Input", "Output"},
		rows = rows,
	})
	return wikitable
end

local params = {
	[1] = {
		name = "game",
		type = "string",
		required = true,
		desc = "A game abbreviation. See [[#Supported Guides]].",
		trim = true,
		nilIfEmpty = true,
	},
	[2] = {
		name = "guide",
		type = "string",
		required = true,
		desc = "A guide name abbreviation. See [[#Supported Guides]].",
		trim = true,
		nilIfEmpty = true,
	},
	[3] = {
		name = "omitPublisher",
		type = "boolean",
		desc = "If present, the author/publisher link is omitted and only the magazine link is shown.",
		canOmit = true,
	},
}
p.Templates = {
	["Guide"] = {
		purpose = "Formatting links to guides.",
		params = params,
		examples = {
			{"ALttP", "Nintendo"},
			{"ALttP&FS", "Nintendo"},
			{"BotW", "Piggyback", "-"},
			{
				desc = "Error handling",
				args = {"OoT3D", "invalid guide"},
			},
			{"invalid game", "Nintendo"},
			{"OoT3D", ""},
			{"", ""},
		}
	},
	["eGuide"] = {
		purpose = "Formatting links to eGuides.",
		params = params,
		examples = {
			{"ST", "Prima"},
			{"BotW", "Piggyback", "-"},
			{
				desc = "Error handling",
				args = {"OoT3D", "invalid guide"},
			},
			{"invalid game", "Nintendo"},
			{"OoT3D", ""},
			{"", ""},
		},
	},
}

function p.Schemas()
	return {
		Data = {
			type = "record",
			required = true,
			properties = {
				{
					_id = "#guides",
					name = "eGuides",
					required = true,
					type = "map",
					keyPlaceholder = "game",
					keys = { type = "string" },
					values = {
						type = "map",
						keyPlaceholder = "guideInput",
						keys = { type = "string" },
						values = {
							type = "record",
							properties = {
								{
									name = "guide",
									type = "string",
									required = true,
									desc = "The wiki page for the guide.",
								},
								{
									name = "by",
									type = "string",
									required = true,
									desc = "The wiki page for the company or team that authored the guide.",
								},
								{
									name = "publisher",
									type = "string",
									desc = "The name of the publisher if different from the above.",
								},
							},
						},
					},
				},
				{
					name = "guides",
					_ref = "#guides",
				},
			},
		},
	}
end

return p