Documentation for this module may be created at Module:SuperNav/doc
local p = {}
-- The navbox we will create and return
local navbox = mw.html.create("div")
-- Prevent from being printed by ebook maker
navbox
:addClass("print-no")
:addClass("entry-unrelated")
--- Searching for the prefix corresponding the project
-- @param #string pageName the name to search
-- @param #table prefixData all prefixes stocked
function searchPrefix(pageName, prefixData)
-- Finding and returning the longest matching key
local keyFounded = ''
for key, var in pairs(prefixData) do
if mw.ustring.find(mw.ustring.lower(pageName),mw.ustring.lower(key),1,true) ~= nil then
if mw.ustring.len(key) > mw.ustring.len(keyFounded) then
keyFounded = key
end
end
end
return keyFounded
end
--- Personalizing the Navbox according to parameters
-- @param #table args all parameters transmitted
function customSkin(args)
-- Loading the default skin for Navbox
local defaultSkin = mw.loadData("Module:Default Nav Skin") or {}
local skin = {}
for key, var in pairs(defaultSkin) do
skin[key] = (mw.text.trim(tostring(var)))
end
for key, var in pairs(args) do
skin[key] = (mw.text.trim(tostring(var)))
end
return skin
end
--- Make wikia interne link from page name
-- @param #table data containing full name, short name, etc. associating this page from pagesList
-- @param #boolean shortened shorten the name of page or not
-- @param #string style styling this link
function wikiaLink(data, shortened, style)
local appear_text = mw.html.create("span")
appear_text:cssText(style)
if shortened then
appear_text:wikitext(data.shortname or data.fullname)
else
appear_text:wikitext(data.longname or data.fullname)
end
return "[[" .. data.fullname .. "|" .. tostring(appear_text) .."]]"
end
--- Create the local navigator (forwarding/backwarding)
-- @param #string pageName name of this page
-- @param #table pagesList all the pages of this project
-- @param #table customizedSkin personalizing parameters
function makeLocalNav(pageName,pagesList,customizedSkin)
--Looking for mainpage
local mainPageData, mainPagePos = {}, 0
for k, v in ipairs(pagesList) do
if v.mainpage then
mainPageData = v
mainPagePos = k
break
end
end
--Determining the position of this page, couting the number of pages as well (n)
local actualPos, n = 0, 0
for k, v in ipairs(pagesList) do
n = n + 1
if v.fullname == pageName then
actualPos = k
end
end
if actualPos == 0 then
actualPos = mainPagePos
end
--Determining the preceding page
local previousPageData = {}
if actualPos > 1 then
if not pagesList[actualPos - 1].mainpage then
previousPageData = pagesList[actualPos - 1]
end
end
--Determining the successing page
local nextPageData = {}
if actualPos < n then
if not pagesList[actualPos + 1].mainpage then
nextPageData = pagesList[actualPos + 1]
end
end
--Constructing html
local localNav, localNav_row, previousPage, mainPage, nextPage
= mw.html.create("table"), mw.html.create("tr"), mw.html.create("td"), mw.html.create("td"), mw.html.create("td")
previousPage
:cssText(customizedSkin.previousPage)
if previousPageData.longname ~= nil then
previousPage:wikitext("► Xem lại " .. wikiaLink(previousPageData,false,customizedSkin.previousPage_link) .. " ◄")
else
previousPage:wikitext(" ")
end
mainPage
:cssText(customizedSkin.mainPage)
if mainPageData.fullname ~= nil then
mainPage:wikitext(customizedSkin.mainPage_left .. wikiaLink(mainPageData,true,customizedSkin.mainPage_link) .. customizedSkin.mainPage_right)
else
mainPage:wikitext(" ")
end
nextPage
:cssText(customizedSkin.nextPage)
if nextPageData.longname ~= nil then
nextPage:wikitext("► Xem tiếp " .. wikiaLink(nextPageData,false,customizedSkin.nextPage_link) .. " ◄")
else
nextPage:wikitext(" ")
end
localNav_row
:cssText(customizedSkin.localNav_row)
:node(previousPage)
:node(mainPage)
:node(nextPage)
:addClass("localNav")
localNav
:cssText(customizedSkin.localNav)
:node(localNav_row)
return localNav
end
--- Create the list of all pages in the project
-- @param #table pagesList all the pages of this project
-- @param #table customizedSkin personalizing parameters
function makeGlobalNav(pagesList,customizedSkin)
-- Ordering and grouping pages according to volume's numeration
local groupedPages, orderedKeys = {}, {}
for _, v in ipairs(pagesList) do
if v.id then
local thisVol = {ft = v, ch = {}}
for _, v2 in ipairs(pagesList) do
if v2.childOf == v.id then
table.insert(thisVol.ch, v2)
end
end
table.insert(orderedKeys, v.id)
groupedPages[v.id] = thisVol
end
end
-- Constructing html
local globalNav, globalNav_title, globalNav_content, unitNodes
= mw.html.create("div"), mw.html.create("div"), mw.html.create("div"), {}
-- title
globalNav_title
:cssText(customizedSkin.globalNav_title)
:addClass("mw-customtoggle-globalNav"):addClass("mw-customtoggle-globalNavClose"):addClass("mw-customtoggle-globalNavOpen")
:wikitext(customizedSkin.globalNav_title_text)
-- content
-- constructing unit nodes, which consist of volumes
for _, id in ipairs(orderedKeys) do
-- for each volume
local data, vol, links = groupedPages[id], mw.html.create("table"), mw.html.create("")
-- fulltext link
local ft = mw.html.create("td")
ft
:cssText(customizedSkin.fulltext)
:wikitext(wikiaLink(data.ft,true,customizedSkin.fulltext_link))
links:node(ft)
-- chapter link
for _, chapter in ipairs(data.ch) do
local ch = mw.html.create("td")
ch
:cssText(customizedSkin.chapter)
:wikitext(wikiaLink(chapter,true,customizedSkin.chapter_link))
links:node(ch)
end
-- volume case
vol
:cssText(customizedSkin.volume)
:node(mw.html.create("tr"):node(links))
-- attaching to unitNodes
-- unitNodes and groupedPages used the same table of ordered keys
unitNodes[id] = vol
end
-- constructing arcs
local arcsStructure = pagesList.arcsStructure
if arcsStructure then
for _, arc in ipairs(arcsStructure) do
if arc.including and arc.id then
local arc_node, title, content = mw.html.create(""), mw.html.create("div"), mw.html.create("div")
-- styling
title
:addClass("mw-customtoggle-"..arc.id):addClass("mw-customtoggle-"..arc.id.."Close"):addClass("mw-customtoggle-"..arc.id.."Open")
:wikitext(arc.fullname)
if not customizedSkin["arcBar_title_"..arc.id] then
title:cssText(customizedSkin.arcBar_title)
else
title:cssText(customizedSkin["arcBar_title_"..arc.id])
end
content
:addClass("mw-collapsible"):addClass("mw-collapsed")
:attr("id", "mw-customcollapsible-"..arc.id)
if not customizedSkin["arcBar_content_"..arc.id] then
content:cssText(customizedSkin.arcBar_content)
else
content:cssText(customizedSkin["arcBar_content_"..arc.id])
end
-- grouping all unit nodes into @arc_node
for _, includedId in ipairs(arc.including) do
content:node(unitNodes[includedId])
end
arc_node:node(title):node(content)
-- deleting included nodes and inserting arc_node into unitNodes
for index, includedId in ipairs(arc.including) do
unitNodes[includedId] = nil
end
unitNodes[arc.id] = arc_node
-- deleting corresponding keys and inserting arc.id into orderedKeys at the first deleted key
local index = 1
repeat
-- comparing orderedKeys[index] with all includedId in arc.including
for i, includedId in ipairs(arc.including) do
if includedId == orderedKeys[index] then
if i==1 then
orderedKeys[index] = arc.id
else
table.remove(orderedKeys, index)
index = index - 1
end
end
end
index = index + 1
until orderedKeys[index] == nil
end
end
end
-- appending volume cases, arc cases to globalNav_content
for _, key in ipairs(orderedKeys) do
globalNav_content:node(unitNodes[key])
end
globalNav_content
:cssText(customizedSkin.globalNav_content)
:attr("id", "mw-customcollapsible-globalNav")
:addClass("mw-collapsible")
if (customizedSkin.collapse_globalNav == "true") then
globalNav_content
:addClass("mw-collapsed")
:cssText("display:none")
end
-- overall
globalNav
:cssText(customizedSkin.globalNav)
:addClass("hidden")
:addClass("globalNav")
:node(globalNav_title)
:node(globalNav_content)
return globalNav
end
--- Searching function
--- Returns the first link, in shortened form, matching the given keyword. If research fails, it returns the mainpage
-- @param #keyword
-- @param #pagesList
function search(keyword, pagesList)
--Looking for mainpage
local mainPageData = {}
for _, v in ipairs(pagesList) do
if v.mainpage then
mainPageData = v
break
end
end
--Determining the corresponding link of keyword
local dataFound = nil
for _, v in ipairs(pagesList) do
if mw.ustring.find(mw.ustring.lower(v.fullname),mw.ustring.lower(keyword),1,true) ~= nil then
dataFound = v
break
end
end
if dataFound == nil then
return wikiaLink(mainPageData, true, nil)
else
return wikiaLink(dataFound, true, nil)
end
end
--- The main function
-- @param #table frame what wikia transmits
function p.makeNav( frame )
-- Getting all parameters transmis via template Auto Nav, including {{FULLPAGENAME}} and customized Navbox's styles
local args = frame.args or {}
-- Getting the title of page using template Auto Nav
local pageName = args["pageName"]
-- The prefixes
local prefixData, pagesList = mw.loadData("Module:PrefixData")
-- Getting the list of pages belonging to this project
if args.src then
pagesList = mw.loadData(args.src)
else
local prefixUsed = searchPrefix(pageName, prefixData)
pagesList = mw.loadData(prefixData[prefixUsed])
end
if args.search == "" or args.search == nil then
-- if user does not give value to arguement "search", then we create a navbox by default
local customizedSkin = customSkin(args)
local inner_navbox = mw.html.create("div")
inner_navbox
:addClass("dotEPUBremove")
-- Append the local nav into our inner_navbox
inner_navbox:node(makeLocalNav(pageName,pagesList,customizedSkin))
-- Append the global nav into our inner_navbox
inner_navbox:node(makeGlobalNav(pagesList,customizedSkin))
-- Append the inner into navbox
navbox:node(inner_navbox)
return navbox
else
return search(args.search, pagesList)
end
end
return p