219 lines
5.7 KiB
JavaScript
219 lines
5.7 KiB
JavaScript
/**
|
||
* doc_tree.js v2 | https://github.com/xaoxuu/hexo-theme-stellar/
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
class WikiPage {
|
||
constructor(page) {
|
||
this.id = page._id
|
||
this.wiki = page.wiki
|
||
this.title = page.title
|
||
this.path = page.path
|
||
this.path_key = page.path.replace('.html', '')
|
||
this.layout = page.layout
|
||
this.updated = page.updated
|
||
}
|
||
}
|
||
|
||
function getWikiObject(ctx) {
|
||
var wiki = { tree:{} }
|
||
const data = ctx.locals.get('data')
|
||
var list = []
|
||
for (let key of Object.keys(data)) {
|
||
if (key.endsWith('.DS_Store')) {
|
||
continue
|
||
}
|
||
if (key.includes('wiki/') && key.length > 5) {
|
||
let newKey = key.replace('wiki/', '')
|
||
let obj = data[key]
|
||
if ((typeof obj.tags == 'string') && obj.tags.constructor == String) {
|
||
obj.tags = [obj.tags]
|
||
}
|
||
if ((typeof obj.tree == 'object') && obj.tree.constructor == Array) {
|
||
obj.tree = { '': obj.tree }
|
||
}
|
||
obj.id = newKey
|
||
if (obj.sort == null) {
|
||
obj.sort = 0
|
||
}
|
||
if (obj.base_dir) {
|
||
if (obj.base_dir.startsWith('/')) {
|
||
obj.base_dir = obj.base_dir.substring(1)
|
||
}
|
||
if (obj.base_dir.length > 1 && obj.base_dir.endsWith('/') == false) {
|
||
obj.base_dir = obj.base_dir + '/'
|
||
}
|
||
} else {
|
||
obj.base_dir = ''
|
||
}
|
||
list.push(obj)
|
||
}
|
||
}
|
||
list = list.sort((p1, p2) => p2.sort - p1.sort)
|
||
for (let item of list) {
|
||
wiki.tree[item.id] = item
|
||
}
|
||
return wiki
|
||
}
|
||
|
||
module.exports = ctx => {
|
||
// wiki 配置
|
||
var wiki = getWikiObject(ctx)
|
||
const pages = ctx.locals.get('pages')
|
||
// wiki 所有页面
|
||
const wiki_pages = pages.filter(p => (p.wiki != null)).map(p => new WikiPage(p))
|
||
const wiki_list = Object.keys(wiki.tree)
|
||
// 上架的项目列表
|
||
wiki.shelf = ctx.locals.get('data').wiki || []
|
||
|
||
// 数据整合:项目标签
|
||
var all_tag_name = []
|
||
for (let id of wiki_list) {
|
||
let item = wiki.tree[id]
|
||
let tags = item.tags
|
||
if (tags) {
|
||
tags.forEach((tag, i) => {
|
||
if (all_tag_name.includes(tag) === false) {
|
||
all_tag_name.push(tag)
|
||
}
|
||
})
|
||
wiki.tree[id].tags = tags
|
||
}
|
||
}
|
||
|
||
// 补充项目名称和首页
|
||
for (let id of wiki_list) {
|
||
let item = wiki.tree[id]
|
||
item.id = id
|
||
if (item.title == undefined || item.title.length === 0) {
|
||
item.title = id
|
||
}
|
||
if (item.name == undefined || item.name.length == 0) {
|
||
item.name = id
|
||
}
|
||
}
|
||
|
||
// 数据整合:每个项目的子页面
|
||
for (let i = 0; i < wiki_list.length; i++) {
|
||
let id = wiki_list[i];
|
||
let item = wiki.tree[id]
|
||
let sub_pages = wiki_pages.filter(p => p.wiki === id)
|
||
if (!sub_pages || sub_pages.length == 0) {
|
||
wiki_list.splice(i, 1)
|
||
delete wiki.tree[id]
|
||
continue
|
||
}
|
||
|
||
// 首页
|
||
// 未特别指定首页时,获取TOC第一页作为首页
|
||
var homepage = item.homepage
|
||
if (homepage == null && item.tree != null) {
|
||
for (let id of Object.keys(item.tree)) {
|
||
const sec = item.tree[id]
|
||
for (let key of sec) {
|
||
let hs = sub_pages.filter(p => p.path_key == item.base_dir + key)
|
||
if (hs.length > 0) {
|
||
homepage = hs[0]
|
||
break
|
||
}
|
||
}
|
||
if (homepage != null) {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
if (homepage == null) {
|
||
homepage = sub_pages[0]
|
||
}
|
||
if (typeof homepage == 'string') {
|
||
homepage = {path: homepage}
|
||
}
|
||
homepage.is_homepage = true
|
||
item.homepage = homepage
|
||
// 内页分组
|
||
var sections = []
|
||
var others = sub_pages
|
||
if (item.tree) {
|
||
// 根据配置设置顺序
|
||
for (let title of Object.keys(item.tree)) {
|
||
var sec = { title: title, pages: []}
|
||
for (let key of item.tree[title]) {
|
||
sec.pages = sec.pages.concat(sub_pages.filter(p => p.path_key == item.base_dir + key))
|
||
others = others.filter(p => p.path_key != item.base_dir + key)
|
||
}
|
||
sections.push(sec)
|
||
}
|
||
if (others.length > 0 && others.filter(p => p.title?.length > 0).length > 0) {
|
||
sections.push({
|
||
title: '...',
|
||
pages: others.sort((p1, p2) => p1.title - p2.title)
|
||
})
|
||
}
|
||
} else {
|
||
// 自动设置顺序
|
||
sections.push({
|
||
pages: sub_pages.sort((p1, p2) => p1.title - p2.title)
|
||
})
|
||
}
|
||
|
||
// page number
|
||
var page_number = 0
|
||
for (let sec of sections) {
|
||
for (let page of sec.pages) {
|
||
page.page_number = page_number++
|
||
}
|
||
}
|
||
item.sections = sections
|
||
item.pages = sub_pages
|
||
}
|
||
|
||
// 全站所有的项目标签
|
||
var all_tags = {}
|
||
all_tag_name.forEach((tag_name, i) => {
|
||
var items = []
|
||
for (let id of wiki_list) {
|
||
let item = wiki.tree[id]
|
||
// 过滤掉找不到页面的项目
|
||
if (item.homepage == null) {
|
||
continue
|
||
}
|
||
// 过滤掉未上架的项目
|
||
if (!wiki.shelf.includes(item.id)) {
|
||
continue
|
||
}
|
||
if (item.tags && item.tags.includes(tag_name) === true && items.includes(tag_name) === false) {
|
||
items.push(item.id)
|
||
}
|
||
}
|
||
all_tags[tag_name] = {
|
||
name: tag_name,
|
||
path: (ctx.theme.config.site_tree.index_wiki.base_dir) + '/tags/' + tag_name + '/index.html',
|
||
items: items
|
||
}
|
||
})
|
||
|
||
// 关联相似项目
|
||
for (let id of wiki_list) {
|
||
let item = wiki.tree[id]
|
||
if (item.tags) {
|
||
var relatedItems = []
|
||
item.tags.forEach((tag_name, i) => {
|
||
let relatedOtherItems = all_tags[tag_name].items.filter(name => name != item.id)
|
||
if (relatedOtherItems.length > 0) {
|
||
relatedItems.push({
|
||
name: tag_name,
|
||
items: relatedOtherItems
|
||
})
|
||
}
|
||
})
|
||
item.relatedItems = relatedItems
|
||
}
|
||
}
|
||
|
||
wiki.all_tags = all_tags
|
||
wiki.all_pages = wiki_pages
|
||
ctx.theme.config.wiki = wiki
|
||
|
||
}
|