Zelda Wiki

Want to contribute to this wiki?
Sign up for an account, and get started!

Come join the Zelda Wiki community Discord server!

READ MORE

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

gameImage

gameImage(game, subject, type, [options])

A specialized version of image that infers the filename from game, subject, and type.

Parameters

Returns

  • A string of wikitext that renders a thumbnail.
  • A boolean — true if the image exists, false otherwise.

Examples

#InputOutputResultStatus
1
gameImage(
  "TWW",
  "Great Fairy Figurine",
  "Model",
  {
    size = "100px",
    link = "Great Fairy",
  }
)
Expected
"[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy|TWW Great Fairy Figurine Model.png]]"
Actual
"[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy]]"
TWW Great Fairy Figurine Model
TFH Red Link desperate
true
Green check

icon

icon(game, subject, [options])

Parameters

Returns

  • An icon thumbnail for the subject in the given game.

Examples

#InputOutputResultStatus
2
icon("LANS", "Pineapple")
Expected
"[[File:LANS Pineapple Icon.png|LANS Pineapple Icon.png]]"
Actual
"[[File:LANS Pineapple Icon.png]]"
LANS Pineapple Icon
TFH Red Link desperate
3
icon("LADX", "Pineapple")
Expected
"[[File:LADX Pineapple Sprite.png|LADX Pineapple Sprite.png]]"
Actual
"[[File:LADX Pineapple Sprite.png]]"
LADX Pineapple Sprite
TFH Red Link desperate

image

image(filename, [options])

A higher-level version of utilsMarkup.file with awareness of whether the file exists or not.

Parameters

Returns

  • Wikitext rendering an image thumbnail.
  • A boolean — true if the image exists, false otherwise.

Examples

#InputOutputResultStatus
4
image(
  "File:TWW Great Fairy Figurine Model.png",
  {
    size = "100px",
    link = "Great Fairy",
  }
)
Expected
"[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy|TWW Great Fairy Figurine Model.png]]"
Actual
"[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy]]"
TWW Great Fairy Figurine Model
TFH Red Link desperate
true
Green check
If file does not exist, show 'click to upload' thumbnail which links to Special:Upload.
5
image(
  "File:TWWHD Great Fairy Figurine Model.png",
  {
    size = "150px",
    link = "Great Fairy",
  }
)
Expected
"[[File:No Image Upload.png|150px|link=https://zelda.gamepedia.com/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png|File:No Image Upload.png]]"
Actual
"[[File:No Image Upload.png|150px|link=https://zelda.fandom.com/wiki/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png]]"
No Image Upload
TFH Red Link desperate
false
Green check
'No image' thumbnail has minimum 100px width, because it is illegible at smaller sizes.
6
image(
  "File:TWWHD Great Fairy Figurine Model.png",
  { size = "64px" }
)
Expected
"[[File:No Image Upload.png|100px|link=https://zelda.gamepedia.com/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png|File:No Image Upload.png]]"
Actual
"[[File:No Image Upload.png|100px|link=https://zelda.fandom.com/wiki/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png]]"
No Image Upload
TFH Red Link desperate
false
Green check

logo(code, options)

Parameters

Returns

  • Given a valid franchise code, returns a logo thumbnail.
  • A boolean indicating whether a logo exists for the game yet.

Examples

