Module:Card: Difference between revisions

ReisuDesign (talk | contribs)
Adds support for split image
ReisuDesign (talk | contribs)
Undo revision 32042 by ReisuDesign (talk)
Tag: Undo
Line 1: Line 1:
local p = {}
local p = {}


Line 8: Line 7:


local allData = {
local allData = {
-- Neighbor
--Neighbor
{'Neighbor', mw.loadData('Module:CentralData/Neighbors')},
{'Neighbor', mw.loadData('Module:CentralData/Neighbors')},
 
--Creatures
-- Creatures
{'Fish', mw.loadData('Module:CentralData/Aquatic Creatures')},
{'Fish', mw.loadData('Module:CentralData/Aquatic Creatures')},
{'Insect', mw.loadData('Module:CentralData/Land Creatures')},
{'Insect', mw.loadData('Module:CentralData/Land Creatures')},
{'Shore-Dweller', mw.loadData('Module:CentralData/Shore-Dwellers')},
{'Shore-Dweller', mw.loadData('Module:CentralData/Shore-Dwellers')},
 
--Furniture
-- Furniture
{'Furniture', mw.loadData('Module:CentralData/Furniture')},
{'Furniture', mw.loadData('Module:CentralData/Furniture')},
 
--Items
-- Items
{'Item', mw.loadData('Module:CentralData/Items')},
{'Item', mw.loadData('Module:CentralData/Items')},
{'Dish', mw.loadData('Module:CentralData/Dishes')},
{'Dish', mw.loadData('Module:CentralData/Dishes')},
{'Crop', mw.loadData('Module:CentralData/Crops')},
{'Crop', mw.loadData('Module:CentralData/Crops')},
{'Tool', mw.loadData('Module:CentralData/Tools')},
{'Tool', mw.loadData('Module:CentralData/Tools')},
 
--Clothing
-- Clothing
{'Clothing', mw.loadData('Module:CentralData/Clothing')},
{'Clothing', mw.loadData('Module:CentralData/Clothing')},
{'Styling', mw.loadData('Module:CentralData/Styling')},
{'Styling', mw.loadData('Module:CentralData/Styling')},
 
--Other
-- Other
{'Title', mw.loadData('Module:CentralData/Titles')},
{'Title', mw.loadData('Module:CentralData/Titles')},
{'Reaction', mw.loadData('Module:CentralData/Reactions')},
{'Reaction', mw.loadData('Module:CentralData/Reactions')},
{'Set', mw.loadData('Module:CentralData/Sets')},
{'Set', mw.loadData('Module:CentralData/Sets')},
 
--Redirects (Things that don't need their own pages)
-- Redirects
{'Redirect', mw.loadData('Module:CentralData/Redirects')},
{'Redirect', mw.loadData('Module:CentralData/Redirects')},
}
}
Line 60: Line 53:
{
{
name = 'type',
name = 'type',
},
{
name = 'split',
},
},
{
{
Line 125: Line 115:
function p.main(frame)
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
local args = require('Module:Arguments').getArgs(frame, {
wrapper = {'Template:Card'},
wrapper = { 'Template:Card' },
parentOnly = false
parentOnly = false
})
})
Line 186: Line 176:


-- Converts "Luca: Myriad Meadows" to "Myriad Meadows"
-- Converts "Luca: Myriad Meadows" to "Myriad Meadows"
-- Only affects the link target, not the displayed card name.
return mw.text.trim(value:gsub('^.-:%s*', '', 1))
return mw.text.trim(value:gsub('^.-:%s*', '', 1))
end
end
Line 195: Line 186:
node:css('width', width)
node:css('width', width)
end
end
end
-- Generates an icon for the second item in a split card.
-- Uses the same filename convention as Recipe.
local function makeSplitIcon(name)
name = tostring(name or '')
local safeName = lib.sanitizeFileName(name)
return '[[File:' ..
safeName ..
' Icon.png|74x74px|link=' ..
name ..
']]'
end
end


Line 215: Line 193:
-- Basic identity
-- Basic identity
out.name = out.name or 'Unknown'
out.name = out.name or 'Unknown'
out.split = out.split or ''


-- Use only a manually supplied type for lookup.
-- Use only a manually supplied type for lookup.
local requestedType = out.nonDefaults
-- This allows {{Card|Sockeye Salmon}} to search Creature, Item, etc.
and out.nonDefaults.type
local requestedType = out.nonDefaults and out.nonDefaults.type or nil
or nil
out.type, out.data = p.getTypeAndData(out.name, requestedType)
 
-- Base name for assets.
out.type, out.data = p.getTypeAndData(
-- Removes a trailing disambiguation such as "(Currency)"
out.name,
-- while keeping the full name for lookup and links.
requestedType
)
 
-- Base name for assets
out.image_name = out.name:gsub('%s*%([^()]*%)$', '')
out.image_name = out.name:gsub('%s*%([^()]*%)$', '')


-- Boolean parameters
-- Boolean params
out.mini = normalizeBool(out.mini)
out.mini = normalizeBool(out.mini)
out.first = normalizeBool(out.first)
out.first = normalizeBool(out.first)
Line 264: Line 237:
out.defaults.quality = out.data.quality
out.defaults.quality = out.data.quality


-- Safety fallback in case TemplateData does not re-resolve
-- defaults after processArgs.
if not (out.nonDefaults and out.nonDefaults.quality) then
if not (out.nonDefaults and out.nonDefaults.quality) then
out.quality = out.data.quality
out.quality = out.data.quality
Line 281: Line 256:
out.quality = normalizeQuality(out.quality)
out.quality = normalizeQuality(out.quality)


-- Label handling
-- Label/text handling
if out.show_label then
if out.show_label then
out.label = out.data
out.label = out.data and (out.data.name or out.data.title) or out.name
and (out.data.name or out.data.title)
or out.name
end
end


Line 294: Line 267:
-- Type-specific behavior
-- Type-specific behavior
local lcType = tostring(out.type or ''):lower()
local lcType = tostring(out.type or ''):lower()
 
if lcType == 'neighbor' then
if lcType == 'neighbor' then
if lib.isEmpty(out.label) then
if lib.isEmpty(out.label) then
Line 303: Line 276:
end
end
end
end
 
if tonumber(out.image_size) then
if tonumber(out.image_size) then
out.image_size = tonumber(out.image_size) + 2
out.image_size = tonumber(out.image_size) + 2
end
end
end
end
 
if lcType == 'redirect' then
if lcType == 'redirect' then
out.defaults.link = stripLinkPrefix(out.name)
out.defaults.link = stripLinkPrefix(out.name)
 
-- Safety fallback in case TemplateData does not re-resolve defaults.
if not (out.nonDefaults and out.nonDefaults.link) then
if not (out.nonDefaults and out.nonDefaults.link) then
out.link = stripLinkPrefix(out.name)
out.link = stripLinkPrefix(out.name)
Line 320: Line 294:
if out.show_caption and lib.isEmpty(out.caption) then
if out.show_caption and lib.isEmpty(out.caption) then
if out.data then
if out.data then
out.caption = out.data.title
out.caption = out.data.title or out.data.name or out.name
or out.data.name
or out.name
else
else
out.caption = out.name
out.caption = out.name
Line 330: Line 302:
-- Link handling
-- Link handling
if out.link == nil then
if out.link == nil then
out.link = lib.ternary(
out.link = lib.ternary(out.name == 'Unknown', '', out.name)
out.name == 'Unknown',
'',
out.name
)
end
end


Line 344: Line 312:
end
end


-- Main image filename
-- File name
if ne(out.image) then
if ne(out.image) then
out.final_file = out.image
out.final_file = out.image
else
else
out.final_file =
out.final_file = lib.sanitizeFileName(out.image_name) .. out.suffix .. '.' .. out.image_ext
lib.sanitizeFileName(out.image_name) ..
out.suffix ..
'.' ..
out.image_ext
end
end


-- Main image wikitext
-- Main image wikitext
local linkPart = out.no_link
local linkPart = out.no_link and '|link=' or ('|link=' .. out.final_link)
and '|link='
or ('|link=' .. out.final_link)


out.image_wikitext = table.concat({
out.image_wikitext = table.concat({
Line 366: Line 328:
out.image_size,
out.image_size,
'px|alt=',
'px|alt=',
out.data and (out.data.name or out.data.title)
out.data and (out.data.name or out.data.title) or out.name,
or out.name,
linkPart,
linkPart,
']]'
']]'
Line 377: Line 338:
function p._main(args)
function p._main(args)
local a = p._processArgs(args)
local a = p._processArgs(args)
local isSplit = ne(a.split)


local node_container = mw.html.create('div')
local node_container = mw.html.create('div')
:addClass('card-container')
:addClass('card-container')
-- Required by existing Recipe CSS
if isSplit then
node_container:addClass('recipe-type-split-card')
end


if a.mini then
if a.mini then
Line 392: Line 346:
end
end


-- Wrapper and body
-- Old-style wrapper/body structure
local node_card = node_container:tag('span')
local node_card = node_container:tag('span')
:addClass('card-wrapper')
:addClass('card-wrapper')
Line 400: Line 354:
-- Galaxy class on body
-- Galaxy class on body
if not a.mini and ne(a.galaxy) then
if not a.mini and ne(a.galaxy) then
node_card:addClass(
node_card:addClass('card-galaxy-' .. normalizeClassName(a.galaxy))
'card-galaxy-' .. normalizeClassName(a.galaxy)
)
end
end


-- Main image
-- Main image
local imageContainer = node_card:tag('span')
node_card:tag('span')
:addClass('card-image-container')
:addClass('card-image-container')
:addClass('card-quality-' .. a.quality)
:addClass('card-quality-' .. a.quality)
 
:wikitext(a.image_wikitext)
if isSplit then
imageContainer:addClass('recipe-type-split-image')
 
imageContainer:tag('span')
:addClass('recipe-type-split-half')
:addClass('recipe-type-split-half-a')
:wikitext(a.image_wikitext)
 
imageContainer:tag('span')
:addClass('recipe-type-split-half')
:addClass('recipe-type-split-half-b')
:wikitext(makeSplitIcon(a.split))
else
imageContainer:wikitext(a.image_wikitext)
end


-- Galaxy icon
-- Galaxy icon
Line 432: Line 369:
:wikitext(
:wikitext(
'[[File:' ..
'[[File:' ..
a.galaxy ..
a.galaxy ..  
' Icon.png|alt=' ..
' Icon.png|alt=' ..
a.galaxy ..
a.galaxy ..
Line 453: Line 390:
:addClass('card-modifier')
:addClass('card-modifier')
:addClass('card-modifier-first')
:addClass('card-modifier-first')
:wikitext(
:wikitext('[[File:Icon Item First.png|x25px|link=|alt=First]]')
'[[File:Icon Item First.png|x25px|link=|alt=First]]'
)
end
end


Line 463: Line 398:
:addClass('card-modifier')
:addClass('card-modifier')
:addClass('card-modifier-up')
:addClass('card-modifier-up')
:wikitext(
:wikitext('[[File:Icon Item UP.png|x25px|link=|alt=UP]]')
'[[File:Icon Item UP.png|x25px|link=|alt=UP]]'
)
end
end


-- Label below the image
-- Label/text below card image
if ne(a.label) then
if ne(a.label) then
node_container:tag('span')
node_container:tag('span')
Line 475: Line 408:
end
end


-- Caption
-- Caption below card
if isSplit then
if a.show_caption and ne(a.caption) then
local node_caption = node_container:tag('span')
:addClass('card-caption')
 
node_caption:wikitext(
'[[:' .. a.name .. ']] / [[:' .. a.split .. ']]'
)
 
setCaptionWidth(node_caption, a.caption_width)
 
elseif a.show_caption and ne(a.caption) then
local node_caption = node_container:tag('span')
local node_caption = node_container:tag('span')
:addClass('card-caption')
:addClass('card-caption')
Line 493: Line 416:
node_caption:wikitext(a.caption)
node_caption:wikitext(a.caption)
else
else
node_caption:wikitext(
node_caption:wikitext('[[', a.final_link, '|', a.caption, ']]')
'[[' .. a.final_link .. '|' .. a.caption .. ']]'
)
end
end


Line 506: Line 427:
function p.templateData(frame)
function p.templateData(frame)
return TemplateData.templateData(CARD_ARGS, {
return TemplateData.templateData(CARD_ARGS, {
description = 'Creates an item-style card with image, quality, label, caption, split images, modifiers, and optional data-driven icons.',
description = 'Creates an item-style card with image, quality, label, caption, modifiers, and optional data-driven icons.',
format = 'inline'
format = 'inline'
}, frame)
}, frame)