Module:Figurines

local p = {} local h = {}

local DataTable = require("Module:Data Table") local Franchise = require("Module:Franchise") local TransclusionArguments = require("Module:Transclusion Arguments") local utilsArg = require("Module:UtilsArg") local utilsCargo = require("Module:UtilsCargo") local utilsString = require("Module:UtilsString") local utilsTable = require("Module:UtilsTable")

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

local GAMES = { ["TWW"] = { gallery = "Nintendo Gallery", columns = {"Figurine", "Description"}, },	["TMC"] = { gallery = "Figurine Gallery", columns = {"Figurine", "Number", "Description"}, }, }

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  in row %d should not be empty.", column, rowIndex) return "" 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 queryResults = utilsCargo.query(CARGO_TABLE, "figurine, name, number, description", {		where = utilsCargo.allOf( { game = args.game }, string.format("_pageName LIKE '%s'", STORING_PAGE_FORMAT), 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  in game  .", page, args.game) categories = categories.."" return "", categories end local gameData = GAMES[args.game] or {} local columnHeaders = gameData.columns or {"Figurine", "Description"} local dataRows = {} for i, figurine in ipairs(queryResults) do		local row = { cells = {} }		table.insert(row.cells, {			sortValue = figurine.name,			content = figurine.figurine,		}) if args.game == "TMC" then table.insert(row.cells, {				content = figurine.number,			}) end table.insert(row.cells, {			content = mw.text.killMarkers(figurine.description),		}) table.insert(dataRows, row) end local dataTable = DataTable.printTable({		headers = columnHeaders, 		rows = dataRows, 		sortable = false,	}) local header local collapsible = frame:expandTemplate({		title = "Collapsible",		args = {			header = gameData.gallery or #dataRows > 1 and "Figurines" or "Figurine",			frame = "true",			collapse = #dataRows > 1 and "true" or "false",			content = dataTable,		}	}) return collapsible, categories end

local storeCategories = "" function p.DataTable(frame) local dataTable, dataTableCategories = DataTable.Main(frame, h.store) return dataTable, storeCategories..dataTableCategories end function h.store(args) local requiredColumns = {COLUMN_DESCRIPTION, COLUMN_FIGURINE, COLUMN_SUBJECTS} local missingColumns = utilsTable.difference(requiredColumns, args.headers) if #missingColumns > 0 then local utilsMarkup = require("Module:UtilsMarkup") missingColumns = utilsTable.map(missingColumns, utilsMarkup.code) h.warn("Columns %s are required.", mw.text.listToText(missingColumns)) storeCategories = storeCategories.."" end for i, row in ipairs(args.rows) do		local cellsByColumn = utilsTable.keyBy(row.cells, "columnHeader") local figurineCell = cellsByColumn[COLUMN_FIGURINE] or {} local subjectsCell = cellsByColumn[COLUMN_SUBJECTS] or {} local descriptionCell = cellsByColumn[COLUMN_DESCRIPTION] or {} local numberCell = cellsByColumn[COLUMN_NUMBER] or {} if figurineCell.raw == nil or figurineCell.raw == "" then storeCategories = storeCategories..h.warnEmpty(COLUMN_FIGURINE, i)		end if descriptionCell.raw == nil or descriptionCell.raw == "" then storeCategories = storeCategories..h.warnEmpty(COLUMN_DESCRIPTION, i)		end if mw.title.getCurrentTitle.nsText ~= "Template" then local figurineName = figurineCell.raw figurineName = figurineName and string.gsub(figurineName, "%[Player Name%]", "Link") figurineName = figurineName and string.gsub(figurineName, "%s%[[%d]%]", "")			mw.getCurrentFrame:expandTemplate({				title = "Figurines/Store",				args = {					game = Franchise.baseGame(args.game) or args.game,					number = numberCell.raw,					name = figurineName,					subjects = subjectsCell.raw,					figurine = figurineCell.storedContent or figurineCell.content,					description = descriptionCell.content,				}			})		end	end 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 TWW or TMC have this template on their respective articles." elseif mw.title.getCurrentTitle.subpageText ~= "Documentation" then report = report.."" 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.filter(subjectsWithFigurines, utilsString.notBlank) subjectsWithFigurines = utilsTable.flatMap(subjectsWithFigurines, utilsString.split) local articlesMissingFigurines = utilsTable.difference(subjectsWithFigurines, articlesWithFigurines) if #articlesMissingFigurines > 0 then local listArticles = utilsTable.map(articlesMissingFigurines, utilsMarkup.link) listArticles = utilsMarkup.bulletList(listArticles) report = report..string.format(" should be added to the following articles as they have 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 %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  parameter of Template:Data Table.", },			game = { type = "string", required = true, desc = "See the  parameter of Template:Data Table.", },			columns = { type = "string", desc = string.format("See the  parameter of Template:Data Table. For Template:Figurines to function correctly, there must be columns named ,  , and  . ", COLUMN_FIGURINE, COLUMN_SUBJECTS, COLUMN_DESCRIPTION), },			["..."] = {				name = "cells", placeholder = "cell", desc = "See the  parameter of Template:Data Table.", },		}	}, }

return p