To edit the documentation or categories for this module, click here.
local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_map = require("Module:MapUtil")
local util_page = require("Module:PageUtil")
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_title = require('Module:TitleUtil')
local util_vars = require('Module:VarsUtil')
local m_team = require('Module:Team')
local lang = mw.getLanguage('en')
local systems = mw.loadData('Module:Systems')
local TeamMembers = require('Module:QueryTeamMembers').main
local SUFFIX, SYSTEM
-- structure of data:
-- aboveFold = thisteam, [thisteam] = { list of players }
-- belowFold = {
-- active = { team, team, team, }
-- inactive = { list, of, teams },
-- [team] = { list of players }, ........
-- }
local p = {}
local h = {}
function p.main(frame)
local args = util_args.merge()
if util_vars.getBool('suppressorgnavbox') then return '' end
-- get inputs
h.castArgs(args)
local vars = h.getVariables(args)
return p._makeNavbox(vars)
end
function p._makeNavbox(vars)
if not vars.team then return '' end
local data = h.getData(vars)
if not data then return '' end
SUFFIX = vars.suffix
SYSTEM = vars.system
h.processLinks(data)
return h.makeOutput(data, vars)
end
function h.castArgs(args)
-- args provided include team and is_player
-- if we're on a player page, we also will know system already
-- but if we're on a team page we'll have to query here, which we'll do later
-- suffix is whether or not we care about the suffix of the page we're on
args.suffix = util_args.castAsBool(args.suffix)
args.team = args[1]
end
function h.getVariables(args)
-- copy args to a separate internal object
local title = util_title.titleTable()
local ret = {}
local titleteam = table.remove(title,1)
ret.team = args.team
ret.organization = args.organization
ret.system = args.system and systems[args.system] or h.getSystemFromTitle(title)
ret.teamlink = util_title.concatSubpage(ret.team, ret.system)
ret.suffix = args.suffix and next(title) and table.concat(title,'/')
ret.state = args.innerstate or 'mw-collapsed'
return ret
end
function h.getSystemFromTitle(title)
-- if we're on a team page then the system will be the 2nd part of the title
-- this only applies to team pages because players aren't system-specific
if title[1] and systems[title[1]] then
return systems[table.remove(title,1)]
end
return nil
end
function h.getData(vars)
-- to make a navbox, we must have either an active roster or sister teams
-- if we have an active roster, we query that and it will go above the fold
-- if we have sister teams, all of that goes below the fold
local data = {}
local active = false
local thisteam = vars.team
local thisteamlink = vars.teamlink
if h.isActive(thisteamlink) then
active = true
data.aboveFold = thisteam
data[thisteam] = h.getPlayers(thisteamlink)
end
if vars.team then
h.addSisterTeamInfoToData(vars, data)
end
return (active or data.hasSister) and data
end
function h.isActive(teamlink)
-- a team is active if both its page exists and also it's not disbanded
if not mw.title.makeTitle('',teamlink).exists then return false end
local query = {
tables = 'Teams',
fields = 'IsDisbanded [boolean]',
where = string.format('_pageName="%s"',teamlink),
}
return not util_cargo.getOneResult(query)
end
function h.getPlayers(team)
local result = TeamMembers(team)
local playerData = {}
for i, row in ipairs(result) do
playerData[i] = row.Link
if row.PlayerPage and not row.Link then
error(('Missing player data for %s'):format(row.PlayerPage))
elseif not row.Link then
error('One or more players is missing data for this team. Please blank edit all players on the team.')
end
playerData[row.Link] = {
link = row.Link,
ID = row.ID,
RoleList = row.RoleList,
}
end
return playerData
end
function h.addSisterTeamInfoToData(vars, data)
-- all data about sister teams goes below the fold except sisterDataLocation & hasSister
-- sisterDataLocation is to be used for the edit button of the navbox
-- hasSister will be checked to see if we proceed with making the navbox or not & then ignored
local row = h.getSisterTeamData(vars.team)
if not row then return end
data.belowFold = h.parseSisterTeamData(row)
h.addSisterTeamPlayersToActiveData(data.belowFold)
data.sisterDataLocation = row._pageName
data.hasSister = true
end
function h.getSisterTeamData(team)
local query = {
tables = 'SisterTeams',
fields = {
"Status=Status",
"_pageName",
"ActiveList=ActiveList",
"InactiveList=InactiveList"
},
where = ('Team="%s"'):format(m_team.teamlinkname(team)),
}
return util_cargo.getOneRow(query)
end
function h.parseSisterTeamData(row)
local teamData = {
active = util_text.splitNonempty(row.ActiveList),
inactive = util_text.split(row.InactiveList),
}
if not teamData.inactive then return end
for _, team in ipairs(teamData.inactive) do
teamData.inactive[team] = { link = team, name = team }
end
return teamData
end
function h.addSisterTeamPlayersToActiveData(belowFold)
for _, team in ipairs(belowFold.active) do
belowFold[team] = h.getPlayers(team)
end
end
-- process links
-- need to figure out how to deal with different systems & links
-- but i think that will be handled with team links / sister team concepts
function h.processLinks(data)
-- we want the navbox to link to corresponding subpages always
-- so make a long list of all links we have, and then determine existence
-- make a lookup table that we'll refer to when printing to decide if we link to the subpage or not
local linksToCheck = h.getListOfAllLinks(data)
util_map.inPlace(linksToCheck, util_title.concatSubpage, SUFFIX)
local linksHash = util_table.hash(util_page.whichPagesExist(linksToCheck))
h.processLinksInData(data, linksHash)
end
function h.getListOfAllLinks(data)
local linksToCheck = {}
if data.aboveFold then
linksToCheck[#linksToCheck+1] = data.aboveFold
linksToCheck[#linksToCheck+1] = util_title.concatSubpageSystem(data.aboveFold, SYSTEM)
util_table.mergeArrays(linksToCheck, data[data.aboveFold])
end
if data.belowFold then
util_table.mergeArrays(linksToCheck, data.belowFold.inactive)
for k, v in ipairs(data.belowFold.active) do
linksToCheck[#linksToCheck+1] = v
util_table.mergeArrays(linksToCheck, data.belowFold[v])
end
end
return linksToCheck
end
function h.processLinksInData(data, linksHash)
-- we need 3 pieces of information per link: the link, the display, and whether the proper subpage exists (so we can add the class if needed)
-- where before we had a table of links, we can add tables of names/exists by adding extra data
-- where we had a constant, we need to transform to having a table of information
h.addExtraDataToLinkTables(data[data.aboveFold], linksHash)
data.aboveFold = h.transformLinkToTable(data.aboveFold, linksHash)
if data.belowFold then
for i, team in ipairs(data.belowFold.active) do
h.addExtraDataToLinkTables(data.belowFold[team], linksHash)
data.belowFold.active[i] = h.transformLinkToTable(team, linksHash)
end
h.addExtraDataToLinkTables(data.belowFold.inactive, linksHash)
end
return
end
function h.addExtraDataToLinkTables(list, hash)
if not list or not next(list) then return end
for k, v in ipairs(list) do
local newlink = util_title.concatSubpage(v, SUFFIX)
local exists = hash[lang:ucfirst(newlink)]
list[v].exists = exists
list[v].link = exists and newlink or v
end
return
end
function h.transformLinkToTable(link, linksHash)
if not link then return nil end
local newlink = util_title.concatSubpage(link, SUFFIX)
local exists = linksHash[lang:ucfirst(newlink)]
return {
name = link,
exists = exists,
link = exists and newlink or link
}
end
-- print output
function h.makeOutput(data, args)
-- navboxargs will be sent to Template:Navbox
-- if there's an active roster, then the active roster is printed expanded above the fold
-- then if there's sister team data we print that below the fold
local thisteam = data.aboveFold
local navboxargs = {
name = data.sisterDataLocation or 'OrgNavbox',
state = 'mw-collapsible'
}
local i = 1
if thisteam then
navboxargs.group1 = h.makeOneLink(
util_title.concatSubpageSystem(thisteam.link, SYSTEM),
m_team.teammediumname(thisteam.name),
thisteam.exists
)
navboxargs.list1 = h.makePlayersOutput(data[thisteam.name])
navboxargs.title = h.makeNavboxTitle(thisteam.name, 'Roster')
i = i + 1
else
navboxargs.title = h.makeNavboxTitle(args.team, 'Organization')
end
if data.belowFold then
navboxargs['list' .. i] = h.belowFold(data.belowFold, args.innerstate)
end
return mw.getCurrentFrame():expandTemplate{ title = 'Navbox', args = navboxargs }
end
function h.makeNavboxTitle(thisteam, defaulttext)
return ('<span class="%s">%s</span> %s'):format(
SUFFIX and 'no-subpage' or '',
m_team.rightlonglinked(thisteam, { system = SYSTEM, size = 45 }),
SUFFIX and ('- ' .. SUFFIX) or defaulttext
)
end
function h.belowFold(data, state)
-- print all of the active teams along with their list of players
-- then print all of the inactive teams just as a list
-- we return an already-made template that gets passed to the outer navbox as an arg
local navboxargs = {
'child',
title = 'Other Teams In Organization (Click [Show] to the Right)',
state = state
}
for i, v in ipairs(data.active) do
navboxargs['group' .. i] = h.makeOneLink(
util_title.concatSubpageSystem(v.link, SYSTEM),
v.name,
v.exists
)
navboxargs['list' .. i] = h.makePlayersOutput(data[v.name])
end
if data.inactive then
navboxargs.below = h.makeTeamsOutput(data.inactive)
end
return mw.getCurrentFrame():expandTemplate{ title = 'Navbox', args = navboxargs }
end
function h.makePlayersOutput(data)
local display = {}
for _, link in ipairs(data) do
local linkInfo = data[link]
display[#display+1] = ('%s%s'):format(
linkInfo.RoleList:images() or '',
h.makeOneLink(linkInfo.link, linkInfo.ID, linkInfo.exists)
)
end
return util_table.concat(display,' • ')
end
function h.makeTeamsOutput(data)
local display = {}
for _, link in ipairs(data or {}) do
local linkInfo = data[link]
display[#display+1] = h.makeOneLink(linkInfo.link, linkInfo.name, linkInfo.exists)
end
local output = table.concat(display,' • ')
return output
end
function h.makeOneLink(link, name, exists)
-- concat link and display, adding the span class if it's not linking to the right subpage
if (not SUFFIX) or exists then
return util_text.intLink(link, name)
else
return ('<span class="no-subpage">[[%s|%s]]</span>'):format(link, name or link)
end
end
return p