#InputOutputResultStatus
7
logo("LANS", { size = "200px" })
Expected
"[[File:LANS English Logo.png|200px|LANS English Logo.png]]"
Actual
"[[File:LANS English Logo 2.png|200px]]"
LANS English Logo 2
TFH Red Link desperate
true
Green check
8
logo("SSB4", { size = "200px" })
Expected
"[[File:SSB4 Logo.png|200px|SSB4 Logo.png]]"
Actual
"[[File:SSB4 Logo.png|200px]]"
SSB4 Logo
TFH Red Link desperate
true
Green check
9
logo("SS (Himekawa)", { size = "200px" })
Expected
"[[File:Viz Media Logo.svg|200px|Viz Media Logo.svg]]"
Actual
"[[File:Viz Media Logo.svg|200px]]"
Viz Media Logo
TFH Red Link desperate
true
Green check
10
logo("TLoZ (Mishouzaki)", { size = "200px" })
Expected
"[[File:TLoZ (Mishouzaki) Manga Cover Artwork.png|200px|TLoZ (Mishouzaki) Manga Cover Artwork.png]]"
Actual
"[[File:TLoZ (Mishouzaki) Manga Cover Artwork.png|200px]]"
TLoZ (Mishouzaki) Manga Cover Artwork
TFH Red Link desperate
true
Green check
11
logo("TAoL (Mishouzaki)", { size = "200px" })
Expected
"[[File:No Image Upload.png|200px|link=https://zelda.gamepedia.com/Special:Upload?wpDestFile=TAoL+%28Mishouzaki%29+Manga+Cover+Artwork.png|File:No Image Upload.png]]"
Actual
"[[File:No Image Upload.png|200px|link=https://zelda.fandom.com/wiki/Special:Upload?wpDestFile=TAoL+%28Mishouzaki%29+Manga+Cover+Artwork.png]]"
No Image Upload
TFH Red Link desperate
false
Green check
12
logo("E", { size = "200px" })
Expected
"[[File:The Legend of Zelda Encyclopedia Cover.png|200px|The Legend of Zelda Encyclopedia Cover.png]]"
Actual
"[[File:The Legend of Zelda Encyclopedia Cover.png|200px]]"
The Legend of Zelda Encyclopedia Cover
TFH Red Link desperate
true
Green check
13
logo("TMoL", { size = "200px" })
Expected
"[[File:Misadventures Link logo2.png|200px|Misadventures Link logo2.png]]"
Actual
"[[File:Misadventures Link logo2.png|200px]]"
Misadventures Link logo2
TFH Red Link desperate
true
Green check

local p = {}
local h = {}

local Franchise = require("Module:Franchise")
local Term = require("Module:Term")
local utilsArg = require("Module:UtilsArg")
local utilsLayout = require("Module:UtilsLayout")
local utilsMarkup = require("Module:UtilsMarkup")
local utilsPage = require("Module:UtilsPage")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")

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

-- Template:FileInfo
function p.StoreWidth(frame)
	return mw.title.getCurrentTitle().file.width
end
function p.StoreHeight(frame)
	return mw.title.getCurrentTitle().file.height
end
function p.FileInfo(frame)
	local args, err = utilsArg.parse(frame:getParent().args, p.Templates.FileInfo)
	local result = p.printFileInfo(args)
	if err then
		return result .. utilsMarkup.categories(err.categories)
	else
		return result
	end
end
function p.printFileInfo(args)
	return h.printFileInfoTable(args) .. h.categories(args.type, args.game, args.subject)
end
function h.printFileInfoTable(args)
	local gameDisplay
	if args.game then
		local gameLogo = Franchise.logo(args.game)
		local gameImage = gameLogo and utilsPage.exists(gameLogo) and utilsMarkup.file(gameLogo, { size = "130px" })
		local gameLink = Franchise.link(args.game)
		local gameText = gameLink and string.format("This is a file pertaining to %s.", gameLink)
		if gameImage and gameText then
			gameDisplay = gameImage .. " " .. gameText
		elseif gameText then
			gameDisplay = gameText
		else
			gameDisplay = ""
		end
	end
	
	local type = args.type and data.typesByKey[args.type]
	type = type and type.cat

	local license = args.licensing and mw.getCurrentFrame():expandTemplate({
		title = "FileInfo/" .. args.licensing,
		args = {
			trademark = args.trademark
		}
	})

	local html = mw.html.create("table"):addClass("FileInfo")
	h.row(html, "Summary", args.summary)
	h.row(html, "Type", type)
	h.row(html, "Game", gameDisplay)
	h.row(html, "Licensing", license, {
		rowspan = args.trademark and "2" or "1" 
	})
	h.row(html, "Trademark", args.trademark and mw.getCurrentFrame():expandTemplate({ title = "FileInfo/Trademark" }))
	
	return tostring(html)
