Module:Franchise
Allows modules to access the information stored in franchise code templates.
These functions return nil
if passed an invalid code. This is not shown in the examples because it would add invalid codes to Special:WantedTemplates.
Codes are case-sensitive.
Lua error in package.lua at line 80: module 'Module:Franchise/Cache' not found.
local p = {}
local h = {}
local Error = require("Module:Error")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")
local Constants = mw.loadData("Module:Constants/Data")
local cache = mw.loadData("Module:Franchise/Cache")
-- Many templates need "Series" as if it were a game. Since it does not fit into the data model of Data:Franchise, it is manually defined here.
local series = {
article = "The Legend of Zelda (Series)",
shortName = "The Legend of Zelda Series",
logo = "File:Zelda Logo TP.png",
link = "[[The Legend of Zelda (Series)|''The Legend of Zelda'' series]]",
display = "''The Legend of Zelda'' series",
canonicity = "canon",
code = "Series",
}
-- [[Template:Game Link]]
function p.Link(frame)
local args = frame.args
local game, nowarn = args[1], args.nowarn
if game == nil or game == "" then
return Error.printError("No game provided", "Category:"..Constants.catInvalidArgs, nowarn)
end
game = utilsString.trim(game)
local link = p.link(game)
if not link then
return Error.printError(string.format("Invalid game <code>%s</code>", game), "Category:"..Constants.catInvalidArgs, nowarn)
end
local correctGameCode = p.code(game)
if game ~= correctGameCode then
link = link..Error.warn(string.format("<code>%s</code> should be written as <code>%s</code>.", game, correctGameCode), "Category:"..Constants.catInvalidArgs)
end
return link
end
-- Template:Franchise/Store *
function p.AddToPreview(frame)
-- Performance optimization
local utilsArg = require("Module:UtilsArg")
local utilsVar = require("Module:UtilsVar")
local utilsMarkup = require("Module:UtilsMarkup")
local doc = mw.loadData("Module:Franchise/Documentation/Data")
local orderCounter = utilsVar.counter("canonOrder")
local entryType = frame.args[1]
local args, err = utilsArg.parse(frame:getParent().args, doc.Templates["Franchise/Store " .. entryType])
if err then
return utilsMarkup.categories(err.categories)
end
args = utilsTable.merge({}, args, {
entryType = entryType,
link = p.deriveLink(entryType, args),
display = p.deriveDisplay(entryType, args),
})
if entryType == "Game" or entryType == "Book" or entryType == "TV" then
args.canonOrder = orderCounter.value()
else
args.canonOrder = "—"
end
if type == "Book" then
args.phraseLink = p.derivePhraseLink(args)
end
utilsVar.add("rows", args)
end
function p.StoreOrder(frame)
-- Performance optimization
local utilsVar = require("Module:UtilsVar")
local orderCounter = utilsVar.counter("canonOrder")
return orderCounter.increment()
end
function p.StoreLink(frame)
return p.deriveLink(frame.args[1], frame:getParent().args)
end
function p.StoreDisplay(frame)
return p.deriveDisplay(frame.args[1], frame:getParent().args)
end
function p.StorePhraseLink(frame)
return p.derivePhraseLink(frame:getParent().args)
end
function p.deriveDisplay(entryType, args)
if args.display ~= nil and args.display ~= "" then
return args.display
elseif entryType == "Book" then
return h.deriveBookFields(args).display
else
return ("''%s''"):format(args.shortName)
end
end
function p.deriveLink(entryType, args)
if args.display ~= nil and args.display ~= "" then
return args.link
elseif entryType == "Book" then
return h.deriveBookFields(args).link
else
return ("''[[%s|%s]]''"):format(args.article, args.shortName)
end
end
function p.derivePhraseLink(args)
return h.deriveBookFields(args).phraseLink
end
function p.Preview(frame)
-- Performance optimization
local utilsMarkup = require("Module:UtilsMarkup")
local utilsLayout = require("Module:UtilsLayout")
local utilsVar = require("Module:UtilsVar")
local previewColumns = {
common = {"canonOrder", "code", "link", "display", "logo", "releaseDate", "canonicity"},
Game = {"type", "graphics", "family", "remakeOf", "supersededBy"},
Book = {"type", "phraseLink", "authors", "basedOn"},
TV = {"type"},
Compilation = {"titles"},
Group = {"games"},
}
previewColumns.Game = utilsTable.concat(previewColumns.common, previewColumns.Game)
previewColumns.Book = utilsTable.concat(previewColumns.common, previewColumns.Book)
previewColumns.TV = utilsTable.concat(previewColumns.common, previewColumns.TV)
previewColumns.Compilation = utilsTable.concat(previewColumns.common, previewColumns.Compilation)
previewColumns.Group = utilsTable.concat(previewColumns.common, previewColumns.Group)
local rows = utilsVar.get("rows")
for _, row in ipairs(rows) do
row.logo = utilsMarkup.link(row.logo)
end
local rowGroups = utilsTable.groupBy(rows, "entryType")
local titles = utilsLayout.table({
sortable = true,
headers = previewColumns.common,
rows = utilsTable.map(rows, utilsTable._toArray(previewColumns.common, ""))
})
local games = utilsLayout.table({
sortable = true,
headers = previewColumns.Game,
rows = utilsTable.map(rowGroups.Game, utilsTable._toArray(previewColumns.Game, ""))
})
local books = utilsLayout.table({
sortable = true,
headers = previewColumns.Book,
rows = utilsTable.map(rowGroups.Book, utilsTable._toArray(previewColumns.Book, ""))
})
local tv = utilsLayout.table({
sortable = true,
headers = previewColumns.TV,
rows = utilsTable.map(rowGroups.TV, utilsTable._toArray(previewColumns.TV, ""))
})
local compilations = utilsLayout.table({
sortable = true,
headers = previewColumns.Compilation,
rows = utilsTable.map(rowGroups.Compilation or {}, utilsTable._toArray(previewColumns.Compilation, ""))
})
local groups = utilsLayout.table({
sortable = true,
headers = previewColumns.Group,
rows = utilsTable.map(rowGroups.Group or {}, utilsTable._toArray(previewColumns.Group, ""))
})
local preview = utilsLayout.tabs({
{
label = "All Titles",
content = titles,
},
{
label = "Games",
content = games,
},
{
label = "Books",
content = books,
},
{
label = "TV Shows",
content = tv,
},
{
label = "Compilations",
content = compilations
},
{
label = "Groups",
content = groups,
}
}, { columns = 15 })
return preview
end
function p.UploadField(frame)
-- Performance optimization
local utilsMarkup = require("Module:UtilsMarkup")
local utilsVar = require("Module:UtilsVar")
local rows = utilsVar.get("rows")
local groups = utilsTable.groupBy(rows, "entryType")
local mainGames, otherGames = utilsTable.partition(groups["Game"], {
canonicity = "canon"
})
local remakes = utilsTable.groupBy(mainGames, "remakeOf")
local books = groups["Book"]
local tvShows = groups["TV"]
local sortedMainGames = {}
for _, mainGame in ipairs(utilsTable.reverse(mainGames)) do
if not mainGame.remakeOf then
table.insert(sortedMainGames, mainGame)
for _, remake in ipairs(remakes[mainGame.code] or {}) do
table.insert(sortedMainGames, remake)
end
end
end
local result = ""
result = result .. "**|None\n"
result = result .. "**Series|The Legend of Zelda Series\n"
result = h.append(result, "Main Series", sortedMainGames)
result = h.append(result, "Other Games", otherGames)
result = h.append(result, "Books, Comics, and Manga", books)
result = h.append(result, "TV Shows", tvShows)
return utilsMarkup.pre(result)
end
function h.append(result, title, entries)
result = result .. "\n*"..title.."\n"
for _, entry in ipairs(entries) do
result = result .. string.format("**%s|%s\n", entry.code, entry.shortName)
end
return result
end
function h.deriveBookFields(args)
local ListPages = require("Module:List Pages")
local utilsString = require("Module:UtilsString")
local subtitle, display, link, phraseLink
local parens = string.find(args.shortName, "%s%([^)]+%)")
if parens then
subtitle = string.sub(args.shortName, 1, parens - 1)
local descriptor = string.sub(args.shortName, parens)
display = ("''%s''%s"):format(subtitle, descriptor)
link = ("[[%s|%s]]"):format(args.article, display)
local authors = ListPages.main(utilsString.split(args.authors))
phraseLink = ("[[%s|''%s'' %s]] by %s"):format(args.article, subtitle, args.type, authors)
else
display = ("''%s''"):format(args.shortName)
link = ("''[[%s|%s]]''"):format(args.article, args.shortName)
phraseLink = link
end
return {
display = display,
link = link,
phraseLink = phraseLink,
}
end
-- QUERIES: ALL
function p.enum(options)
if not options then
return cache.enum
end
enum = utilsTable.clone(cache.enum) -- clone the read-only cache item so that we can modify it
if options.includeSeries then
table.insert(enum, 1, "Series")
end
if options.includeCompilations then
local codes = utilsTable.map(cache.compilations, "code")
enum = utilsTable.concat(codes, enum)
end
if options.includeGroups then
-- insert "groups" so as to not disrupt the release order. This matters for Template:Media (e.g. the Figher page, which uses SSB4)
for _, group in ipairs(cache.groups) do
local i = 1
repeat
i = i + 1
until i == #enum or p.isCanon(enum[i]) == p.isCanon(group.code) and p.releaseDate(enum[i]) >= p.releaseDate(group.code)
table.insert(enum, i, group.code)
end
end
enum.reference = "[[Data:Franchise]]"
return enum
end
function p.article(code)
return h.get(code, "article")
end
function p.canonicity(code)
return h.get(code, "canonicity")
end
function p.code(code)
return h.get(code, "code")
end
function p.display(code)
return h.get(code, "display")
end
function p.isCanon(code)
return p.canonicity(code) == "canon"
end
function p.link(code)
return h.get(code, "link")
end
function p.logo(code)
return h.get(code, "logo")
end
function p.releaseDate(code)
return h.get(code, "releaseDate")
end
function p.ShortName(frame)
-- Performance optimization
local utilsArg = require("Module:UtilsArg")
local utilsMarkup = require("Module:UtilsMarkup")
local args, err = utilsArg.parse(frame.args, {
params = {
[1] = {
name = "code",
enum = p.enum({
includeSeries = true,
includeCompilations = true,
includeGroups = true,
}),
}
}
})
if err then
return utilsMarkup.categories(err.categories)
end
return p.shortName(args.code)
end
function p.shortName(code)
return h.get(code, "shortName")
end
function p.type(code)
return h.get(code, "type")
end
-- QUERIES: GAMES
function p.enumGames(includeSeries)
if includeSeries then
local enum = utilsTable.concat({"Series"}, cache.enumGames)
enum.reference = "[[Data:Franchise]]"
return enum
end
return cache.enumGames
end
function p.baseGame(code)
local baseGame = h.get(code, "remakeOf")
local hasBaseGame = baseGame ~= nil and baseGame ~= ""
return hasBaseGame and baseGame or code
end
function p.family(code)
return h.get(code, "family")
end
function p.graphics(code)
return h.get(code, "graphics")
end
function p.hasRemakes(code)
return utilsTable.hasKey(cache.remakes, string.lower(code))
end
function p.isRemake(code)
return p.type(code) == "remake"
end
function p.remakes(code)
return utilsTable.clone(cache.remakes[string.lower(code)]) or {}
end
-- QUERIES: BOOKS
function p.phraseLink(code)
return h.get(code, "phraseLink")
end
function h.get(code, prop)
code = string.lower(code)
if code == "series" then
return series[prop]
end
local title = cache.titlesByCode[code]
return title and title[prop]
end
return p