87,252
edits
PhantomCaleb (talk | contribs) No edit summary |
TriforceTony (talk | contribs) No edit summary |
||
(41 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local h = {} | |||
local | |||
local File = require("Module:File") | local File = require("Module:File") | ||
local Franchise = require("Module:Franchise") | local Franchise = require("Module:Franchise") | ||
local Term = require("Module:Term") | |||
local utilsArg = require("Module:UtilsArg") | local utilsArg = require("Module:UtilsArg") | ||
local utilsMarkup = require("Module:UtilsMarkup") | local utilsMarkup = require("Module:UtilsMarkup") | ||
local utilsString = require("Module:UtilsString") | local utilsString = require("Module:UtilsString") | ||
local utilsTable = require("Module:UtilsTable") | local utilsTable = require("Module:UtilsTable") | ||
local | local utilsVar = require("Module:UtilsVar") | ||
local CATEGORY_INVALID_ARGS = "[[Category:"..require("Module:Constants/category/invalidArgs").."]]" | |||
local CATEGORY_INVALID_ARGS = "[[Category:"..Constants | local CATEGORY_PARAM_CAPTION = "[[Category:Infoboxes using captions]]" | ||
local CATEGORY_PARAM_CAPTION = "[[Category:Infoboxes | local CATEGORY_PARAM_NAME = "[[Category:Infoboxes using the name parameter]]" | ||
local CATEGORY_PARAM_NAME = "[[Category:Infoboxes | local CATEGORY_BR_TAGS = "[[Category:Infoboxes using br tags]]" | ||
local CATEGORY_BR_TAGS = "[[Category:Infoboxes | local CATEGORY_BR_TAGS_GAME = "[[Category:Infoboxes using br tags in game fields]]" | ||
local | local CLASS_TOOLTIP = require("Module:Constants/class/tooltip") | ||
local DEFAULT_IMG_SIZE = "320x320px" | |||
local VAR_IS_AFTER_INFOBOX = require("Module:Constants/var/isAfterInfobox") | |||
function p.Main(frame) | function p.Main(frame) | ||
Line 38: | Line 39: | ||
end | end | ||
return categories | for k, v in pairs(args) do | ||
if string.find(v, "<br") then | |||
h.warn("It appears the <code>%s</code> field may be using <code><nowiki><br></nowiki></code> tags to create a list. If so, please use [[Template:List]] or [[Template:Infobox Game Blocks]] instead. See [[:Category:Infoboxes using br tags]] for more information.", k) | |||
categories = categories..CATEGORY_BR_TAGS | |||
end | |||
end | |||
local styles = frame:extensionTag({ | |||
name = "templatestyles", | |||
args = { src = "Module:Infobox/Styles.css" } | |||
}) | |||
utilsVar.set(VAR_IS_AFTER_INFOBOX, true) | |||
return styles, categories | |||
end | end | ||
function p.Image(frame) | function p.Image(frame) | ||
local file = frame.args[1] | local file = frame.args[1] | ||
local caption = frame.args[2] | |||
if file == nil or file == "" then | if file == nil or file == "" then | ||
return nil | return nil | ||
Line 48: | Line 64: | ||
return file | return file | ||
else | else | ||
local image = File.image(file, { | local image, exists = File.image(file, { | ||
size = frame.args.size or DEFAULT_IMG_SIZE, -- unclear whether we should even support custom sizing or force them all to 320x320px. | size = frame.args.size or DEFAULT_IMG_SIZE, -- unclear whether we should even support custom sizing or force them all to 320x320px. | ||
scale = 10, | scale = 10, | ||
}) | }) | ||
if exists then | |||
-- Set this image as the article's representative image for things like page previews | |||
mw.ext.seo.set({ | |||
image = file | |||
}) | |||
end | |||
if caption and caption ~= "" then | |||
local html = mw.html.create("div") | |||
:addClass("infobox__image-caption") | |||
:wikitext(caption) | |||
image = image .. tostring(html) | |||
end | |||
return image | return image | ||
end | end | ||
end | end | ||
Line 80: | Line 88: | ||
local categories = "" | local categories = "" | ||
games = games and utilsString.trim(games) | |||
if games == nil or games == "" then | if games == nil or games == "" then | ||
return nil | return nil | ||
Line 85: | Line 94: | ||
if string.find(games, "<br") then | if string.find(games, "<br") then | ||
categories = categories..CATEGORY_BR_TAGS_GAME | |||
games = utilsString.split(games, "<br>") | |||
games = utilsTable.flatMap(games, utilsString._split("<br/>")) | |||
else | |||
games = utilsString.split(games) | |||
end | end | ||
local gameLinks = utilsTable.map(games, p.link) | local gameLinks = utilsTable.map(games, p.link) | ||
local gameLinks = utilsTable.compact(gameLinks) | local gameLinks = utilsTable.compact(gameLinks) | ||
Line 109: | Line 118: | ||
return game | return game | ||
end | end | ||
local game, notes = utilsMarkup.separateMarkup(game) | |||
local link = Franchise.link(game) | local link = Franchise.link(game) | ||
local properCode = Franchise.code(game) | local properCode = Franchise.code(game) | ||
if not link then | if not link then | ||
h.warn(string.format("Invalid entry <code>%s</code>. See [[Data:Franchise]] for a list of valid entries.", game)) | |||
return nil | return nil | ||
elseif properCode and properCode ~= game then | elseif properCode and properCode ~= game then | ||
h.warn(string.format("<code>%s</code> should be written as <code>%s</code>", game, properCode)) | |||
end | end | ||
return link | return link..notes | ||
end | end | ||
function p.GameBlocks(frame) | function p.GameBlocks(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local blocks, categories = h.parseBlocks(args) | |||
local html = mw.html.create("ul"):addClass("infobox-game-blocks") | |||
for i, block in ipairs(blocks) do | |||
local gameText = html | |||
:tag("li") | |||
:addClass("infobox-game-blocks__game") | |||
:tag("span") | |||
:addClass("infobox-game-blocks__game-text") | |||
local game = gameText:done() | |||
if blocks.compact then | |||
gameText:wikitext(Franchise.display(block.game)) | |||
local gameList = game | |||
:tag("ul") | |||
:addClass("infobox-game-blocks__game-list") | |||
for j, listItem in ipairs(block.listItems) do | |||
gameList | |||
:tag("li") | |||
:addClass("infobox-game-blocks__game-list-item") | |||
:wikitext(listItem) | |||
end | |||
else | |||
html:addClass("infobox-game-blocks--compact") | |||
gameText | |||
:tag("span") | |||
:addClass(CLASS_TOOLTIP) | |||
:attr("title", Franchise.shortName(block.game)) | |||
:wikitext(block.game) | |||
:done() | |||
:wikitext(": ") | |||
game:wikitext(block.listItems[1]) | |||
end | |||
end | |||
return tostring(html), categories | |||
end | |||
function h.parseBlocks(args) | |||
local categories = "" | local categories = "" | ||
local seenParams = {} | local seenParams = {} | ||
local blocks = {} | local blocks = {} | ||
blocks.compact = false | |||
for i, game in ipairs(Franchise.enum({ includeSeries = true })) do | for i, game in ipairs(Franchise.enum({ includeSeries = true })) do | ||
seenParams[game] = true | seenParams[game] = true | ||
Line 131: | Line 180: | ||
listItems = listItems and utilsString.trim(listItems) | listItems = listItems and utilsString.trim(listItems) | ||
listItems = listItems and utilsString.nilIfEmpty(listItems) | listItems = listItems and utilsString.nilIfEmpty(listItems) | ||
if listItems and string.find(listItems, ", %l") then | |||
h.warn("Lowercase character detected following comma. Within <code>Template:Infobox Game Blocks</code>, commas are used to separate list items. All list items should be in sentence case. Literal commas can be escaped using {{Template|,}}.") | |||
categories = categories..CATEGORY_INVALID_ARGS | |||
end | |||
if listItems and string.find(listItems, "<br") then | |||
h.warn("Using <code><nowiki><br></nowiki></code> tags to create lists is discouraged. Use commas instead, as this template treats them as delimiters. See [[Template:Infobox Game Blocks]] for more information.") | |||
categories = categories..CATEGORY_BR_TAGS | |||
listItems = utilsString.split(listItems, "<br>") | |||
listItems = utilsTable.flatMap(listItems, utilsString._split("<br/>")) | |||
elseif listItems then | |||
listItems = utilsString.split(listItems, '%s*,%f[^,%d]%s*') -- %f[^,%d] is so we don't split numbers on their thousands separator (e.g., 1,500) | |||
end | |||
if listItems then | if listItems then | ||
table.insert(blocks, { | table.insert(blocks, { | ||
game = | game = game, | ||
listItems = | listItems = listItems, | ||
}) | }) | ||
end | |||
local hasDiv = listItems and listItems[1] and string.find(listItems[1], "<div") -- See [[Minuet of Forest]] "Notes" field, for example | |||
if listItems and #listItems > 1 or hasDiv then | |||
blocks.compact = true | |||
end | |||
if listItems and listItems[1] and string.find(listItems[1], "plainlist") then | |||
blocks.compact = true | |||
end | end | ||
end | end | ||
Line 142: | Line 210: | ||
if not seenParams[k] then | if not seenParams[k] then | ||
local errorMessage = string.format("Invalid game <code>%s</code>", k) | local errorMessage = string.format("Invalid game <code>%s</code>", k) | ||
h.warn(errorMessage) | |||
categories = categories..CATEGORY_INVALID_ARGS | categories = categories..CATEGORY_INVALID_ARGS | ||
end | end | ||
end | end | ||
local | return blocks, categories | ||
end | |||
function p.Title(frame) | |||
local subpageName = mw.title.getCurrentTitle().subpageText | |||
local term = Term.fetchTerm(subpageName, "Series") | |||
return term or utilsString.stripTrailingParentheses(subpageName) | |||
end | |||
function h.warn(msg, ...) | |||
local utilsError = require("Module:UtilsError") | |||
local warnMessage = string.format(msg, ...) | |||
utilsError.warn(warnMessage, { | |||
includeInstance = false, | |||
}) | |||
end | end | ||
Line 188: | Line 242: | ||
format = "block", | format = "block", | ||
purpose = string.format("[[Guidelines:Articles#Infobox|Infobox]] for [[:Category:%s|%s]].", plural, string.lower(plural)), | purpose = string.format("[[Guidelines:Articles#Infobox|Infobox]] for [[:Category:%s|%s]].", plural, string.lower(plural)), | ||
categories = {"Infobox | categories = {"Infobox templates"}, | ||
boilerplate = { | boilerplate = { | ||
separateRequiredParams = false, | separateRequiredParams = false, | ||
Line 241: | Line 295: | ||
name = "producer", | name = "producer", | ||
desc = "The producer(s) of the film.", | desc = "The producer(s) of the film.", | ||
type = "content", | |||
}, | |||
{ | |||
name = "writer", | |||
desc = "The writer(s) of the film.", | |||
type = "content", | |||
}, | |||
{ | |||
name = "production", | |||
desc = "The companies producing the film.", | |||
type = "content", | |||
}, | |||
{ | |||
name = "distributor", | |||
desc = "The companies distributing the film.", | |||
type = "content", | type = "content", | ||
}, | }, | ||
Line 288: | Line 357: | ||
} | } | ||
p.Documentation | function p.Documentation() | ||
return { | |||
Games = { | |||
desc = "Used by [[:Category:Infobox templates|infobox templates]] to turn comma-separated [[Data:Franchise|game codes]] into lists of games.", | |||
frameParams = { | |||
[1] = { | |||
name = "param", | |||
desc = "The infobox parameter, usually <code><nowiki>{{{game|}}}</nowiki></code> or <code><nowiki>{{{other|}}}</nowiki></code>.", | |||
}, | |||
}, | }, | ||
cases = { | |||
{ | |||
args = {"TLoZ, TAoL, ALttP"}, | |||
}, | |||
{ | |||
args = {"TLoZ (Ran), BoMC, TLoZ (Susumu)"}, | |||
}, | |||
{ | |||
args = {""}, | |||
}, | |||
{ | |||
args = {}, | |||
}, | |||
{ | |||
args = {"invalid game"}, | |||
}, | |||
{ | |||
args = {"OoT, invalid game, TP"}, | |||
}, | |||
{ | |||
desc = "br tags are discouraged due to the poor HTML semantics.", | |||
args = {"{{OoT}}<br>{{TP}}<br/>{{TotK}}"}, | |||
}, | |||
} | |||
}, | }, | ||
Image = { | |||
{ | desc = "Used by [[:Category:Infobox templates|infobox templates]] to generate an image when [[Template:Media]] is not used.", | ||
frameParams = { | |||
[1] = { | |||
name = "file", | |||
desc = "The image parameter - a file name.", | |||
}, | |||
[2] = { | |||
name = "caption", | |||
desc = "The caption parameter.", | |||
}, | |||
size = { | |||
desc = "Image size in pixels. Sprites are scaled to a maximum of 10 times their original size.", | |||
default = DEFAULT_IMG_SIZE, | |||
}, | |||
}, | }, | ||
{ | cases = { | ||
desc = "Sprites are scaled to a maximum of 10 times their original size.", | { | ||
args = {"File:TWW Great Fairy Figurine Model.png"}, | |||
}, | |||
{ | |||
args = {"File:TWW Great Fairy Figurine Model.png", "Great Fairy Figurine", size = "250px"} | |||
}, | |||
{ | |||
desc = "Sprites are scaled to a maximum of 10 times their original size.", | |||
args = {"File:ALttP Apple Sprite.png"}, | |||
}, | |||
{ | |||
desc = "[[Template:Media]] output is rendered as-is", | |||
args = {"{{Media|Model TWW= TWW Great Fairy Figurine Model.png}}"} | |||
}, | |||
{ | |||
desc = "Anything other than a file name starting with <code>File:</code> is rendered as-is", | |||
args = {"{{Plural|Series|Cyber Pico Bloom}} are never seen in-game"}, | |||
}, | |||
}, | }, | ||
}, | }, | ||
} | } | ||
end | |||
return p | return p |
edits