Editing Module:Card

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
local p = {}
local p = {}
local lib = require('Module:Feature')
local lib = require('Module:Feature')
local ne = lib.isNotEmpty
local ne = lib.isNotEmpty
local TemplateData = require('Module:TemplateData')
local link_label = require('Module:Link_Label')._main
local namespace = require('Module:Namespace_detect')._main
local getTemplateArgs = require('Module:Parser').getTemplateArgs
local array = require('Module:Array')
local array = require('Module:Array')
local CentralData = require('Module:CentralData')


local allData = CentralData.dataSheets
local allData = {
{'Agent', mw.loadData('Module:CentralData/Agents')},
{'W-Engine', mw.loadData('Module:CentralData/W-Engines')},
{'Drive Disc', mw.loadData('Module:CentralData/Drive Discs')},
{'Bangboo', mw.loadData('Module:CentralData/Bangboo')},
{'Enemy', mw.loadData('Module:CentralData/Enemies')},
{'Resonium', mw.loadData('Module:CentralData/Resonia')},
{'Item', mw.loadData('Module:CentralData/Items')},
{'Companion', mw.loadData('Module:CentralData/Companions')},
{'Outfit', mw.loadData('Module:CentralData/Outfits')},
}


local CARD_ARGS = {
local COLON = ':'
{
name = 'name',
alias = 1,
default = 'Unknown',
},
{
name = 'label',
alias = {2, 'text', 'count', 'amount', 'x'},
},
{
name = 'show_label',
alias = 'show_text',
type = '1',
},
{
name = 'quality',
alias = 'rarity',
default = 'Common',
},
{
name = 'type',
},
{
name = 'split',
},
{
name = 'suffix',
default = '',
},
{
name = 'image',
},
{
name = 'image_size',
alias = {'imageSize', 'size'},
},
{
name = 'image_ext',
alias = {'imageExt', 'ext', 'extension'},
default = 'png',
},
{
name = 'link',
},
{
name = 'link_suffix',
default = '',
},
{
name = 'no_link',
type = '1',
},
{
name = 'caption',
},
{
name = 'show_caption',
type = '1',
},
{
name = 'caption_width',
alias = 'captionWidth',
},
{
name = 'mini',
type = '1',
},
{
name = 'first',
type = '1',
},
{
name = 'up',
alias = 'UP',
type = '1',
},
{
name = 'notice',
},
}


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
})
})
return p._main(args)
return p._main(args)
end
end


local function getDataByName(dataType, dataTable, name)
function p._main(args)
local data = dataTable[name]
local item = args[1] or args.name or 'Unknown'
 
local label = args[2] or args.label or args.text or args.count or args.amount or args.x or nil
if data then
return data
-- Reset agent-specific data to prevent carry-over from previous cards
local agRank, agAttribute, agSpecialty, bbRank, weRank, weSpecialty, outRank, notice = nil, nil, nil, nil, nil, nil, nil, nil
-- Caption Params:
local caption = args.caption or nil
local caption_width = args.caption_width or args.captionWidth or nil
    -- Image File Params:
local type, data = p.getTypeAndData(item, args.type)
local suffix = args.suffix or ''
local imageSize = args.image_size or args.imageSize or lib.ternary(args.mini == '1', 48, 70)
local imageExt = args.image_ext or args.imageExt or 'png'
-- Link Params:
local link = args.link or lib.ternary(item == 'Unknown', '', item)
local link_suffix = args.link_suffix or ''
-- Rank Param:
local rank = args.rank or args.quality or args.rarity or nil
-- Try to get Rank From Data
if lib.isEmpty(rank) and data then
if data.rank then
rank = data.rank
end
end
-- If rank is still empty, set it to "C"
if lib.isEmpty(rank) then
rank = 'C'
end
end
 
local normalizedType = tostring(dataType or ''):lower()
-- If rank contains a semicolon, then split and get first
if normalizedType == 'neighbor' or normalizedType == 'neighbors' then
if string.find(rank, ";") then
return nil
rank = array._main({
rank,
';',
firstItemOnly = 1
})
end
end
 
