Module:Figurines: Difference between revisions

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search
No edit summary
No edit summary
 
(3 intermediate revisions by the same user not shown)
Line 9: Line 9:
local utilsArg = require("Module:UtilsArg")
local utilsArg = require("Module:UtilsArg")
local utilsCargo = require("Module:UtilsCargo")
local utilsCargo = require("Module:UtilsCargo")
local utilsPage = require("Module:UtilsPage")
local utilsString = require("Module:UtilsString")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")
local utilsTable = require("Module:UtilsTable")
Line 114: Line 115:


function p.DataTable(frame)
function p.DataTable(frame)
local game = frame:getParent().args.game
local game = utilsString.trim(frame:getParent().args.game)
return DataTable.Main(frame, h.store, h.extensionArgs)
return DataTable.Main(frame, {
requiredColumns = h.requiredColumns(game),
storeFn = h.store,
})
end
end
function h.extensionArgs(args)
function h.requiredColumns(game)
local columns = GAMES[args.game] or DEFAULT_COLUMNS
if GAMES[game].hasNumbers then
table.insert(columns, COLUMN_SUBJECTS)
return {COLUMN_FIGURINE, COLUMN_SUBJECTS, COLUMN_DESCRIPTION, COLUMN_NUMBERS}
return {
else
requiredColumns = columns
return {COLUMN_FIGURINE, COLUMN_SUBJECTS, COLUMN_DESCRIPTION}
}
end
end
end
function h.store(args, rows)
function h.store(args, rows)
Line 144: Line 148:
figurine = figurine and string.gsub(figurine, "%[Player Name%]", "Link")
figurine = figurine and string.gsub(figurine, "%[Player Name%]", "Link")
local fileType = "Figurine " .. (Franchise.graphics(args.game) == "2D" and "Sprite" or "Model")
local fileType = "Figurine " .. (Franchise.graphics(args.game) == "2D" and "Sprite" or "Model")
local entry = GalleryList.entry(args.game, fileType, figurine, {
local entry = GalleryList.parseEntry(figurine, args.game, fileType, {
useTerms = false,
useTerms = false,
})
})
Line 173: Line 177:
report = "{{Good}} No issues detected—All subjects which have figurines in [[Figurines in The Wind Waker|TWW]] or [[Figurines in The Minish Cap|TMC]] have this template on their respective articles."
report = "{{Good}} No issues detected—All subjects which have figurines in [[Figurines in The Wind Waker|TWW]] or [[Figurines in The Minish Cap|TMC]] have this template on their respective articles."
elseif mw.title.getCurrentTitle().subpageText ~= "Documentation" then
elseif mw.title.getCurrentTitle().subpageText ~= "Documentation" then
report = report.."[[Category:Templates Needing Attention]]"
report = report.."[[Category:Templates needing attention]]"
end
end
return frame:preprocess(report)
return frame:preprocess(report)
Line 198: Line 202:
local articlesMissingFigurines = utilsTable.difference(subjectsWithFigurines, articlesWithFigurines)
local articlesMissingFigurines = utilsTable.difference(subjectsWithFigurines, articlesWithFigurines)
articlesMissingFigurines = utilsTable.filter(articlesMissingFigurines, function(page)
return not utilsPage.isRedirect(page)
end)
if #articlesMissingFigurines > 0 then
if #articlesMissingFigurines > 0 then

Latest revision as of 09:33, 5 November 2023

This is the main module for the following templates:
local p = {}
local h = {}

local DataTable = require("Module:Data Table")
local File = require("Module:File")
local Franchise = require("Module:Franchise")
local GalleryList = require("Module:Gallery List")
local TransclusionArguments = require("Module:Transclusion Arguments")
local utilsArg = require("Module:UtilsArg")
local utilsCargo = require("Module:UtilsCargo")
local utilsPage = require("Module:UtilsPage")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")

local CARGO_TABLE = "Figurines"
local CATEGORY_INVALID_ARGS = require("Module:Constants/category/invalidArgs")
local FIGURINE_LIST_PAGE_FORMAT = "Figurines in %s"
local COLUMN_DESCRIPTION = "Description"
local COLUMN_FIGURINE = "Figurine"
local COLUMN_NUMBER = "Number"
local COLUMN_SUBJECTS = "Subject(s)"

local GAMES = {
	["TWW"] = {
		gallery = "Nintendo Gallery",
		size = "x150px",
	},
	["TMC"] = {
		gallery = "Figurine Gallery",
		scale = 2,
		hasNumbers = true,
	},
}

function h.warn(msg, ...)
	local utilsError = require("Module:UtilsError")
	msg = string.format(msg, ...)
	utilsError.warn(msg)