end
function h.row(html, field, value, attributes)
	if value then
		return html
			:tag("tr")
			:tag("th")
				:wikitext(field)
				:done()
			:tag("td")
				:wikitext(value)
				:done()
			:done()
	end
end
function h.categories(type, game, subjects)
	local gameName = game and Franchise.shortName(game)
	local typeCat = type and data.typesByKey[type] and data.typesByKey[type].cat
	
	local categories = {}
	if typeCat and not typeCat.nogame and gameName and game ~= "Series" then
		table.insert(categories, gameName .. " " .. typeCat)
	elseif typeCat then
		table.insert(categories, typeCat)
	elseif gameCat then
		table.insert(categories, gameName .. " Files")
	end
	if subjects then
		categories = utilsTable.concat(categories, h.subjectCategories(subjects, game))
	end
	
	return utilsMarkup.categories(categories)
end
function h.subjectCategories(subjects, game)
	local categories = utilsTable.flatMap(subjects, function(subject)
		local term, err = Term.fetchTerm(subject, game)
		if not term then
			return err.categories -- add term-related maintenance categories, if any
		end
		term = string.gsub(term, "#", "") -- strip # from term because categories can't have them in their name
		local category = "Images of "..term
		 -- only add subject-based categories if they already exist, to avoid spamming Special:WantedCategories
		if utilsPage.exists(category) then
			return {category}
		else
			return {}
		end
	end)
	return categories
end

-- Module:File/Data
function p.Data(frame)
	local result = ""
	
	result = result .. utilsMarkup.heading(2, "Types")
	result = result .. utilsLayout.table({
		sortable = true,
		headers = {"Type", "Category"},
		rows = utilsTable.map(data.types, function(type)
			local key = utilsMarkup.code(type.key)
			local cat = "[[:Category:"..type.cat.."]]"
			return {key, cat}
		end)
	})
	
	result = result .. utilsMarkup.heading(2, "Licenses")
	result = result .. utilsLayout.table({
		sortable = true,
		headers = {"License", "Template", "Output"},
		rows = utilsTable.map(data.licenses, function(license)
			local template = "FileInfo/"..license
			local templateLink = "[[Template:"..template.."]]"
			local templateOutput = mw.getCurrentFrame():expandTemplate({title = template})
			return {utilsMarkup.code(license), templateLink, templateOutput} 
		end)
	})

	return result
end

-- Various templates
function p.Icon(frame)
	local args = frame.args
	return p.icon(args[1], args[2], {
		size = args.size
	})
end

-- Utilities
function p.gameImage(game, subject, type, options)
	local parts = utilsTable._filter(utilsString.notEmpty)({game, subject, type})
	local filename = table.concat(parts, " ") .. ".png"
	return p.image(filename, options)
end

function p.icon(game, subject, options)
	local type = "Icon"
	if Franchise.graphics(game) == "2D" then
		type = "Sprite"
	end
	return p.gameImage(game, subject, type, options)
end

function p.image(filename, options)
	filename = utilsPage.stripNamespace(filename)
	if utilsPage.exists("File:" .. filename) then
		return utilsMarkup.file(filename, options), true
	end
	local uploadUrl = mw.uri.fullUrl("Special:Upload")
	uploadUrl:extend({
		wpDestFile = filename
	})
	local options = utilsTable.merge({}, options, {
		link = tostring(uploadUrl)
	})

	-- Make sure thumbnail for 'no image' is no less than 100x100px
	local size
	for dimension in string.gmatch(options.size or "", "[0-9]+") do
		if tonumber(dimension) < 100 then
			size = "100px"
		end
	end
	options.size = size or options.size or "100px"
	
	return utilsMarkup.file("File:No Image Upload.png", options), false
end

function p.logo(code, options)
	local filename = Franchise.logo(code)
	return p.image(filename, options)
end

