We're currently performing an overhaul of our entire tournament results system so results will be missing from team and player pages for a while, and there may be some errors on tournament pages. Please bear with us as we complete this update.

Module:SubpageTabs

From Call of Duty Esports Wiki
Jump to: navigation, search

To edit the documentation or categories for this module, click here.


local util_args = require('Module:ArgsUtil')
local util_map = require("Module:MapUtil")
local util_page = require("Module:PageUtil")
local util_table = require('Module:TableUtil')
local util_title = require('Module:TitleUtil')
local util_vars = require("Module:VarsUtil")

local tabs = require('Module:AutomatedTabs').main
local Navbox = require('Module:SubpageNavbox').navbox
local After = require('Module:SubpageAfter').after

local SETTINGS = mw.loadData('Module:SubpageSettings')
local PRELOAD = nil
local CURRENT_ROOT_TITLE = nil
local DELETE_UNEXPECTED = false

--[[ json structure:
	{
		links = a, b, c, d,
		names = ,
		a = { links = , names = }, b = { links = , names = }
		names table is added only after construction of links table
		construction is recursive
	}
]]
local h = {}
local p = {}

function p.main(frame)
	local args = util_args.merge()
	h.castArgs(args)
	h.setConstants(args)
	local pages = h.getPageList()
	local json = h.jsonFromPages(pages)
	local data = {
		linkadjustments = h.linkAdjustments(json),
		navboxdata = not args.nonavbox and Navbox(args.preload),
		after = h.getAfterContent(args.preload),
		basepage = CURRENT_ROOT_TITLE,
		tabstype = args.tabstype or 'header'
	}
	return tabs(json, data)
end

function h.castArgs(args)
	args.nonavbox = util_args.castAsBool(args.nonavbox)
	args.preload = args[1] or 'Player'
end

function h.setConstants(args)
	PRELOAD = SETTINGS[args.preload]
	CURRENT_ROOT_TITLE = mw.title.getCurrentTitle().rootPageTitle.text
	DELETE_UNEXPECTED = util_args.castAsBool(args.delete_unexpected_pages)
end

function h.getPageList()
	local pgtbl = util_page.getSubpageList(nil, 'SubpageTabs')
	util_map.inPlace(pgtbl, h.processOnePageTitle)
	return pgtbl
end

function h.processOnePageTitle(title)
	local tbl = util_title.titleTable(title)
	table.remove(tbl, 1)
	return tbl
end

function h.jsonFromPages(pages)
	if #pages <= 1 then -- no subpages
		return nil
	end
	local json = { links = { 'Overview' } }
	h.jsonLoop(json, pages)
	h.processJson(json, PRELOAD.lookup, PRELOAD.order, '')
	return json
end

function h.jsonLoop(json, pages)
	-- go through all of the pages from our subpage list, and for each page add its data to the json
	while #pages > 0 do
		local page = table.remove(pages,1)
		h.pageRecursion(json, page)
		h.addMissingPages(json)
	end
	return
end

function h.pageRecursion(json, page)
	-- the page should always exist, but when we reach the end of our recursion for this one page, #page will be 0
	if not page or #page == 0 then
		return
	end
	-- pull out the first titlepart of the page, and the rest of the page will be dealt with later when we call this again
	titlepart = table.remove(page, 1)
	if #page > 0 then
		-- if we dont have an entry at this level yet
		if not json[titlepart] then
			-- assume the 1st thing is going to be called Overview
			json[titlepart] = { links = { 'Overview' } }
		end
		-- recursion
		-- json[titlepart] is one step later, and page has been truncated
		h.pageRecursion(json[titlepart],page)
	elseif #page == 0 then
		-- if we are on the very last part of the page then just append the current page to the list
		json.links[#json.links+1] = titlepart
	end
	return
end

function h.addMissingPages(json)
	-- if there's no overview for statistics for example, we still want to print the stats
	for k, v in pairs(json) do
		-- actually pretty sure everything in the json is a table but we'll just double check to avoid errors
		-- want to skip this for links obviously
		if type(v) == 'table' and k ~= 'links' then
			if not util_table.keyOf(json.links, k) then
				-- k is the set of sub-subpages, so if there's no subpage of this then we want to add it
				json.links[#json.links+1] = k
				-- also in this case that means there's no overview. because we made an overview by default
				-- we now need to remove it from the list of sub-subpages
				if v.links[1] then
					table.remove(v.links,1)
				end
			end
			h.addMissingPages(v)
		end
	end
end

function h.processJson(json, lookup, order, index)
	h.processJsonLinks(json, order)
	-- add the name list
	json.names = {}
	for k, link in ipairs(json.links) do
		json.names[k] = lookup[index .. link] or link
	end
	-- recursion
	for k, v in pairs(json) do
		if v.links then
			h.processJson(v, lookup, order[k] or {}, k)
		end
	end
	return
end

function h.processJsonLinks(json, order)
	-- we already added the missing links in h.addMissingPages, so no need to do that again here
	
	-- sort links
	util_table.sortByKeyOrder(json.links, order)
	
	-- remove overview if we don't have an overview, since json creation automatically adds one
	-- but actually we may have already removed the overview in the event that the page doesn't exist period
	-- but if the page exists & we don't want it to be here, then we will remove it now
	-- this code means that you may want to specify both Overview as being the first element of your
	-- page order array in SubpageTabs and also have nooverview=true in the same line
	if order.nooverview and json.links[1] == 'Overview' then
		table.remove(json.links,1)
	end
	return
end

function h.linkAdjustments(json)
	if not json then return nil end
	if not json.links then return nil end
	local tbl = { fr = { find = {}, replace = {} }, cd = {} }
	h.linkAdjustmentsRecursion(json, CURRENT_ROOT_TITLE, PRELOAD.order, tbl)
	return tbl
end

function h.linkAdjustmentsRecursion(json, title, order, tbl)
	for i = #json.links, 1, -1 do
		v = json.links[i]
		if not h.isThisPageExpected(order, v) then
			-- in this case we have some redirect or something that we don't
			-- actually want to add, e.g. random redirect
			table.remove(json.links, i)
			table.remove(json.names, i)
		elseif json[v] and json[v].links and order[v] then
			local lr = order[v .. '_linkrecent']
			if lr then
				new_title = util_title.concatSubpage(CURRENT_ROOT_TITLE, v)
				-- optionally can define _linkrecent=true to just show the last one
				-- or can specify a specific tab to show as a string
				-- e.g. Gallery_linkrecent = "Splash Screens"
				-- we'll pick what to focus depending
				local focused = type(lr) == 'string' and lr or json[v].links[#json[v].links]
				tbl.cd[new_title] = util_title.concatSubpage(new_title, focused)
			end
			h.linkAdjustmentsRecursion(json[v], new_title, order[v], tbl)
		end
	end
	return
end

function h.isThisPageExpected(order, v)
	if not DELETE_UNEXPECTED then return true end
	return util_table.keyOf(order, v)
end

function h.getAfterContent(profile)
	if mw.title.getCurrentTitle().namespace ~= 0 then return end
	return After(profile)
end

return p