for quality, names in pairs(dataTable) do
-- Make sure rank is uppercase
if type(names) == 'table' then
rank = rank:upper()
for _, itemName in ipairs(names) do
if itemName == name then
-- Modifiers:
return {
local isFirst = args.first or false
quality = quality
local isUp = args.UP or args.up or false
}
-- Attribute/specialty
local attribute = args.attr or args.attribute or nil
local specialty = args.spec or args.fightSpec or args.fs or nil
if lib.isEmpty(suffix) then
local lcType = type:lower()
if (lcType == 'agent') then
suffix = ' Icon'
--Grabs Agent Rank, Attribute and Specialty from Data to display icons
agRank = data['rank']
agAttribute = data['attribute']
agSpecialty = data['specialty']
--In Full-Size Card-Mode, if there is no specified text, Agents will default to using their full name displayed underneath.
if args.mini ~= "1" then
if (label == nil) then label = item end
end
-- In Mini-Size Card-Mode, if there is no specified text, Agents will use their "shortName" pulled from /data as the displayed text.
-- In cases where Agents do not have a "shortName", their full name will be displayed instead.
if args.mini == "1" then
if (label == nil) and data['shortName'] ~= nil then label = data['shortName']
elseif (label == nil) and data['shortName'] == nil then label = item
end
end
end
end
end
end
-- hackish workaround to account for the slight transparent borders on hoyolab agent icons
 
if (tonumber(imageSize) ~= nil) then
return nil
imageSize = tonumber(imageSize) + 2
end
 
function p.getTypeAndData(name, requestedType)
local img_type = requestedType or 'Item'
local img_data = nil
 
for _, v in ipairs(allData) do
local dataType = v[1]
local dataTable = v[2]
 
if lib.isEmpty(requestedType) or dataType == requestedType then
local data = getDataByName(dataType, dataTable, name)
 
if data then
img_type = dataType
img_data = data
break
end
end
elseif (lcType == 'bangboo') then
suffix = ' Icon'
--Grabs Bangboo Rank from Data to display icons
bbRank = data['rank']
elseif (lcType == 'w-engine') then
suffix = ' Icon'
--Grabs W-Engine Rank and Specialty from Data to display icons
weRank = data['rank']
weSpecialty = data['specialty']
elseif (lcType == 'enemy') then
suffix = '' --icon
enemyType = data and data['type'] or ''
enemyTier = data and data['tier'] or ''
enemyWeakness = data and data['weakness'] or ''
imageSize = lib.ternary(args.mini == '1', 48, 70)
elseif (lcType == 'drive disc') then
suffix = ' Icon'
elseif (lcType == 'npc') then
suffix = ' Icon'
elseif (lcType == 'outfit') then
suffix = ' Icon'
--Grabs Outfit Rank from Data to display icons
outRank = data['rank']
end
end
end
end


return img_type, img_data
local final_file = args.image or type .. ' ' .. lib.sanitizeFileName(item) .. suffix .. '.' .. imageExt
end
 
local final_link = link .. link_suffix
local function normalizeBool(value)
return value == true or value == '1' or value == 1 or value == 'yes'
local file = '[[File:' .. final_file .. '|' .. imageSize .. 'px|alt=' .. item .. '|link=' .. final_link .. ']]'
end
 
local result = mw.html.create()
local function normalizeClassName(value)
return tostring(value or '')
local card_container = result:tag('div')
:lower()
:addClass('card-container')
:gsub('%s+', '-')
:addClass('card-rank-' .. rank)
end
 
if args.mini == "1" then
local function normalizeQuality(quality)
card_container:addClass('mini-card')
quality = tostring(quality or '')
 
if quality:find(';', 1, true) then
quality = array._main({
quality,
';',
firstItemOnly = 1
})
end
end
local card_wrapper = card_container:tag('div')
:addClass('card-wrapper')
local card_body = card_wrapper:tag('div')
:addClass('card-body')
local card_link = card_wrapper:tag('div')
:addClass('card-link')
:wikitext('[[' .. final_link .. ']]')
local card_image = card_body:tag('div')
:addClass('card-image-container')
:wikitext(file)


if lib.isEmpty(quality) then
--[[if label and not (args.label == "0" or args.text == "0") then --]]
quality = 'Common'
    if (label or args.show_text) and (args.label ~= "0" or args.text ~= "0") then  
end
if args.show_label == "1" or args.show_text == "1" then
label = data and data.name or item
end
local card_label = card_container:tag('div')
:addClass('card-label')
:wikitext(label)
end


return normalizeClassName(quality)
if (caption or args.show_caption) and args.show_caption ~= "0" then
end
if args.show_caption == "1" then
 
caption = (data and data.name) or item
local function stripLinkPrefix(value)
end
value = tostring(value or '')
local card_caption = card_container:tag('div')
 
