Module:Infobox

From Zelda Wiki, the Zelda encyclopedia
Revision as of 02:04, 13 October 2022 by PhantomCaleb (talk | contribs)
Jump to navigation Jump to search

Lua error in Module:Documentation/Module at line 333: attempt to call field 'Documentation' (a table value).


local p = {}

local Constants = mw.loadData("Module:Constants/Data")

local Franchise = require("Module:Franchise")
local utilsArg = require("Module:UtilsArg")
local utilsMarkup = require("Module:UtilsMarkup")
local utilsPackage = require("Module:UtilsPackage")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")
local _utilsError = utilsPackage.lazyLoad("Module:UtilsError")

local CATEGORY_INVALID_ARGS = "[[Category:"..Constants.category.invalidArgs.."]]"
local CATEGORY_PARAM_CAPTION = "[[Category:Infoboxes Using Captions]]"
local CATEGORY_PARAM_NAME = "[[Category:Infoboxes Using the Name Parameter]]"
local CATEGORY_BR_TAGS = "[[Category:Infoboxes Using br Tags]]"
local BR_TAGS_MSG = "Using <code><nowiki><br></nowiki></code> tags to create lists is discouraged. See [[:Category:Infoboxes Using br Tags]] for more information."

function p.Main(frame)
	local templateName = "Infobox "..frame:getParent():getTitle()
	
	local args, err, categories
	local templateSpec = p.Templates[templateName]
	if templateSpec then
		args, err = utilsArg.parse(frame:getParent().args, templateSpec)
	else
		args = frame:getParent().args
	end
	categories = err and err.categoryText or ""
	
	if args.name and args.name ~= "" then
		categories = categories..CATEGORY_PARAM_NAME
	end
	if args.caption and args.caption ~= "" then
		categories = categories..CATEGORY_PARAM_CAPTION
	end
	
	return categories
end

function p.List(frame)
	listItems = frame.args[1]
	if listItems == nil or listItems == "" then
		return nil
	end

	if string.find(listItems, "<br") then
		_utilsError().warn(BR_TAGS_MSG)
		return listItems..CATEGORY_BR_TAGS
	end

	listItems = utilsString.trim(listItems)
	listItems = utilsString.split(listItems)
	if #listItems == 1 then
		return listItems[1]
	else
		return utilsMarkup.list(listItems)
	end
end

function p.Games(frame)
	local games = frame.args[1]
	local categories = ""

	if games == nil or games == "" then
		return nil
	end

	if string.find(games, "<br") then
		_utilsError().warn(BR_TAGS_MSG)
		categories = categories..CATEGORY_BR_TAGS
		return games, categories
	end
	
	games = utilsString.trim(games)
	games = utilsString.split(games)
	local gameLinks = utilsTable.map(games, p.link)
	local gameLinks = utilsTable.compact(gameLinks)
	if #gameLinks ~= #games then
		categories = categories..CATEGORY_INVALID_ARGS
	end
	
	if #gameLinks == 1 then
		return gameLinks[1], categories
	else
		local gameList = utilsMarkup.list(gameLinks)
		return gameList, categories
	end
end
function p.link(game)
	if utilsMarkup.containsLink(game) then
		return game
	end
	local link = Franchise.link(game)
	local properCode = Franchise.code(game)
	if not link then
		_utilsError().warn(string.format("Invalid entry <code>%s</code>. See [[Data:Franchise]] for a list of valid entries.", game))
		return nil
	elseif properCode and properCode ~= game then
		_utilsError().warn(string.format("<code>%s</code> should be written as <code>%s</code>", game, properCode))
	end
	return link
end

function p.GameBlocks(frame)
	local args = frame:getParent().args
	local categories = ""

	local seenParams = {}
	local blocks = {}
	for i, game in ipairs(Franchise.enum({ includeSeries = true })) do
		seenParams[game] = true
		local listItems = args[game]
		listItems = listItems and utilsString.trim(listItems)
		listItems = listItems and utilsString.nilIfEmpty(listItems)
		if listItems then
			table.insert(blocks, {
				game = Franchise.display(game), 
				listItems = args[game],
			})
		end
	end

	for k, v in pairs(args) do
		if not seenParams[k] then
			local errorMessage = string.format("Invalid game <code>%s</code>", k)
			_utilsError().warn(errorMessage)
			categories = categories..CATEGORY_INVALID_ARGS
		end
	end
	
	local html = mw.html.create("ul")
		:addClass("infobox-game-blocks")
	for i, block in ipairs(blocks) do
		local gameList = html:tag("li")
			:tag("span")
				:addClass("infobox-game-blocks__game")
				:wikitext(block.game)
				:done()
			:tag("ul")
				:addClass("infobox-game-blocks__game-list")
		local listItems = block.listItems
		if string.find(listItems, "<br") then
			_utilsError().warn(BR_TAGS_MSG)
			categories = categories..CATEGORY_BR_TAGS
			gameList:tag("li")
				:wikitext(listItems)
				:done()
		else
			listItems = utilsString.split(listItems)
			for j, listItem in ipairs(listItems) do
				gameList:tag("li")
					:wikitext(listItem)
			end
		end
	end
	
	return tostring(html), categories