end
function h.warnEmpty(column, rowIndex)
	h.warn("The value for column <code>%s</code> in row %d should not be empty.", column, rowIndex)
	return "[[Category:"..CATEGORY_INVALID_ARGS.."]]"
end

function p.Main(frame)
	local args, err = utilsArg.parse(frame:getParent().args, p.Templates["Figurines"])
	local categories = err and err.categoryText or ""
	
	if err then
		return "", categories
	end
	TransclusionArguments.store({
		module = "Module:Figurines",
		isValid = true,
		args = {args.game}
	})
	
	local page = args.page or mw.title.getCurrentTitle().subpageText
	local figurineListPage = string.format(FIGURINE_LIST_PAGE_FORMAT, Franchise.shortName(args.game))
	local queryResults = utilsCargo.query(CARGO_TABLE, "figurine, name, number, description", {
		where = utilsCargo.allOf(
			string.format("_pageName = '%s'", figurineListPage),
			utilsCargo.holdsAny("subjects", {page})
		),
		orderBy = "number, name, _ID" -- sort by ID so that figurines with the same name are listed in the order stored (see Silver Darknut)
	})
	if #queryResults == 0 then
		h.warn("No figurines found for subject <code>%s</code> in game <code>%s</code>.", page, args.game)
		categories = categories.."[[Category:"..CATEGORY_INVALID_ARGS.."]]"
		return "", categories
	end
	
	local gameData = GAMES[args.game] or {}
	
	local columns = {COLUMN_FIGURINE, COLUMN_DESCRIPTION .. " [Description]"}
	if gameData.hasNumbers then
		table.insert(columns, 2, COLUMN_NUMBER)
	end
	local dataRows = {}
	for i, figurine in ipairs(queryResults) do
		local image = File.image(figurine.figurine, {
			scale = gameData.scale,
			size = gameData.size,
		})
		local figurineDisplayName = string.gsub(figurine.name, "Link", frame:expandTemplate({
			title = "Player Name"
		}))
		local link = string.format("<div><b>[[%s#%s|%s]]</b></div>", figurineListPage, figurine.name, figurineDisplayName)
		
		local row = {
			cells = {image..link, figurine.description}
		}
		if gameData.hasNumbers then
			table.insert(row.cells, 2, figurine.number)
		end
		table.insert(dataRows, row)
	end
	local dataTable = DataTable.printTable(dataRows, {
		columns = columns,
		sortable = false,
	})

	local collapsibleHeader = gameData.gallery or #dataRows > 1 and "Figurines" or "Figurine"
	local collapsible = frame:expandTemplate({
		title = "Collapsible",
		args = {
			header = collapsibleHeader,
			frame = "true",
			collapse = #dataRows > 1 and "true" or "false",
			content = dataTable,
		}
	})
	return collapsible, categories
end

function p.DataTable(frame)
	local game = utilsString.trim(frame:getParent().args.game)
	return DataTable.Main(frame, {
		requiredColumns = h.requiredColumns(game),
		storeFn = h.store,
	})
end
function h.requiredColumns(game)
	if GAMES[game].hasNumbers then
		return {COLUMN_FIGURINE, COLUMN_SUBJECTS, COLUMN_DESCRIPTION, COLUMN_NUMBERS}
	else
		return {COLUMN_FIGURINE, COLUMN_SUBJECTS, COLUMN_DESCRIPTION}
	end
end
function h.store(args, rows)
	local categories = ""
	for i, row in ipairs(rows) do
		local isValid = true
		local figurine = row[COLUMN_FIGURINE]
		local subjects = row[COLUMN_SUBJECTS]
		local description = row[COLUMN_DESCRIPTION]
		local number = row[COLUMN_NUMBER]
		
		if figurine == nil or figurine == "" then
			isValid = false
			categories = categories..h.warnEmpty(COLUMN_FIGURINE, i)
		end
		if description == nil or description == "" then
			isValid = false
			categories = categories..h.warnEmpty(COLUMN_DESCRIPTION, i)
		end
		if isValid and mw.title.getCurrentTitle().nsText == "" then
			figurine = figurine and string.gsub(figurine, "%[Player Name%]", "Link")
			local fileType = "Figurine " .. (Franchise.graphics(args.game) == "2D" and "Sprite" or "Model")
			local entry = GalleryList.parseEntry(figurine, args.game, fileType, {
				useTerms = false,
			})
			local figurineName = entry.subject
			local figurineFile = entry.file

			mw.getCurrentFrame():expandTemplate({
				title = "Figurines/Store",
				args = {
					game = Franchise.baseGame(args.game) or args.game,
					number = number,
					name = figurineName,
					subjects = subjects,
					figurine = figurineFile,
					description = description,
				}
			})
		end
	end
	return categories
