Có thể viết tài liệu về mô đun này tại Mô đun:SuperNavTest/tài liệu.
local p = {}
--- 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 keyFound = ''
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(keyFound) then
keyFound = key
end
end
end
return keyFound
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 mw.uri.encode(v.fullname) == mw.uri.encode(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)
localNav
:cssText(customizedSkin.localNav)
:addClass("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
-- for title
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
-- for content
content
:addClass("mw-collapsible")
:attr("id", "mw-customcollapsible-"..arc.id)
-- close content bar if demanded
if not customizedSkin["arcBar_open_"..arc.id] then
content:addClass("mw-collapsed")
end
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
--- Follow /Unfollow buttons
-- @param #frame current global frame
function makeFollowerBar(frame)
local followerDiv, followDiv, unfollowDiv, bookmarkDiv = mw.html.create("tr"), mw.html.create("th"), mw.html.create("th"), mw.html.create("th")
followDiv
:addClass("follow")
:cssText("text-align: center; font-size: medium; font-weight: bold; display: table-cell; width: 33%;")
:node(frame:expandTemplate{title="FollowButton", args={text=true}})
unfollowDiv
:addClass("unfollow")
:cssText("text-align: center; font-size: medium; font-weight: bold; display: table-cell; width: 33%; border-right: 2px steelblue solid !important;")
:node(frame:expandTemplate{title="UnfollowButton", args={text=true}})
bookmarkDiv
:cssText("text-align: center; font-size: medium; font-weight: bold; display: table-cell; width: 33%; border-right: 2px steelblue solid !important;")
:node(frame:expandTemplate{title="ToBookmarkPage", args={text=true}})
followerDiv
:addClass("followerBar")
:cssText("width: 100%; display: table; color: #0a3073;")
:node(unfollowDiv)
:node(bookmarkDiv)
:node(followDiv)
return mw.html.create("table")
:cssText("margin: 0em auto 0px auto; width: 100%; background: #f9f9f9; border: 2px steelblue solid !important; padding: 0.2em; border-collapse: collapse; font-weight: bold;")
:node(followerDiv)
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"] or args["pagename"]
local pageName = mw.title.getCurrentTitle()
-- 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
-- The header and navbox we will create and return
local navboxHeader, navbox = mw.html.create("h2"), mw.html.create("div")
-- Prevent from being printed by ebook maker
navboxHeader
:addClass("print-no")
:addClass("entry-unrelated")
:addClass("dotEPUBremove")
navbox
:addClass("print-no")
:addClass("entry-unrelated")
:addClass("dotEPUBremove")
local customizedSkin = customSkin(args)
local inner_navbox = mw.html.create("div")
-- Append the follower bar into our inner_navbox
:node(makeFollowerBar(frame))
-- Append the local nav into our inner_navbox
:node(makeLocalNav(pageName,pagesList,customizedSkin))
-- Append the global nav into our inner_navbox
:node(makeGlobalNav(pagesList,customizedSkin))
-- Append the inner into navbox
navbox:node(inner_navbox)
-- Create the header
navboxHeader
:wikitext("Theo dõi & Thanh chuyển trang")
return mw.html.create(""):node(navboxHeader):node(navbox)
else
return search(args.search, pagesList)
end
end
return p