Module:Figurines: Difference between revisions
Jump to navigation
Jump to search
PhantomCaleb (talk | contribs) No edit summary |
PhantomCaleb (talk | contribs) No edit summary |
||
(24 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
local DataTable = require("Module:Data Table") | local DataTable = require("Module:Data Table") | ||
local File = require("Module:File") | |||
local Franchise = require("Module:Franchise") | local Franchise = require("Module:Franchise") | ||
local GalleryList = require("Module:Gallery List") | |||
local TransclusionArguments = require("Module:Transclusion Arguments") | local TransclusionArguments = require("Module:Transclusion Arguments") | ||
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") | ||
local CARGO_TABLE = " | local CARGO_TABLE = "Figurines" | ||
local CATEGORY_INVALID_ARGS = require("Module:Constants/category/invalidArgs") | local CATEGORY_INVALID_ARGS = require("Module:Constants/category/invalidArgs") | ||
local | local FIGURINE_LIST_PAGE_FORMAT = "Figurines in %s" | ||
local COLUMN_DESCRIPTION = "Description" | local COLUMN_DESCRIPTION = "Description" | ||
local COLUMN_FIGURINE = "Figurine" | local COLUMN_FIGURINE = "Figurine" | ||
local COLUMN_NUMBER = "Number" | local COLUMN_NUMBER = "Number" | ||
local COLUMN_SUBJECTS = "Subject(s)" | 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, ...) | function h.warn(msg, ...) | ||
Line 41: | Line 56: | ||
}) | }) | ||
local page = mw.title.getCurrentTitle().subpageText | 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", { | local queryResults = utilsCargo.query(CARGO_TABLE, "figurine, name, number, description", { | ||
where = utilsCargo.allOf( | where = utilsCargo.allOf( | ||
string.format("_pageName = '%s'", figurineListPage), | |||
string.format("_pageName | |||
utilsCargo.holdsAny("subjects", {page}) | utilsCargo.holdsAny("subjects", {page}) | ||
), | ), | ||
Line 56: | Line 71: | ||
end | end | ||
local | local gameData = GAMES[args.game] or {} | ||
if | |||
local columns = {COLUMN_FIGURINE, COLUMN_DESCRIPTION .. " [Description]"} | |||
if gameData.hasNumbers then | |||
table.insert(columns, 2, COLUMN_NUMBER) | |||
end | end | ||
local dataRows = {} | local dataRows = {} | ||
for i, figurine in ipairs(queryResults) do | 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 = { | local row = { | ||
cells = {} | cells = {image..link, figurine.description} | ||
} | } | ||
if gameData.hasNumbers then | |||
table.insert(row.cells, 2, figurine.number) | |||
if | |||
table.insert(row.cells, | |||
end | end | ||
table.insert(dataRows, row) | table.insert(dataRows, row) | ||
end | end | ||
local | local dataTable = DataTable.printTable(dataRows, { | ||
local | columns = columns, | ||
sortable = false, | |||
}) | |||
local collapsibleHeader = gameData.gallery or #dataRows > 1 and "Figurines" or "Figurine" | |||
local collapsible = frame:expandTemplate({ | local collapsible = frame:expandTemplate({ | ||
title = " | title = "Collapsible", | ||
args = { | args = { | ||
header = | header = collapsibleHeader, | ||
frame = "true", | |||
collapse = #dataRows > 1 and "true" or "false", | |||
content = dataTable, | content = dataTable, | ||
} | } | ||
}) | }) | ||
Line 94: | Line 115: | ||
function p.DataTable(frame) | 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 = "" | 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 | ||
end | |||
return categories | |||
end | |||
return | |||
end | end | ||
function p.Report(frame) | 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 | end | ||
Line 155: | Line 223: | ||
[1] = { | [1] = { | ||
name = "game", | name = "game", | ||
desc = "A game code ( | desc = "A game code.", | ||
enum = utilsTable.keys(GAMES), | |||
required = true, | 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"}, | |||
}, | }, | ||
}, | }, |
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