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.buildJson(json, pages)
h.processJson(json, PRELOAD.lookup, PRELOAD.order, '')
return json
end
function h.buildJson(json, pages)
-- go through all of the pages from our subpage list, and for each page add its data to the json
for _, page in ipairs(pages) do
h.pageRecursion(json, page, 1)
h.addMissingPages(json)
end
end
function h.pageRecursion(json, page, i)
-- 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 = page[i]
if i < #page then
h.initTitlepartInJsonAtThisLevel(json, titlepart)
-- recursion
-- json[titlepart] is one step later, and `i` has been incremented
h.pageRecursion(json[titlepart], page, i+1)
elseif i == #page 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
end
function h.initTitlepartInJsonAtThisLevel(json, titlepart)
if not json[titlepart] then
json[titlepart] = { links = { 'Overview' } }
end
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