:addClass('card-caption')
-- Converts "Luca: Myriad Meadows" to "Myriad Meadows".
:wikitext('[[', final_link, '|', caption, ']]')
return mw.text.trim(value:gsub('^.-:%s*', '', 1))
end
if caption_width == 'auto' or lib.isEmpty(caption_width) then
 
card_caption:addClass('auto-width')
local function setCaptionWidth(node, width)
else
if width == 'auto' or lib.isEmpty(width) then
card_caption:css('width', caption_width)
node:addClass('auto-width')
end
else
node:css('width', width)
end
end
end
 
if (isFirst) then
-- Generates the second icon for a split card.
local card_mod_first = card_wrapper:tag('div')
local function makeSplitIcon(name, mini)
:addClass('card-modifier card-modifier-first')
name = tostring(name or '')
:wikitext('[[File:Icon Item First.png|x25px]]')
 
local size = mini and 74 or 56
 
return '[[File:' ..
lib.sanitizeFileName(name) ..
' Icon.png|' ..
size .. 'x' .. size ..
'px|link=' ..
name ..
']]'
end
 
function p._processArgs(args)
local out = TemplateData.processArgs(args, CARD_ARGS)
 
-- Basic identity
out.name = out.name or 'Unknown'
out.split = out.split or ''
 
-- Use only a manually supplied type for lookup.
local requestedType = out.nonDefaults
and out.nonDefaults.type
or nil
 
out.type, out.data = p.getTypeAndData(
out.name,
requestedType
)
 
-- Base name for assets.
-- Removes a trailing disambiguation such as "(Currency)".
out.image_name = out.name--:gsub('%s*%([^()]*%)$', '')
 
-- Boolean parameters
out.mini = normalizeBool(out.mini)
out.first = normalizeBool(out.first)
out.up = normalizeBool(out.up)
out.no_link = normalizeBool(out.no_link)
out.show_label = normalizeBool(out.show_label)
out.show_caption = normalizeBool(out.show_caption)
 
-- Image defaults
out.suffix = out.suffix or ''
out.image_ext = out.image_ext or 'png'
 
if lib.isEmpty(out.image_size) then
out.image_size = out.mini and 48 or 70
end
end
 
if lib.isEmpty(out.suffix) then
if (isUp) then
out.suffix = ' Icon'
local card_mod_up = card_wrapper:tag('div')
:addClass('card-modifier card-modifier-up')
:wikitext('[[File:Icon Item UP.png|x25px]]')
end
end
 
-- Data-driven defaults
-- Attribute icon, applied automatically for agents or manually specified for anything else
if out.data then
if args.mini ~= "1" then -- Only display the icons if mini is not set to "1"
if out.data.name then
if ne(agRank) then
out.defaults.label = out.data.name
card_body:addClass('card-rank-' .. string.lower(agRank))
out.defaults.caption = out.data.name
card_body:tag('span')
:addClass('card-icon-rank')
:wikitext('[[File:Icon AgentRank ', agRank, '.png|alt=', agRank, '|link=|20px]]')
end
if ne(bbRank) then
card_body:addClass('card-rank-' .. string.lower(bbRank))
card_body:tag('span')
:addClass('card-icon-rank')
:wikitext('[[File:Icon Bangboo Rank ', bbRank, '.png|alt=', bbRank, '|link=|20px]]')
end
if ne(weRank) then
card_body:addClass('card-rank-' .. string.lower(weRank))
card_body:tag('span')
:addClass('card-icon-rank')
:wikitext('[[File:Icon AgentRank ', weRank, '.png|alt=', weRank, '|link=|20px]]')
end
if ne(agAttribute) then
card_body:addClass('card-attribute-' .. string.lower(agAttribute))
card_body:tag('span')
:addClass('card-icon-attribute')
:wikitext('[[File:Icon ', agAttribute, '.png|alt=', agAttribute, '|link=', agAttribute, '|20px]]')
end
if ne(agSpecialty) then
card_body:addClass('card-specialty-' .. string.lower(agSpecialty))
card_body:tag('span')
:addClass('card-icon-specialty')
:wikitext('[[File:Icon ', agSpecialty, '.png|alt=', agSpecialty, '|link=', agSpecialty, '|20px]]')
end
end
 
if ne(weSpecialty) then
if out.data.title then
card_body:addClass('card-specialty-' .. string.lower(weSpecialty))
out.defaults.caption = out.data.title
card_body:tag('span')
:addClass('card-icon-specialty')
:wikitext('[[File:Icon ', weSpecialty, '.png|alt=', weSpecialty, '|link=', weSpecialty, '|20px]]')
end
end
 