end

function p.Report(frame)
	local report = ""
	report = report..h.report("TWW")
	report = report..h.report("TMC")
	if report == "" then
		report = "{{Good}} No issues detected—All subjects which have figurines in [[Figurines in The Wind Waker|TWW]] or [[Figurines in The Minish Cap|TMC]] have this template on their respective articles."
	elseif mw.title.getCurrentTitle().subpageText ~= "Documentation" then
		report = report.."[[Category:Templates needing attention]]"
	end
	return frame:preprocess(report)
end
function h.report(game)
	local utilsMarkup = require("Module:UtilsMarkup")
	local report = ""

	local articlesWithFigurines = TransclusionArguments.query({
		template = "Template:Figurines",
		parameter = "1",
		argument = game,
	})
	articlesWithFigurines = utilsTable.map(articlesWithFigurines, "_pageName")
	
	local subjectsWithFigurines = utilsCargo.query("Figurines", "subjects", {
		where = string.format("game = '%s'", game)
	})
	subjectsWithFigurines = utilsTable.map(subjectsWithFigurines, "subjects")
	subjectsWithFigurines = utilsTable.flatMap(subjectsWithFigurines, utilsString.split)
	subjectsWithFigurines = utilsTable.filter(subjectsWithFigurines, function(subject)
		return subject ~= "" and subject ~= "N/A"
	end)
	
	local articlesMissingFigurines = utilsTable.difference(subjectsWithFigurines, articlesWithFigurines)
	articlesMissingFigurines = utilsTable.filter(articlesMissingFigurines, function(page)
		return not utilsPage.isRedirect(page)
	end)
	
	if #articlesMissingFigurines > 0 then
		local listArticles = utilsTable.map(articlesMissingFigurines, utilsMarkup.link)
		listArticles = utilsMarkup.bulletList(listArticles)
		report = report..string.format("{{Template|Figurines|%s}} should be added to the following articles as they have [[Figurines in %s|Figurines in %s]]:", game, Franchise.shortName(game), Franchise.display(game))
		report = report..listArticles
	end
	return report
end

p.Templates = {
	["Figurines"] = {
		purpose = "Displays the figurines of a particular subject by retrieving data stored at [[Figurines in The Wind Waker]] or [[Figurines in The Minish Cap]].",
		usesData = true,
		categories = {"Comment Templates"},
		params = {
			[1] = {
				name = "game",
				desc = "A game code.",
				enum = utilsTable.keys(GAMES),
				required = true,
			},
			[2] = {
				name = "page",
				type = "wiki-page-name",
				desc = "A wiki page name. Should usually be left blank, in which case it default to the current page.",
				trim = true,
				nilIfEmpty = true,
			},
		},
		examples = {
			vertical = true,
			{"TWW", "Link"},
			{
				desc = "Collapsed by default when there is more than one figurine.",
				args = {"TMC", "Vaati"},
			},
			{
				desc = "Different figurines can have the same name.",
				args = {"TWW", "Silver Darknut"},
			},
			{
				desc = "Error handling",
				args = {"TWW", "Not a Page"},
			},
			{
				args = {"Not a Game"},
			},
		},
	},
	["Data Table/Figurines"] = {
		purpose = string.format("An extension of [[Template:Data Table]] for [[Figurine]] listings. Data is stored in the [[Special:CargoTables/%s|%s]] Cargo table for retrieval by [[Template:Figurines]].", CARGO_TABLE, CARGO_TABLE),
		usage = "See [[Template:Data Table]] for more information",
		format = "block",
		paramOrder = {"name", "game", "columns", "..."},
		params = {
			name = {
				type = "string",
				required = true,
				desc = "See the <code>name</code> parameter of [[Template:Data Table]].",
			},
			game = {
				type = "string",
				required = true,
				desc = "See the <code>game</code> parameter of [[Template:Data Table]].",
			},
			columns = {
				type = "string",
				desc = string.format("See the <code>columns</code> parameter of [[Template:Data Table]].<p>For [[Template:Figurines]] to function correctly, there must be columns named <code>%s</code>, <code>%s</code>, and <code>%s</code>.</p>", COLUMN_FIGURINE, COLUMN_SUBJECTS, COLUMN_DESCRIPTION),
			},
			["..."] = {
				name = "cells",
				placeholder = "cell",
				desc = "See the <code>cells</code> parameter of [[Template:Data Table]].",
			},
		}
	},
}

return p