Documentation for this module may be created at Module:Media/doc
-- This modules serves as the code for Template:Media. local p = {} local h = {} local File = require("Module:File") local Franchise = require("Module:Franchise") local utilsLayout = require("Module:UtilsLayout") local utilsMarkup = require("Module:UtilsMarkup") local utilsTable = require("Module:UtilsTable") local CAT_INVALID_ARGS = require("Module:Constants/category/invalidArgs") -- In the order in which they are to be presented, from left to right local mediaTypes = { { type = "Artwork", category = "Artwork", description = "Official artwork provided by Nintendo", }, { type = "Render", category = "Renders", description = "Official models provided by Nintendo", }, { type = "Model", category = "Models", description = "In-game models", }, { type = "Sprite", category = "Sprites", description = "In-game sprites or icons", }, { type = "Screenshot", category = "Screenshots", description = "In-game screenshots", }, { type = "Map", category = "Maps", description = "In-game map of an area", }, { type = "Thumbnail", category = "Thumbnails", description = "In-game images", }, } -- Template:Media function p.Main(frame) local args = frame:getParent().args return p.main(args) end function p.main(args) local remainingArgs = utilsTable.clone(args) local categories = {} local games = {} local typeTabs = {} local typeTabWithLatestRelease = 1 local latestReleaseOverall = "" local fileCount = 0 local latestImagePerType = {} for _, mediaType in ipairs(mediaTypes) do local gameTabs = {} local defaultGameTab = 1 local latestReleaseForType = "" for i, game in ipairs(Franchise.enum({ includeSeries = true, includeGroups = true })) do local key = mediaType.type .. " " .. game remainingArgs[key] = nil local file = args[key] if file ~= nil and file ~= "" then fileCount = fileCount + 1 table.insert(games, game) local img, exists if utilsMarkup.containsLink(file) or file ~= mw.text.killMarkers(file) then -- if user specified markup, simply render the markup as-is. img = file exists = true else if not string.find(file, "^File:") then h.warn(string.format("Invalid filename <code>%s</code>. Filenames must start with <code>File:</code>.", file)) table.insert(categories, CAT_INVALID_ARGS) file = "File:"..file end img, exists = File.image(file, { size = "320x320px", scale = mediaType.type == "Sprite" and 10 or nil, -- For sprites, scale to a maximum of 10x its original size. Only done for sprites due to scaling being somewhat expensive. isPixelArt = mediaType.type == "Sprite" or Franchise.graphics(game) == "2D" }) end table.insert(gameTabs, { label = game, content = img, tooltip = Franchise.shortName(game) }) if not exists and mw.title.getCurrentTitle().nsText ~= "User" then table.insert(categories, "Articles lacking files") table.insert(categories, "Articles lacking " .. string.lower(mediaType.category)) table.insert(categories, string.format("%s articles lacking files", Franchise.shortName(game))) end local release = Franchise.releaseDate(game) -- empty string here means an unreleased game. This ensures the unreleased is sorted last. -- the 'i' is appended to ensure that multiple unreleased games are sorted in canon order. if release == "" then release = "unreleased"..i end if exists and release and release > latestReleaseForType then latestReleaseForType = release defaultGameTab = #gameTabs latestImagePerType[#typeTabs + 1] = file end if exists and release and release > latestReleaseOverall then latestReleaseOverall = release typeTabWithLatestRelease = #typeTabs + 1 end end end if #gameTabs > 0 then table.insert(typeTabs, { label = mediaType.type, tooltip = mediaType.description, gameTabs = gameTabs, defaultGameTab = defaultGameTab, }) end end remainingArgs["defaultTypeTab"] = nil local defaultTypeTab = utilsTable.findIndex(typeTabs, function(typeTab) return typeTab.label == args.defaultTypeTab end) defaultTypeTab = defaultTypeTab or typeTabWithLatestRelease local invalidKeys = utilsTable.keys(remainingArgs) if #invalidKeys > 0 then local msg = string.format("The following keys use an invalid media type or game code: <code>%s</code><p>For a list of valid types, see [[Template:Media]]. For a list of valid games, see [[Module:Franchise]].</p>", utilsTable.print(invalidKeys)) h.warn(msg) table.insert(categories, CAT_INVALID_ARGS) end local mainGames, otherGames = utilsTable.partition(games, function(game) local gameType = Franchise.type(game) return gameType == "main" or gameType == "remake" end) if #mainGames > 0 and #otherGames > 0 then otherGames = utilsTable.map(otherGames, utilsMarkup.code) otherGames = mw.text.listToText(otherGames) h.warn("Entries for %s should be moved from the infobox to the Gallery section. As per [[Template:Media#Guidelines]], infoboxes should not mix main series games with other games.", otherGames) table.insert(categories, CAT_INVALID_ARGS) end local content if #typeTabs == 1 and #typeTabs[1].gameTabs == 1 then content = typeTabs[1].gameTabs[1].content else for i, typeTab in ipairs(typeTabs) do typeTab.content = utilsLayout.tabs(typeTab.gameTabs, { default = typeTab.defaultGameTab, align = "center", tabOptions = { position = "bottom", columns = 5, }, contentOptions = { alignVertical = "center", fixedHeight = true, } }) end content = utilsLayout.tabs(typeTabs, { default = defaultTypeTab, align = "center", tabOptions = { columns = 4, }, }) end -- Set the file under the default type and game tab as the article's representative image for page previews and OpenGraph local pageImage = latestImagePerType[defaultTypeTab] if pageImage then pageImage = string.gsub(pageImage, "^File:", "") -- only works without the namespace prefix mw.ext.seo.set({ image = pageImage }) end return content .. utilsMarkup.categories(categories) end function h.warn(msg, ...) local utilsError = require("Module:UtilsError") local warnMessage = string.format(msg, ...) utilsError.warn(warnMessage) end return p