Module:Card
| Main | Documentation | Usage |
This Lua module is used primarily on pages in the Main namespace. It can be found on 2,430 pages, or on about 60.63% of those pages.
Edits to this Lua module will be widely noticed. To avoid large-scale disruption and unnecessary server load, any changes to this Lua module should be tested in its sandbox or testcases subpages. The tested changes can then be added to this page in one single edit.
Please consider discussing any changes in the wiki's Discord.
This module implements {{Card}}.
To update, see: Module:CentralData.
local p = {}
local lib = require('Module:Feature')
local ne = lib.isNotEmpty
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 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 COLON = ':'
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrapper = { 'Template:Card' },
parentOnly = false
})
return p._main(args)
end
function p._main(args)
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
-- 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
-- If rank contains a semicolon, then split and get first
if string.find(rank, ";") then
rank = array._main({
rank,
';',
firstItemOnly = 1
})
end
-- Make sure rank is uppercase
rank = rank:upper()
-- Modifiers:
local isFirst = args.first or false
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
-- hackish workaround to account for the slight transparent borders on hoyolab agent icons
if (tonumber(imageSize) ~= nil) then
imageSize = tonumber(imageSize) + 2
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
local final_file = args.image or type .. ' ' .. lib.sanitizeFileName(item) .. suffix .. '.' .. imageExt
local final_link = link .. link_suffix
local file = '[[File:' .. final_file .. '|' .. imageSize .. 'px|alt=' .. item .. '|link=' .. final_link .. ']]'
local result = mw.html.create()
local card_container = result:tag('div')
:addClass('card-container')
:addClass('card-rank-' .. rank)
if args.mini == "1" then
card_container:addClass('mini-card')
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 label and not (args.label == "0" or args.text == "0") then --]]
if (label or args.show_text) and (args.label ~= "0" or args.text ~= "0") then
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
if (caption or args.show_caption) and args.show_caption ~= "0" then
if args.show_caption == "1" then
caption = (data and data.name) or item
end
local card_caption = card_container:tag('div')
:addClass('card-caption')
:wikitext('[[', final_link, '|', caption, ']]')
if caption_width == 'auto' or lib.isEmpty(caption_width) then
card_caption:addClass('auto-width')
else
card_caption:css('width', caption_width)
end
end
if (isFirst) then
local card_mod_first = card_wrapper:tag('div')
:addClass('card-modifier card-modifier-first')
:wikitext('[[File:Icon Item First.png|x25px]]')
end
if (isUp) then
local card_mod_up = card_wrapper:tag('div')
:addClass('card-modifier card-modifier-up')
:wikitext('[[File:Icon Item UP.png|x25px]]')
end
-- Attribute icon, applied automatically for agents or manually specified for anything else
if args.mini ~= "1" then -- Only display the icons if mini is not set to "1"
if ne(agRank) then
card_body:addClass('card-rank-' .. string.lower(agRank))
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
if ne(weSpecialty) then
card_body:addClass('card-specialty-' .. string.lower(weSpecialty))
card_body:tag('span')
:addClass('card-icon-specialty')
:wikitext('[[File:Icon ', weSpecialty, '.png|alt=', weSpecialty, '|link=', weSpecialty, '|20px]]')
end
if ne(outRank) then
card_body:addClass('card-rank-' .. string.lower(outRank))
card_body:tag('span')
:addClass('card-icon-rank')
:wikitext('[[File:Icon Item Rank ', outRank, '.png|alt=', outRank, '|link=|20px]]')
end
local cinema = args.cinema or args.c or nil
if ne(cinema) then
card_body:tag('span')
:addClass('card-cinema')
:addClass('cinema-' .. cinema)
:wikitext(' C', cinema)
card_body:addClass('card-with-cinema')
end
local phase = args.phase or args.p or nil
if ne(phase) then
card_body:tag('span')
:addClass('card-phase')
:addClass('phase-' .. phase)
:wikitext(' P', phase)
card_body:addClass('card-with-phase')
end
local notice = args.notice or nil
if ne(notice) then
card_body:tag('span')
:addClass('card-notice-label')
:wikitext(notice)
end
if ne(enemyType) then
card_body:tag('span')
:addClass('card-icon-enemy-type')
:wikitext('[[File:', enemyType, ' Icon.png|alt=', enemyType, '|link=', enemyType, '|28px]]')
end
if ne(enemyWeakness) then
local weaknessContainer = card_body:tag('span')
:addClass('card-enemy-weaknesses')
for weakness in lib.gsplit(enemyWeakness, ';') do
weaknessContainer:wikitext('[[File:Icon ', weakness, '.png|16px|link=', weakness, '|Weak to ', weakness, ']]')
end
end
end
if ne(enemyTier) then
card_body:addClass('card-enemy card-enemy-' .. enemyTier:gsub(' ', ''))
end
return tostring(result)
end
function p.getTypeAndData(name, type)
local img_type = type or 'Item'
local img_data = nil
for i, v in ipairs(allData) do
-- Only if the type was either not provided in the card args or if the provided type from card args is equal
if lib.isEmpty(type) or v[1] == type then
local data = v[2][name]
if data then
img_type = v[1]
img_data = data
break
end
end
end
return img_type, img_data
end
return p