Module:Franchise

local p = {} local h = {}

local utilsArg = require("Module:UtilsArg") local utilsCargo = require("Module:UtilsCargo") local utilsLayout = require("Module:UtilsLayout") local utilsMarkup = require("Module:UtilsMarkup") local utilsString = require("Module:UtilsString") local utilsTable = require("Module:UtilsTable") local utilsVar = require("Module:UtilsVar")

local idCounter = utilsVar.counter("id")

local CARGO = { tables = { Game = "FranchiseGames", Comic = "FranchiseComics", },	fields = { common = { id = "Integer (unique)", code = "String (unique)", page = "Page", shortName = "String", firstRelease = "Date", canonicity = "String", type = "String", display = "Wikitext", link = "Wikitext", },		Game = { family = "String", remakeOf = "String", supersededBy = "String", },		Comic = { authors = "List of String", basedOn = "String", },	} } CARGO.fields.Game = utilsTable.merge(CARGO.fields.common, CARGO.fields.Game) CARGO.fields.Comic = utilsTable.merge(CARGO.fields.common, CARGO.fields.Comic)

local FIELDS = { common = {"id", "code", "link", "display", "firstRelease", "canonicity", "type"}, Game = {"family", "remakeOf", "supersededBy"}, Comic = {"authors", "basedOn"} } FIELDS.Game = utilsTable.concat(FIELDS.common, FIELDS.Game) FIELDS.Comic = utilsTable.concat(FIELDS.common, FIELDS.Comic)

local validators = { common = { code = { nonEmpty = true }, page = { nonEmpty = true }, shortName = { nonEmpty = true }, firstRelease = {}, canonicity = { required = true, enum = {"canon", "ambiguous", "non-canon"} },		link = {}, display = {} },	Game = { type = { enum = {"main", "remake", "spin-off"}, }	},	Comic = { type = { enum = {"comic", "manga"} },		authors = { nonEmpty = true }, basedOn = { --TODO: enum = p.gameEnum, },	} } validators.Game = utilsTable.merge({}, validators.common, validators.Game) validators.Comic = utilsTable.merge({}, validators.common, validators.Comic)

local doc = { common = { code = "Unique identifier for the title.", page = "The wiki page for the title.", shortName = "The short name for the title used in categories such as Category:Items in Link's Awakening (Nintendo Switch). Usually the title's subtitle.", firstRelease = "The date of the title's first release.", canonicity = "The title's canonicity.", },	Game = { type = "One of:,  ,  , or nothing for any other game. The first three types are show on the Main Page.", link = "Wikitext for how the game is to be linked in articles. If left empty, it is derived from  and   by default.", display = "Wikitext for how the game is to be linked in articles. If left empty, it is derived from  and   by default.", remakeOf = "The game that this title is a remake of, if any.", supersededBy = "The name of the game that supersedes this one in terms of canon." },	Comic = { type = "One of:,  .", authors = "Comma-separated list of authors and illustrators", basedOn = "Game that the comic is based on.", } }

function p.CargoDeclare(frame) local entryType = frame.args[1] return utilsCargo.declare(CARGO.tables[entryType], CARGO.fields[entryType]) end

function p.CargoStore(frame) local entryType = frame.args[1] local args = frame:getParent.args args = utilsTable.mapValues(args, utilsString.nilIfEmpty) args = h.derive(args, entryType) local err = utilsArg.validate(args, validators[entryType]) if err then return utilsMarkup.categories(err) end utilsVar.add("rows", utilsTable.merge(args, { entryType = entryType }))	return utilsCargo.store(CARGO.tables[entryType], args) end

function p.CargoPreview(frame) local rows = utilsVar.get("rows") local rowGroups = utilsTable.groupBy(rows, "entryType") local titles = utilsLayout.table({		sortable = true,		headers = FIELDS.common,		rows = utilsTable.map(rows, utilsTable._toArray(FIELDS.common, ""))	}) local games = utilsLayout.table({		sortable = true,		headers = FIELDS.Game,		rows = utilsTable.map(rowGroups.Game, utilsTable._toArray(FIELDS.Game, ""))	}) local comics = utilsLayout.table({		sortable = true,		headers = FIELDS.Comic,		rows = utilsTable.map(rowGroups.Comic, utilsTable._toArray(FIELDS.Comic, ""))	}) local preview = utilsLayout.tabs({		{			label = "All Titles",			content = titles,		},		{			label = "Games",			content = games,		},		{			label = "Comics",			content = comics,		},	}) return preview end

function h.derive(args, type) if type == "Game" then return h.deriveGame(args) elseif type == "Comic" then return h.deriveComic(args) else return args end end

function h.deriveGame(args) return utilsTable.merge(args, {		link = args.link or ("%s"):format(args.page, args.shortName),		display = args.display or ("%s"):format(args.shortName),		id = idCounter.increment	}) end

function h.deriveComic(args) return utilsTable.merge(args, {		link = args.link or ("%s"):format(args.page, args.shortName),		display = args.display or "", -- TODO		id = idCounter.increment	}) end

return p