Module:SummonIconTable: Difference between revisions
From Liquipedia Wildcard Wiki
No edit summary |
No edit summary Tag: Manual revert |
||
| Line 1: | Line 1: | ||
local Class = require('Module:Class') | local Class = require('Module:Class') | ||
local | local HeroIcon = require('Module:CharacterIcon') | ||
local Lua = require('Module:Lua') | local Lua = require('Module:Lua') | ||
local HtmlWidgets = Lua.import('Module:Widget/Html/All') | local HtmlWidgets = Lua.import('Module:Widget/Html/All') | ||
local Br = HtmlWidgets.Br | |||
local Div = HtmlWidgets.Div | local Div = HtmlWidgets.Div | ||
local Span = HtmlWidgets.Span | |||
local | local HeroIconTable = {} | ||
-- Constants for house themes and icons | -- Constants for house themes and icons | ||
local | local DEFAULT = {theme = 'gray-theme-dark-bg', text = 'All Summons'} | ||
local | local HERO_HOUSE = { | ||
['malus'] = { | ['malus'] = { | ||
theme = 'wildcard-malus-theme', | theme = 'wildcard-malus-theme', | ||
| Line 28: | Line 30: | ||
} | } | ||
function HeroIconTable.display(args) | |||
args = args or {} | args = args or {} | ||
local conditions = HeroIconTable._buildConditions(args) | |||
local conditions = | local heroes = mw.ext.LiquipediaDB.lpdb('datapoint', { | ||
local | |||
conditions = conditions, | conditions = conditions, | ||
order = 'name asc', | order = 'name asc', | ||
| Line 42: | Line 39: | ||
}) | }) | ||
-- Normalize results | -- Normalize results if single item | ||
if type( | if type(heroes) == 'table' and heroes.name then | ||
heroes = {heroes} | |||
elseif type( | elseif type(heroes) ~= 'table' then | ||
heroes = {} | |||
end | end | ||
local count = # | local count = #heroes | ||
local data = HeroIconTable._getCategoryData(args) | |||
return Div{ | return Div{ | ||
classes = {'white-text'}, | classes = {'white-text'}, | ||
css = {['text-align'] = 'center', ['font-weight'] = 'bold'}, | css = {['text-align'] = 'center', ['font-weight'] = 'bold'}, | ||
children = { | children = { | ||
HeroIconTable._createHeader(data, count), | |||
HeroIconTable._createBody(heroes) | |||
} | } | ||
} | } | ||
end | end | ||
function HeroIconTable._getCategoryData(args) | |||
function | |||
local house = args.house and string.lower(args.house) or nil | local house = args.house and string.lower(args.house) or nil | ||
return | return HERO_HOUSE[house] or DEFAULT | ||
end | end | ||
function HeroIconTable._createHeader(data, count) | |||
local headerText = data.text | |||
function | |||
local headerText = | |||
local headerChildren = {} | local headerChildren = {} | ||
-- Add | -- Add House Icon if available in data and it's not the default "All Summons" | ||
if data.icon and data.text ~= DEFAULT.text then | |||
table.insert(headerChildren, | table.insert(headerChildren, | ||
'[[' .. | '[[' .. data.icon .. '|30x30px|link=]] ' | ||
) | ) | ||
end | end | ||
table.insert(headerChildren, string.format('%s (%d)', headerText, count)) | table.insert(headerChildren, string.format('%s (%d)', headerText, count)) | ||
return Div{ | return Div{ | ||
classes = { | classes = {data.theme}, | ||
css = {padding = '5px 10px', ['font-size'] = '18px', ['border-radius'] = '0.5rem'}, | css = {padding = '5px 10px', ['font-size'] = '18px', ['border-radius'] = '0.5rem'}, | ||
children = headerChildren | children = headerChildren | ||
| Line 97: | Line 84: | ||
end | end | ||
function HeroIconTable._createBody(heroes) | |||
function | |||
return Div{ | return Div{ | ||
css = { | css = { | ||
| Line 110: | Line 94: | ||
['flex-wrap'] = 'wrap' | ['flex-wrap'] = 'wrap' | ||
}, | }, | ||
children = | children = HeroIconTable._generateHeroIcons(heroes) | ||
} | } | ||
end | end | ||
function HeroIconTable._generateHeroIcons(heroes) | |||
function | |||
local icons = {} | local icons = {} | ||
for _, entry in ipairs( | for _, entry in ipairs(heroes) do | ||
if entry.name then | if entry.name then | ||
-- | -- Determine house-based theme | ||
local heroTheme = DEFAULT.theme | |||
if entry.extradata and entry.extradata.house then | |||
local house = string.lower(entry.extradata.house) | |||
if HERO_HOUSE[house] then | |||
heroTheme = HERO_HOUSE[house].theme | |||
end | |||
end | |||
table.insert(icons, Div{ | table.insert(icons, Div{ | ||
classes = {'zoom-container'}, | classes = {'zoom-container'}, | ||
css = { | css = {width = '85px', display = 'inline-block'}, | ||
children = { | children = { | ||
Div{ | |||
classes = {heroTheme}, | |||
css = { | |||
['border-radius'] = '0.5rem 0.5rem 0 0', | |||
overflow = 'hidden', | |||
['margin-bottom'] = '2px', | |||
['text-align'] = 'center' | |||
}, | |||
children = {HeroIconTable._getHeroIconContainer(entry)} | |||
}, | |||
Div{ | |||
classes = {heroTheme}, | |||
css = { | |||
['border-radius'] = '0 0 0.5rem 0.5rem', | |||
overflow = 'hidden', | |||
padding = '2px', | |||
['margin-bottom'] = '10px', | |||
['text-align'] = 'center' | |||
}, | |||
children = { | |||
Span{ | |||
css = { | |||
['font-size'] = entry.name == 'Bolgar' and '10.5px' or '13.5px', | |||
['font-weight'] = 'bold', | |||
['word-break'] = 'break-word' | |||
}, | |||
children = {entry.name} | |||
} | |||
} | |||
} | } | ||
} | } | ||
| Line 144: | Line 152: | ||
end | end | ||
-- | function HeroIconTable._getHeroIconContainer(entry) | ||
return Div{ | |||
css = { | |||
function | width = '85px', | ||
height = '85px', | |||
display = 'flex', | |||
['align-items'] = 'center', | |||
['justify-content'] = 'center', | |||
overflow = 'hidden' | |||
}, | |||
children = { | |||
HeroIconTable._getHeroIcon(entry) | |||
} | |||
} | |||
end | |||
function HeroIconTable._getHeroIcon(entry) | |||
return HeroIcon.Icon{ | |||
character = entry.name, | |||
size = 'x85px' | |||
} | |||
end | |||
function HeroIconTable._buildConditions(args) | |||
local conditions = { | local conditions = { | ||
'[[type::Summon]]', | '[[type::Summon]]', | ||
'[[name::!]]' | '[[name::!]]' | ||
} | } | ||
if args.house then | if args.house then | ||
table.insert(conditions, '[[extradata_house::' .. args.house .. ']]') | table.insert(conditions, '[[extradata_house::' .. args.house .. ']]') | ||
end | end | ||
return table.concat(conditions, ' AND ') | return table.concat(conditions, ' AND ') | ||
end | end | ||
return Class.export( | return Class.export(HeroIconTable) | ||
Revision as of 16:39, 6 May 2025
Overview
[edit]This module creates a responsive grid display of summons icons with automatic categorization into their houses.
It pulls data from Liquipedia's database and applies theme-appropriate styling.
By default this module show all heroes available.
You can either use invoke or simple template.
For invoke use:
{{#invoke:Lua|invoke|module=SummonIconTable|fn=display}}(All Heroes){{#invoke:Lua|invoke|module=SummonIconTable|house=Malus|fn=display}}{{#invoke:Lua|invoke|module=SummonIconTable|house=Lubabub|fn=display}}{{#invoke:Lua|invoke|module=SummonIconTable|house=Chronos|fn=display}}
Parameters
[edit]|house=(optional)- Malus: Shows only summons within Malus house (cinnabar-theme-dark-bg)
- Lubabub: Shows only summons within Lubabub house (forest-theme-dark-bg)
- Chronos: Shows only summons within Chronos house (gold-bg-alt)
Usage Examples
[edit]- All Summons
{{SummonIconTable}}
All Summons (268)
- Only Summons in Malus House
{{SummonIconTable|house=Malus}}
Copy/Paste
[edit]- All Summons
{{SummonIconTable}}
- Categorized Champions
{{SummonIconTable|house=Malus}}
{{SummonIconTable|house=Chronos}}
{{SummonIconTable|house=Lubabub}}
For more information on how to contribute, please refer to our Help:Edit an Article.
local Class = require('Module:Class')
local HeroIcon = require('Module:CharacterIcon')
local Lua = require('Module:Lua')
local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Br = HtmlWidgets.Br
local Div = HtmlWidgets.Div
local Span = HtmlWidgets.Span
local HeroIconTable = {}
-- Constants for house themes and icons
local DEFAULT = {theme = 'gray-theme-dark-bg', text = 'All Summons'}
local HERO_HOUSE = {
['malus'] = {
theme = 'wildcard-malus-theme',
text = 'Malus',
icon = 'File:Wildcard_gameasset_Malus_Faction_Icon_White.png'
},
['chronos'] = {
theme = 'wildcard-chronos-theme',
text = 'Chronos',
icon = 'File:Wildcard_gameasset_Chronos_Faction_Icon_White.png'
},
['lubabub'] = {
theme = 'wildcard-lubabub-theme',
text = 'Lubabub',
icon = 'File:Wildcard_gameasset_Lubabub_Faction_Icon_White.png'
}
}
function HeroIconTable.display(args)
args = args or {}
local conditions = HeroIconTable._buildConditions(args)
local heroes = mw.ext.LiquipediaDB.lpdb('datapoint', {
conditions = conditions,
order = 'name asc',
limit = 5000
})
-- Normalize results if single item
if type(heroes) == 'table' and heroes.name then
heroes = {heroes}
elseif type(heroes) ~= 'table' then
heroes = {}
end
local count = #heroes
local data = HeroIconTable._getCategoryData(args)
return Div{
classes = {'white-text'},
css = {['text-align'] = 'center', ['font-weight'] = 'bold'},
children = {
HeroIconTable._createHeader(data, count),
HeroIconTable._createBody(heroes)
}
}
end
function HeroIconTable._getCategoryData(args)
local house = args.house and string.lower(args.house) or nil
return HERO_HOUSE[house] or DEFAULT
end
function HeroIconTable._createHeader(data, count)
local headerText = data.text
local headerChildren = {}
-- Add House Icon if available in data and it's not the default "All Summons"
if data.icon and data.text ~= DEFAULT.text then
table.insert(headerChildren,
'[[' .. data.icon .. '|30x30px|link=]] '
)
end
table.insert(headerChildren, string.format('%s (%d)', headerText, count))
return Div{
classes = {data.theme},
css = {padding = '5px 10px', ['font-size'] = '18px', ['border-radius'] = '0.5rem'},
children = headerChildren
}
end
function HeroIconTable._createBody(heroes)
return Div{
css = {
gap = '8px',
padding = '8px 6px',
display = 'flex',
['justify-content'] = 'center',
['align-items'] = 'center',
['flex-wrap'] = 'wrap'
},
children = HeroIconTable._generateHeroIcons(heroes)
}
end
function HeroIconTable._generateHeroIcons(heroes)
local icons = {}
for _, entry in ipairs(heroes) do
if entry.name then
-- Determine house-based theme
local heroTheme = DEFAULT.theme
if entry.extradata and entry.extradata.house then
local house = string.lower(entry.extradata.house)
if HERO_HOUSE[house] then
heroTheme = HERO_HOUSE[house].theme
end
end
table.insert(icons, Div{
classes = {'zoom-container'},
css = {width = '85px', display = 'inline-block'},
children = {
Div{
classes = {heroTheme},
css = {
['border-radius'] = '0.5rem 0.5rem 0 0',
overflow = 'hidden',
['margin-bottom'] = '2px',
['text-align'] = 'center'
},
children = {HeroIconTable._getHeroIconContainer(entry)}
},
Div{
classes = {heroTheme},
css = {
['border-radius'] = '0 0 0.5rem 0.5rem',
overflow = 'hidden',
padding = '2px',
['margin-bottom'] = '10px',
['text-align'] = 'center'
},
children = {
Span{
css = {
['font-size'] = entry.name == 'Bolgar' and '10.5px' or '13.5px',
['font-weight'] = 'bold',
['word-break'] = 'break-word'
},
children = {entry.name}
}
}
}
}
})
end
end
return icons
end
function HeroIconTable._getHeroIconContainer(entry)
return Div{
css = {
width = '85px',
height = '85px',
display = 'flex',
['align-items'] = 'center',
['justify-content'] = 'center',
overflow = 'hidden'
},
children = {
HeroIconTable._getHeroIcon(entry)
}
}
end
function HeroIconTable._getHeroIcon(entry)
return HeroIcon.Icon{
character = entry.name,
size = 'x85px'
}
end
function HeroIconTable._buildConditions(args)
local conditions = {
'[[type::Summon]]',
'[[name::!]]'
}
if args.house then
table.insert(conditions, '[[extradata_house::' .. args.house .. ']]')
end
return table.concat(conditions, ' AND ')
end
return Class.export(HeroIconTable)