if ne(outRank) then
if out.data.quality then
card_body:addClass('card-rank-' .. string.lower(outRank))
out.defaults.quality = out.data.quality
card_body:tag('span')
 
:addClass('card-icon-rank')
if not (out.nonDefaults and out.nonDefaults.quality) then
:wikitext('[[File:Icon Item Rank ', outRank, '.png|alt=', outRank, '|link=|20px]]')
out.quality = out.data.quality
end
end
end
end
local cinema = args.cinema or args.c or nil
 
if ne(cinema) then
-- Quality / rarity
card_body:tag('span')
out.quality = normalizeQuality(out.quality)
:addClass('card-cinema')
 
:addClass('cinema-' .. cinema)
-- Label handling
:wikitext(' C', cinema)
if out.show_label then
card_body:addClass('card-with-cinema')
out.label = out.data
and (out.data.name or out.data.title)
or out.name
end
 
if out.label == '0' then
out.label = nil
end
 
-- Type-specific behavior
local lcType = tostring(out.type or ''):lower()
 
if lcType == 'neighbor' then
if lib.isEmpty(out.label) then
if out.mini and out.data and out.data.shortName then
out.label = out.data.shortName
elseif not out.mini then
out.label = out.name
end
end
end
 
local phase = args.phase or args.p or nil
if tonumber(out.image_size) then
if ne(phase) then
out.image_size = tonumber(out.image_size) + 2
card_body:tag('span')
:addClass('card-phase')
:addClass('phase-' .. phase)
:wikitext(' P', phase)
card_body:addClass('card-with-phase')
end
end
end
    local notice = args.notice or nil
 
    if ne(notice) then
if lcType == 'redirect' then
    card_body:tag('span')
out.defaults.link = stripLinkPrefix(out.name)
:addClass('card-notice-label')
 
:wikitext(notice)
if not (out.nonDefaults and out.nonDefaults.link) then
    end
out.link = stripLinkPrefix(out.name)
if ne(enemyType) then
card_body:tag('span')
:addClass('card-icon-enemy-type')
:wikitext('[[File:', enemyType, ' Icon.png|alt=', enemyType, '|link=', enemyType, '|28px]]')
end
end
end
if ne(enemyWeakness) then
 
local weaknessContainer = card_body:tag('span')
-- Caption defaults
:addClass('card-enemy-weaknesses')
if out.show_caption and lib.isEmpty(out.caption) then
if out.data then
for weakness in lib.gsplit(enemyWeakness, ';') do
out.caption = out.data.title
weaknessContainer:wikitext('[[File:Icon ', weakness, '.png|16px|link=', weakness, '|Weak to ', weakness, ']]')
or out.data.name
end
or out.name
else
out.caption = out.name
end
end
end
end
 
-- Link handling
if ne(enemyTier) then
if out.link == nil then
card_body:addClass('card-enemy card-enemy-' .. enemyTier:gsub(' ', ''))
out.link = lib.ternary(
out.name == 'Unknown',
'',
out.name
)
end
 
out.link_suffix = out.link_suffix or ''
out.final_link = out.link .. out.link_suffix
 
if out.no_link then
out.final_link = ''
end
end
 
-- Main image filename
return tostring(result)
if ne(out.image) then
out.final_file = out.image
else
out.final_file =
lib.sanitizeFileName(out.image_name) ..
out.suffix ..
'.' ..
out.image_ext
end
 
-- Main image wikitext
local linkPart = out.no_link
and '|link='
or ('|link=' .. out.final_link)
 
out.image_wikitext = table.concat({
'[[File:',
out.final_file,
'|',
out.image_size,
'px|alt=',
out.data and (out.data.name or out.data.title)
or out.name,
linkPart,
']]'
})
 
return out
end
end


function p._main(args)
function p.getTypeAndData(name, type)
local a = p._processArgs(args)
local img_type = type or 'Item'
local isSplit = ne(a.split)
local img_data = nil
 
-- Outer container
for i, v in ipairs(allData) do
local node_container = mw.html.create('div')
-- Only if the type was either not provided in the card args or if the provided type from card args is equal
:addClass('card-container')
if lib.isEmpty(type) or v[1] == type then
 
local data = v[2][name]
if isSplit then
if data then
node_container:addClass('card-split-card')
img_type = v[1]
end
img_data = data
 
break
if a.mini then
end
node_container:addClass('mini-card')
end
 
-- Wrapper and body
local node_card = node_container:tag('span')
:addClass('card-wrapper')
:tag('span')
:addClass('card-body')
 