p.Templates = {
	FileInfo = {
		purpose = "Displays, categorizes, and stores file information. See [[Guidelines:Files]] for further guidance.",
		format = "block",
		paramOrder = {"summary", "subject", "type", "source", "game", "licensing", "trademark"},
		params = {
			summary = {
				--required = true,
				type = "content",
				desc = "A short description of the file.",
				trim = true,
				nilIfEmpty = true,
			},
			type = {
				required = "Category:Files Lacking Type",
				type = "string",
				desc = "The type of file, which determines how it is [[:Category:Files by Type|categorized]].",
				enum = data.typesEnum,
				trim = true,
				nilIfEmpty = true,
			},
			source = {
				required = "Category:Files Lacking Sources",
				type = "string",
				desc = "The original source of the file. It may be in the form of a URL or author recognition. [[Template:Source]] exists for this purpose.",
				trim = true,
				nilIfEmpty = true,
			},
			subject = {
				type = "string",
				desc = "Wiki article names of all the subjects depicted in the file. A comma-separated list.",
				split = true,
				trim = true,
				nilIfEmpty = true,
			},
			game = {
				--required = true,
				type = "string",
				desc = "A [[Data:Franchise|game code]].",
				enum = Franchise.enumGames({ includeSeries = true }),
				trim = true,
				nilIfEmpty = true,
			},
			licensing = {
				required = "Category:Unlicensed Files",
				type = "string",
				desc = "The copyright licensing for the file. For the vast majority of files, <code>Copyright</code> is the correct value here.",
				enum = data.licenses,
				trim = true,
				nilIfEmpty = true,
			},
			trademark = {
				type = "boolean",
				desc = "Enter any text to add a trademark notice to the licensing. Use on all [[:Category:Trademarks|trademarks]] (usually denoted by an ® or ™ symbol).",
				trim = true,
				nilIfEmpty = true,
			}
		},
		examples = {
			vertical = true,
			{
				summary = "{{Term|LADX|Animal Village|link}}",
				subject = "Animal Village, Rabbit",
				type = "map",
				source = "{{Source|Original|MannedTooth}}",
				game = "LADX",
				licensing = "Copyright",
			},
			{
				summary = "The [[Timeline]]",
				source = "{{Cite Book|book= E |page= 10}}",
				type = "print",
				game = "Series",
				licensing = "Copyright"
			},
			{
				summary = "Nintendo's current logo.",
				type = "logo",
				source = "",
				licensing = "PD-Simple",
				trademark = "yes",
			},
			{
				summary = "File missing required info"
			},
		},
	}
}

local optionsSchema =  {
	type = "record",
	properties = {
		{
			name = "size",
			type = "string",
			desc = "Image size in pixels.",
		},
		{
			name = "link",
			type = "string",
			desc = "Name of a page on the wiki or an external URL for the image thumbnail to link to.",
		},
		{
			name = "caption",
			type = "string",
			desc = "[https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img Alt text] for the image.",
		},
	}
}
local franchiseCode = {
	required = true,
	type = "string",
	desc = "A [[Data:Franchise|franchise code]]."
}

p.Schemas = {
	image = {
		filename = {
			required = true,
			type = "string",
			desc = "Filename of the image, with or without the namespace prefix.",
		},
		options = optionsSchema,
	},
	gameImage = {
		game = franchiseCode,
		subject = {
			type = "string",
			required = true,
		},
		type = {
			type = "string",
			required = true,
			enum = {"", "Artwork", "Icon", "Model", "Render", "Screenshot", "Sprite", "Texture"},
		},
		options = optionsSchema,
	},
	icon = {
		game = franchiseCode,
		subject = {
			type = "string",
			required = true,
		},
		options = optionsSchema,
	},
	logo = {
		code = franchiseCode,
		optons = optionsSchema,
	},
}