end

local templateSpec = function(args)
	local singular = args.singular
	local plural = args.plural
	local params = args.params
	local productionParams = args.productionParams
	local imageSuchAs = args.imageSuchAs

	local spec = {
		format = "block",
		purpose = string.format("[[Guidelines:Articles#Infobox|Infobox]] for [[:Category:%s|%s]].", plural, string.lower(plural)),
		categories = {"Infobox Templates"},
		boilerplate = {
			separateRequiredParams = false,	
		},
		paramOrder = {"name", "image", "caption"},
		params = {
			name = {
				desc = "<p>Name to use in the infobox header. Defaults to {{Template|Page Name}}.</p><p>In general, this parameter should be omitted unless the title requires italics.</p>",
				type = "content",
			},
			image = {
				desc = string.format("An image to represent the %s, such as %s.", singular, imageSuchAs),
				type = "wiki-file-name",
			},
			caption = {
				desc = "A caption for the image.",
				type = "content",
			}
		},
	}
	for i, param in ipairs(params or {}) do
		spec.params[param.name] = param
		table.insert(spec.paramOrder, param.name)
	end
	for i, param in ipairs(productionParams or {}) do
		spec.params[param.name] = param
		table.insert(spec.paramOrder, param.name)
	end
	
	return spec
end

local released = {
	name = "released",
	desc = "Release date(s) of the film. Use [[Template:Release]].",
	type = "content",
}

p.Templates = {
	["Infobox Game Blocks"] = {},
	["Infobox Film"] = templateSpec({
		singular = "film",
		plural = "films",
		imageSuchAs = "a release poster or a DVD cover",
		params = {
			{
				name = "director",
				desc = "The director(s) of the film.",
				type = "content",
			},
			{
				name = "producer",
				desc = "The producer(s) of the film.",
				type = "content",
			},
			{
				name = "country",
				desc = "Country or countries of production.",	
			},
			released,
		}
	}),
	["Infobox Television"] = templateSpec({
		singular = "television",
		plural = "television",
		imageSuchAs = "the series' logo or title card",
		params = {
			{
				name = "basedOn",
				type = "string",
				desc = "Comma separated list of [[Data:Franchise|games]] that the series is based on.",
				enum = Franchise.enum(),
				trim = true,
				split = true,
			},
			{
				name = "seasons",
				type = "content",
				desc = "Number of seasons.",
			},
			{
				name = "episodes",
				type = "content",
				desc = "Number of total episodes.",
			},
			{
				name = "company",
				type = "content",
				desc = "Production comapany or companies.",
			},
			{
				name = "distributor",
				type = "content",
				desc = "Distributor(s) of the television series.",
			},
			released,
		}
	})
}

p.Documentation = {
	List = {
		desc = "Used by [[:Category:Infobox Templates|infobox templates]] to turn comma-separated input into lists.",
		frameParams = {
			[1] = {
				name = "param",
				desc = "The infobox parameter",
			},
		},
		cases = {
			{
				args = {"A, B, C"}
			},
			{
				desc = "{{Template|,}} can be used to escape commas when an item itself contains a comma.",
				args = {"[[The Way of Sumo{{,}} Part I]], [[The Way of Sumo{{,}} Part II]], [[The Way of Sumo{{,}} Part III]]"},
			},
			{
				args = {"A"},
			},
			{
				args = {""},
			},
			{
				args = {},
			},
			{
				desc = "br tags are discouraged due to the poor HTML semantics.",
				args = {"A<br>B<br>C"},
			}
		},
	},
	Games = {
		desc = "Used by [[:Category:Infobox Templates|infobox templates]] to turn comma-separated [[Data:Franchise|game codes]] into lists of games.",
		frameParams = {
			[1] = {
				name = "param",
				desc = "The infobox parameter, usually <code><nowiki>{{{game|}}}</nowiki></code> or <code><nowiki>{{{other|}}}</nowiki></code>.",
			},
		},
		cases = {
			{
				args = {"TLoZ, TAoL, ALttP"},
			},
			{
				args = {"TLoZ (Ran), BoMC, TLoZ (Susumu)"},
			},
			{
				args = {""},
			},
			{
				args = {},
			},
			{
				args = {"invalid game"},
			},
			{
				args = {"OoT, invalid game, TP"},
			},
			{
				desc = "br tags are discouraged due to the poor HTML semantics.",
				args = {"{{OoT}}<br>{{TP}}<br>{{TotK}}"},
			},
		}
	},
}

return p