-- Galaxy class on body
if not a.mini and ne(a.galaxy) then
node_card:addClass(
'card-galaxy-' .. normalizeClassName(a.galaxy)
)
end
 
-- Main image container
local imageContainer = node_card:tag('span')
:addClass('card-image-container')
:addClass('card-quality-' .. a.quality)
 
-- Split or regular image
if isSplit then
imageContainer:addClass('card-split-image')
 
-- First item: top-left half
imageContainer:tag('span')
:addClass('card-split-half')
:addClass('card-split-half-a')
:wikitext(a.image_wikitext)
 
-- Second item: bottom-right half
imageContainer:tag('span')
:addClass('card-split-half')
:addClass('card-split-half-b')
:wikitext(makeSplitIcon(a.split, a.mini))
else
imageContainer:wikitext(a.image_wikitext)
end
 
-- Notice label
if not a.mini and ne(a.notice) then
node_card:tag('span')
:addClass('card-notice-label')
:wikitext(a.notice)
end
 
-- First modifier
if a.first then
node_card:tag('span')
:addClass('card-modifier')
:addClass('card-modifier-first')
:wikitext(
'[[File:Icon Item First.png|x25px|link=|alt=First]]'
)
end
 
-- UP modifier
if a.up then
node_card:tag('span')
:addClass('card-modifier')
:addClass('card-modifier-up')
:wikitext(
'[[File:Icon Item UP.png|x25px|link=|alt=UP]]'
)
end
 
-- Label below the image
if ne(a.label) then
node_container:tag('span')
:addClass('card-label')
:wikitext(a.label)
end
 
-- Caption
-- Split captions are opt-in and use spans instead of list items.
if a.show_caption and isSplit then
local node_caption = node_container:tag('span')
:addClass('card-caption')
:addClass('card-split-caption')
 
local list = node_caption:tag('span')
:addClass('card-split-caption-list')
 
list:tag('span')
:addClass('card-split-caption-item')
:wikitext('[[' .. a.name .. ']]')
 
list:tag('span')
:addClass('card-split-caption-item')
:wikitext('[[' .. a.split .. ']]')
 
setCaptionWidth(node_caption, a.caption_width)
 
elseif a.show_caption and ne(a.caption) then
local node_caption = node_container:tag('span')
:addClass('card-caption')
 
if a.no_link or lib.isEmpty(a.final_link) then
node_caption:wikitext(a.caption)
else
node_caption:wikitext(
'[[' .. a.final_link .. '|' .. a.caption .. ']]'
)
end
end
setCaptionWidth(node_caption, a.caption_width)
end
end
 
return tostring(node_container)
return img_type, img_data
end
 
function p.templateData(frame)
return TemplateData.templateData(CARD_ARGS, {
description = 'Creates an item-style card with image, quality, label, split images, modifiers, and optional data-driven icons.',
format = 'inline'
}, frame)
end
 
function p.syntax(frame)
return TemplateData.syntax(CARD_ARGS, frame)
end
end


return p
return p
Please note that all contributions to The Petit Planet Wiki are considered to be released under the Creative Commons Attribution-ShareAlike (see Petit Planet Wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template
Below are commonly used wikitext from MediaWiki:Edittools. Click on any to insert them in the edit box.
File Pages==Summary====Licensing=={{Fairuse}}{{File|}}
Dynamic Page List¦²«»²{¦}²«»«/»«!----»
Array in DPL¹^2{}^2^2{¹}^2
Parser Functions{{#if:||}}
{{#ifeq:|||}}
{{#expr:}}
{{#switch:||#default=}}
{{#replace:||}}
{{#titleparts:}}
{{#tag:|}}
Markup{{}}|[][[]][[Category:]]#REDIRECT [[]] [[Category:Redirect Pages]]<code></code><includeonly></includeonly><noinclude></noinclude><nowiki></nowiki><!----><br>§
Notices{{Stub|}}{{Stub Dialogue}}{{Upcoming}}{{Under Construction}}{{Placeholder|}}
Magic Words{{!}}{{formatnum:}}{{lc:}}{{uc:}}{{PAGENAME}}{{FULLPAGENAME}}{{ROOTPAGENAME}}{{BASEPAGENAME}}{{SUBPAGENAME}}{{DISPLAYTITLE:|noreplace}}__TOC____NOTOC____EXPECTUNUSEDCATEGORY____HIDDENCAT__
HTML Entities&mdash;&nbsp;&comma;&shy;