Module:Participant
From eSportsAmaze
More actions
Documentation for this module may be created at Module:Participant/doc
local p = {}
local html = mw.html
local cargo = mw.ext.cargo
local function sqlEscape(s)
if not s then return "" end
s = s:gsub("\\", "\\\\")
s = s:gsub("'", "\\'")
return s
end
-- HELPER: Smart Tournament Name Detection
local function getTournamentName(args)
if args.tournament and args.tournament ~= "" then return args.tournament end
local pageTitle = mw.title.getCurrentTitle().text
local parts = mw.text.split(pageTitle, '/')
if parts[2] == "Tournaments" and parts[3] then return parts[3] end
return mw.title.getCurrentTitle().baseText
end
-- INTERNAL: Builds the HTML for a single card
local function buildCard(data, seedOverride)
local root = html.create('div'):addClass('roster-card')
-- HEADER
local header = root:tag('div'):addClass('roster-header')
local headerContent = header:tag('div'):addClass('header-content')
-- LOGO LOGIC
-- Priority: 1. Tournament Entry Custom Logo -> 2. Master DB Custom Logo -> 3. Master DB Default Name -> 4. Shield
local lightLogo = "Shield_team.png"
local darkLogo = "Shield_team_dark.png"
-- Check Entry (Tournament specific) Override first
if data.entryImg and data.entryImg ~= "" then
lightLogo = data.entryImg
darkLogo = (data.entryImgDark and data.entryImgDark ~= "") and data.entryImgDark or lightLogo
-- Check Master DB
elseif data.masterImg and data.masterImg ~= "" then
lightLogo = data.masterImg
darkLogo = (data.masterImgDark and data.masterImgDark ~= "") and data.masterImgDark or lightLogo
end
local logoDiv = headerContent:tag('div'):addClass('roster-logo')
logoDiv:tag('div'):addClass('logo-lightmode'):wikitext('[[File:' .. lightLogo .. '|link=]]')
logoDiv:tag('div'):addClass('logo-darkmode'):wikitext('[[File:' .. darkLogo .. '|link=]]')
-- NAME LOGIC
local displayName = data.displayName
if not displayName or displayName == "" then displayName = data.team end
headerContent:tag('div'):addClass('roster-name'):wikitext('[[' .. data.team .. '|' .. displayName .. ']]')
-- SEEDING
local finalSeed = seedOverride
if not finalSeed or finalSeed == "" then finalSeed = data.seeding end
if finalSeed and finalSeed ~= "" then
root:tag('div'):addClass('roster-subheader'):wikitext(finalSeed)
end
-- PLAYERS
local contentRows = root:tag('div'):addClass('roster-content-rows')
local players = {data.p1, data.p2, data.p3, data.p4, data.p5, data.p6}
local playerCount = 0
for _, pl in ipairs(players) do if pl and pl ~= "" then playerCount = playerCount + 1 end end
local playerInner = contentRows:tag('div'):addClass('roster-players-inner'):addClass('count-' .. playerCount)
for _, pl in ipairs(players) do
if pl and pl ~= "" then
playerInner:tag('div'):addClass('roster-row player'):wikitext('[[' .. pl .. ']]')
end
end
-- STAFF
if (data.coach and data.coach ~= "") or (data.analyst and data.analyst ~= "") then
local staffInner = contentRows:tag('div'):addClass('roster-staff-inner')
if data.coach and data.coach ~= "" then staffInner:tag('div'):addClass('roster-row staff'):wikitext('C: [[' .. data.coach .. ']]') end
if data.analyst and data.analyst ~= "" then staffInner:tag('div'):addClass('roster-row staff'):wikitext('A: [[' .. data.analyst .. ']]') end
end
return tostring(root)
end
-- PUBLIC 1: ENTRY MODULE
function p.entry(frame)
local args = frame:getParent().args
local count = tonumber(args.count) or 20
local tournamentName = getTournamentName(args)
for i = 1, count do
local prefix = 't' .. i
local team = args[prefix]
if team and team ~= "" then
if cargo and cargo.store then
cargo.store("Tournament_Teams", {
tournament = tournamentName,
team = team,
display_name = args[prefix .. 'name'],
image = args[prefix .. 'img'],
image_dark = args[prefix .. 'imgdark'],
seeding = args[prefix .. 'seed'],
p1 = args[prefix .. 'p1'],
p2 = args[prefix .. 'p2'],
p3 = args[prefix .. 'p3'],
p4 = args[prefix .. 'p4'],
p5 = args[prefix .. 'p5'],
p6 = args[prefix .. 'p6'],
coach = args[prefix .. 'c'],
analyst = args[prefix .. 'a']
})
end
end
end
return "<div style='display:none;'>Roster Data Saved Successfully.</div>"
end
-- PUBLIC 2: DISPLAY MODULE
function p.display(frame)
local args = frame:getParent().args
local tournamentName = getTournamentName(args)
local count = tonumber(args.count) or 24
-- 1. Gather Requested Teams
local requestedTeams = {}
local orderedRequests = {}
for i = 1, count do
local team = args['t' .. i]
if team and team ~= "" then
local cleanTeam = sqlEscape(team)
table.insert(requestedTeams, "'" .. cleanTeam .. "'")
table.insert(orderedRequests, { name = team, seed = args['t' .. i .. 'seed'] })
end
end
if #requestedTeams == 0 then return "" end
local teamListSql = table.concat(requestedTeams, ", ")
-- 2. MEMORY MAP A: Fetch Rosters (Tournament Specific)
local rosterDb = {}
if cargo and cargo.query then
local rResults = cargo.query(
"Tournament_Teams",
"team, display_name, image, image_dark, seeding, p1, p2, p3, p4, p5, p6, coach, analyst",
{ where = "tournament='" .. sqlEscape(tournamentName) .. "' AND team IN (" .. teamListSql .. ")", limit = count }
)
for _, row in ipairs(rResults) do
rosterDb[row.team] = row
end
end
-- 3. MEMORY MAP B: Fetch Master Logos (Global Teams Table)
-- FIXED: We now query 'name' instead of '_pageName' to avoid underscore mismatches
local masterDb = {}
if cargo and cargo.query then
local mResults = cargo.query(
"Teams",
"name, image, image_dark",
{ where = "name IN (" .. teamListSql .. ")", limit = count }
)
for _, row in ipairs(mResults) do
masterDb[row.name] = row
end
end
-- 4. BUILD HTML
local container = html.create('div')
:addClass('participant-group-container')
:css('display', 'flex')
:css('flex-wrap', 'wrap')
:css('gap', '15px')
:css('justify-content', 'center')
for _, req in ipairs(orderedRequests) do
local teamName = req.name
local rosterData = rosterDb[teamName] or { team = teamName }
-- Merge Master Logos
if masterDb[teamName] then
-- 1. If DB has specific image set, use it
if masterDb[teamName].image and masterDb[teamName].image ~= "" then
rosterData.masterImg = masterDb[teamName].image
else
-- 2. If DB exists but field is blank, assume TeamName.png (Instead of Shield)
rosterData.masterImg = teamName .. ".png"
end
-- Dark Mode Logic
if masterDb[teamName].image_dark and masterDb[teamName].image_dark ~= "" then
rosterData.masterImgDark = masterDb[teamName].image_dark
else
rosterData.masterImgDark = rosterData.masterImg -- Fallback to light
end
end
rosterData.entryImg = rosterData.image
rosterData.entryImgDark = rosterData.image_dark
rosterData.displayName = rosterData.display_name
container:wikitext(buildCard(rosterData, req.seed))
end
return tostring(container)
end
return p