p.Documentation = {
	image = {
		desc = "A higher-level version of [[Module:UtilsMarkup#file|utilsMarkup.file]] with awareness of whether the file exists or not.",
		params = {"filename", "options"},
		returns = {
			"Wikitext rendering an image thumbnail.",
			"A boolean — true if the image exists, false otherwise.",
		},
		cases = {
			{
				args = {"File:TWW Great Fairy Figurine Model.png", { 
					link = "Great Fairy", 
					size = "100px"
				}},
				expect = {"[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy|TWW Great Fairy Figurine Model.png]]", true}
			},
			{
				desc = "If file does not exist, show 'click to upload' thumbnail which links to [[Special:Upload]].",
				args = {"File:TWWHD Great Fairy Figurine Model.png", {
					link = "Great Fairy", 
					size = "150px",
				}},
				expect = {"[[File:No Image Upload.png|150px|link=https://zelda.gamepedia.com/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png|File:No Image Upload.png]]", false}
			},
			{
				desc = "'No image' thumbnail has minimum 100px width, because it is illegible at smaller sizes.",
				args = {"File:TWWHD Great Fairy Figurine Model.png", {
					size = "64px",
				}},
				expect = {"[[File:No Image Upload.png|100px|link=https://zelda.gamepedia.com/Special:Upload?wpDestFile=TWWHD+Great+Fairy+Figurine+Model.png|File:No Image Upload.png]]", false},
			},
		},
	},
	gameImage = {
		desc = "A specialized version of [[Module:File#image|image]] that infers the filename from game, subject, and type.",
		params = {"game", "subject", "type", "options"},
		returns = {
			"A <code>string</code> of wikitext that renders a thumbnail.",
			"A boolean — true if the image exists, false otherwise.",
		},
		cases = {
			{
				args = {"TWW", "Great Fairy Figurine", "Model", { 
					link = "Great Fairy", 
					size = "100px"
				}},
				expect = {"[[File:TWW Great Fairy Figurine Model.png|100px|link=Great Fairy|TWW Great Fairy Figurine Model.png]]", true}
			},
		}
	},
	icon = {
		params = {"game", "subject", "options"},
		returns = "An icon thumbnail for the subject in the given game.",
		cases = {
			{
				args = {"LANS", "Pineapple"},
				expect = "[[File:LANS Pineapple Icon.png|LANS Pineapple Icon.png]]"
			},
			{
				args = {"LADX", "Pineapple"},
				expect = "[[File:LADX Pineapple Sprite.png|LADX Pineapple Sprite.png]]"
			},
		}
	},
	logo = {
		params = {"code", "options"},
		returns = {
			"Given a valid [[Data:Franchise|franchise code]], returns a logo thumbnail.",
			"A boolean indicating whether a logo exists for the game yet.",
		},
		cases = {
			{
				args = {"LANS", { size = "200px" }},
				expect = {"[[File:LANS English Logo.png|200px|LANS English Logo.png]]", true}
			},
			{
				args = {"SSB4", { size = "200px" }},
				expect = {"[[File:SSB4 Logo.png|200px|SSB4 Logo.png]]", true},
			},
			{
				args = {"SS (Himekawa)", { size = "200px" }},
				expect = {"[[File:Viz Media Logo.svg|200px|Viz Media Logo.svg]]", true}
			},
			{
				args = {"TLoZ (Mishouzaki)", { size = "200px" }},
				expect = {"[[File:TLoZ (Mishouzaki) Manga Cover Artwork.png|200px|TLoZ (Mishouzaki) Manga Cover Artwork.png]]", true},
			},
			{
				args = {"TAoL (Mishouzaki)", { size = "200px" }},
				expect = {"[[File:No Image Upload.png|200px|link=https://zelda.gamepedia.com/Special:Upload?wpDestFile=TAoL+%28Mishouzaki%29+Manga+Cover+Artwork.png|File:No Image Upload.png]]", false},
			},
			{
				args = {"E", { size = "200px" }},
				expect = {"[[File:The Legend of Zelda Encyclopedia Cover.png|200px|The Legend of Zelda Encyclopedia Cover.png]]", true},
			},
			{
				args = {"TMoL", { size = "200px" }},
				expect = {"[[File:Misadventures Link logo2.png|200px|Misadventures Link logo2.png]]", true},
			},
		}
	}
}

return p
Advertisement