Module:Icon: Difference between revisions

From Final Fantasy XIV Online Wiki
Jump to navigation Jump to search
Gurgum (talk | contribs)
support stellar missions
Gurgum (talk | contribs)
fix logic for what does or doesn't get a frame
Line 108: Line 108:
-- @param dyeCount For items only
-- @param dyeCount For items only
local function gameIcon(args)
local function gameIcon(args)
-- use a plain icon for currencies, FATEs/CEs, quests, stellar missions
    -- use a plain icon for anything that isn't an achievement, item, or trait
     local lc_type = args.type:lower()
     local lc_type = args.type:lower()
if lc_type == "critical engagement" or lc_type == "currency" or lc_type == "fate" or lc_type == "quest" or lc_type == "stellar mission" then
if lc_type ~= "achievement" and lc_type ~= "item" and lc_type ~= "trait" then
return p.plainIcon({
return p.plainIcon({
icon = args.icon,
icon = args.icon,
Line 118: Line 118:
end
end


-- everything else uses a frame icon
-- achievements, items, and traits use a frame icon
local frame = nil
local frame = nil
if args.type == "Item" and args.hq then
if args.type == "Item" and args.hq then

Revision as of 21:49, 11 February 2026

This module contains several functions for rendering icons from the game, for use with both wikitext templates as well as from other Lua modules.


Wikitext functions

These functions are designed to be used directly in templates via {{#invoke:}}.

renderGameIcon

Renders the in-game icon of something.

Parameters

type
The type of thing being shown - quest, item, currency, action, achievement, etc. Usually pulled from Property:Has context.
icon
Icon file reference, including File: namespace and file extension. Usually pulled from Property:Has game icon.
link
Where the icon should link when clicked, usually the article name of the relevant concept.
size
Icon size. One of small, mid, or large. Defaults to small.

For item icons specifically, these parameters can also be used:

hq
If set, renders a high-quality item.
dyeCount
If set, renders an item with a number of dye slots. Usually pulled from Property:Has dye channels.

Example

{{#invoke: Icon | renderGameIcon
| type = Action
| icon = File:Transpose.png
| link = Transpose
| size = big
}}

renderGameIconWithLabel

Renders an in-game icon, alongside a label which links back to the thing, plus an optional quantity.

Parameters

All parameters taken by renderGameIcon, plus:

text
Label text. This text will be a link that directs to the link parameter. Pass nothing or set to "x" to hide the label (useful to display quantity in a condensed way).
qty
Quantity, displayed between the item icon and the label.
allowWrap
By default, icon and label will be grouped in a container that prevents text wrapping. Set this parameter to disable that behavior. This should only really be used in infoboxes and other narrow templates.

Examples

{{#invoke: Icon | renderGameIconWithLabel
| type = Action
| icon = File:Cure.png
| link = Cure
| size = small
| text = Freecure isn't real and can't hurt you
}}

Freecure isn't real and can't hurt you

renderGameIconFromQuery

Renders an iccon and label for something selected by the provided SMW {{#ask:}} query. Link is inferred from the query result.

Parameters

size
hq
text
qty
allowWrap
As described in § renderGameIcon and § renderGameIconWithLabel.

Examples

{{#invoke: Icon | renderGameIconFromQuery
| query = [[Has context::Item]][[Has internal ID::4]]
| size = big
}}

Wind Shard

Lua functions

These functions are designed to be called from other Lua modules and accept Lua values as their parameters instead of mw.frame objects. To use any of these functions, load the module first with e.g.

local icon = require("Module:Icon")

plainIcon

Displays a non-framed icon from the game, for example quest icons.

Parameters

Takes a single table parameter with the following keys:

icon
Icon file reference, including File: namespace and file extension.
link
Where the icon should link when clicked, usually the article name of the relevant concept.
size
Icon size. One of small, mid, or large. Defaults to small.

Returns

  • A wikitext string.

Example

local questIcon = icon.plainIcon({
    icon = "File:Quest icon.png",
    link = "Quest",
    size = "big",
})

frameIcon

Displays a framed icon from the game, for example an item or action.

Parameters

Takes a single table parameter with the following keys:

icon
Icon file reference, including File: namespace and file extension.
link
Where the icon should link when clicked, usually the article name of the relevant concept.
frame
Frame type for the icon. Can be hq, trait, achievement, or leave nil for the standard frame.
dyeCount
For items, the number of dye slots the item has. Default is 0.
size
Icon size. One of small, mid, or large. Defaults to small.

Returns

Example

local traitIcon = icon.frameIcon({
    icon = "File:Heavier shot.png",
    link = "Heavier Shot",
    frame = "trait",
    size = "big",
})

gameIconFromQuery

Executes an SMW query and renders icon and label for the resulting object. Link is inferred from query result.

Parameters

Takes a single table parameter with the following keys:

query
SMW query string.
size
hq
text
qty
allowWrap
As described in § renderGameIcon and § renderGameIconWithLabel, but with hq and allowWrap being proper Lua booleans rather than strings.

Returns

Wikitext string.

Examples

local myIcon = icon.gameIconFromQuery({
    query = "[[Has context::Item]][[Has internal ID::4]]",
    size = "big",
})

--[[
	A module for rendering icons from the game.

	Provides both library functions for use in other modules, and template functions for use with {{#invoke}}.
]]

-- TODO: break this out into its own module
local yesno = require("Module:Yesno")

local p = {}

-- CSS classes assigned to a frame icon based on desired frame type
local frameClasses = {
	trait = "standard-frame-icon-trait",
	achievement = "standard-frame-icon-achievement",
	hq = "standard-frame-icon-hq",
}
-- CSS classes assigned to frame icons at different sizes
local frameIconSizeClasses = {
	small = "small",
	mid = "mid",
	big = nil, -- default in CSS
}
-- Pixel dimensions of frame icons at different sizes
local frameIconSizeDimensions = {
	small = 20,
	mid = 30,
	big = 40
}

-- Pixel dimensions of non-frame icons at different sizes
local plainIconSizeDimensions = {
	small = 24,
	mid = 36,
	big = 48,
}

--- Renders a non-framed icon from the game.
-- @param icon
-- @param link
-- @param size
-- @return wikitext
function p.plainIcon(args)
	if not args.size or args.size == "" then
		args.size = "small"
	end
	args.link = args.link or args.icon -- default to icon page if no link is provided

	return ("[[%s|%dpx|link=%s]]"):format(
		args.icon,
		plainIconSizeDimensions[args.size],
		args.link
	)
end

--- Renders frame icon dye slots if there are any
-- @return HTML builder node
local function dyeSlots(dyeCount)
	if not dyeCount or dyeCount < 1 then
		return ""
	end

	span = mw.html.create("span"):addClass("standard-frame-icon-dye-slots")
	for i = 1, dyeCount do
		span:node(mw.html.create("span"))
	end
	return span
end

--- Renders an icon image inside a frame.
-- @param icon Image to use as icon, including "File:" namespace and ".png" extension
-- @param link Optional link for the icon, defaults to the icon image's file page
-- @param size Icon size, one of "small" "mid" "big"
-- @param frame Frame type, one of "trait" "achievement" "hq" or nil for standard frame
-- @param dyeCount For item icons: number of dye slots. One of 0, 1, 2, or nil
-- @return HTML builder node
function p.frameIcon(args)
	if not args.icon then
		error("icon is required")
	end
	if not args.size or args.size == "" then
		args.size = "small"
	end
	args.dyeCount = args.dyeCount or 0
	args.link = args.link or args.icon -- default to icon page if no link is provided

	return mw.html.create("span")
		:addClass("plainlinks")
		:addClass("standard-frame-icon")
		:addClass(frameClasses[args.frame])
		:addClass(frameIconSizeClasses[args.size])
		:wikitext(
			("[[%s|%dpx|link=%s]]"):format(
				args.icon,
				frameIconSizeDimensions[args.size],
				args.link
			)
		)
		:node(dyeSlots(args.dyeCount))
end

--- internal helper for generic template usage where type of icon isn't known beforehand and we're relying on SMW data
-- @param icon
-- @param link
-- @param size
-- @param type
-- @param hq For items only
-- @param dyeCount For items only
local function gameIcon(args)
    -- use a plain icon for anything that isn't an achievement, item, or trait
    local lc_type = args.type:lower()
	if lc_type ~= "achievement" and lc_type ~= "item" and lc_type ~= "trait" then
		return p.plainIcon({
			icon = args.icon,
			link = args.link,
			size = args.size,
		})
	end

	-- achievements, items, and traits use a frame icon
	local frame = nil
	if args.type == "Item" and args.hq then
		frame = "hq"
	elseif args.type == "Trait" then
		frame = "trait"
	elseif args.type == "Achievement" then
		frame = "achievement"
	end

	return p.frameIcon({
		icon = args.icon,
		link = args.link,
		size = args.size,
		frame = frame,
	})
end

-- function to be invoked from templates that don't display labels
function p.renderGameIcon(frame)
	return gameIcon({
		-- normalize parameters
		icon = frame.args.icon,
		link = frame.args.link,
		size = frame.args.size,
		type = frame.args.type,
		hq = yesno(frame.args.hq),
		dyeCount = tonumber(frame.args.dyeCount),
	})
end

-- implementation for {{Game icon}} and other templates that do display labels
function p.renderGameIconWithLabel(frame)
	-- if qty is empty then don't render it
	local qty = frame.args.qty
	if qty == "" then
		qty = nil
	end

	-- if text is empty or set to "x" (in template usage) don't render it
	local text = frame.args.text
	if text == "" or text == "x" then
		text = nil
	end

	local span = mw.html.create("span")
	-- set text wrapping
	if not yesno(frame.args.allowWrap) then
		span:css("white-space", "nowrap")
	end

	-- render icon using other passed parameters - this is a bit hacky but w/e
	span:node(p.renderGameIcon(frame))

	-- render quantity, if present
	if qty then
		span:node(" " .. qty)
	end

	-- render text link, if any
	if text then
		span:node((" [[%s|%s]]"):format(frame.args.link or frame.args.icon, text))
	end

	return span
end

--- internal helper for generic template usage where items/etc need to be looked
--- up via SMW query. really just a helper to invoke {{#ask}} with some fancy
--- parameters and format the result with {{Game icon format}}, which in turn
--- just calls back to this module's p.renderGameIconWithLabel. very cursed.
function p.gameIconFromQuery(args)
	return mw.getCurrentFrame():callParserFunction("#ask", {
		args.query,
		"?=Pagename",
		"?Has context",
		"?Has game icon",
		"?Has canonical name",
		"?Has dye channels",
        limit = 1,
        searchlabel = "",
		format = "plainlist",
		link = "none",
		["named args"] = "yes",
		template = "Game icon format",
		userparam = ("%s;%s;%s;%s;%s"):format(
			args.text or "",
			args.size or "",
			args.hq and "y" or "",
			args.qty or "",
			args.allowWrap and "y" or ""
		)
	})
end

--- gameIconWithQuery wrapped for use with {{#invoke}}
function p.renderGameIconFromQuery(frame)
	return p.gameIconFromQuery({
		query = frame.args.query,
		text = frame.args.text,
		size = frame.args.size,
		hq = yesno(frame.args.hq),
		qty = frame.args.qty,
		allowWrap = yesno(frame.args.allowWrap)
	})
end

return p