2021-07-04 20:21:31 +08:00
|
|
|
|
/**
|
2022-11-19 19:54:37 +08:00
|
|
|
|
* doc_tree.js v2 | https://github.com/xaoxuu/hexo-theme-stellar/
|
2021-07-04 20:21:31 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
2022-11-19 16:08:50 +08:00
|
|
|
|
class WikiPage {
|
|
|
|
|
constructor(page) {
|
|
|
|
|
this.id = page._id
|
2023-12-06 13:20:04 +08:00
|
|
|
|
this.wiki = page.wiki
|
2022-11-19 16:08:50 +08:00
|
|
|
|
this.title = page.title
|
|
|
|
|
this.path = page.path
|
2023-12-06 13:20:04 +08:00
|
|
|
|
this.path_key = page.path.replace('.html', '')
|
2022-11-19 16:08:50 +08:00
|
|
|
|
this.layout = page.layout
|
2022-11-19 23:14:41 +08:00
|
|
|
|
this.updated = page.updated
|
2022-11-19 16:08:50 +08:00
|
|
|
|
}
|
2021-07-26 22:26:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-12-06 13:20:04 +08:00
|
|
|
|
function getWikiObject(ctx) {
|
|
|
|
|
var wiki = { tree:{} }
|
|
|
|
|
const data = ctx.locals.get('data')
|
|
|
|
|
var list = []
|
|
|
|
|
for (let key of Object.keys(data)) {
|
|
|
|
|
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.toc == 'object') && obj.toc.constructor == Array) {
|
|
|
|
|
obj.toc = { '': obj.toc }
|
|
|
|
|
}
|
|
|
|
|
obj.id = newKey
|
|
|
|
|
if (obj.sort == null) {
|
|
|
|
|
obj.sort = 0
|
|
|
|
|
}
|
2024-01-20 01:51:09 +08:00
|
|
|
|
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 = ''
|
2023-12-06 13:22:07 +08:00
|
|
|
|
}
|
2023-12-06 13:20:04 +08:00
|
|
|
|
list.push(obj)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-06 13:22:07 +08:00
|
|
|
|
list = list.sort((p1, p2) => p2.sort - p1.sort)
|
2023-12-06 13:20:04 +08:00
|
|
|
|
for (let item of list) {
|
|
|
|
|
wiki.tree[item.id] = item
|
2021-07-04 20:21:31 +08:00
|
|
|
|
}
|
2022-11-19 16:08:50 +08:00
|
|
|
|
return wiki
|
|
|
|
|
}
|
2021-07-09 21:17:55 +08:00
|
|
|
|
|
2022-11-19 16:08:50 +08:00
|
|
|
|
module.exports = ctx => {
|
2021-07-04 20:21:31 +08:00
|
|
|
|
// wiki 配置
|
2023-12-06 13:20:04 +08:00
|
|
|
|
var wiki = getWikiObject(ctx)
|
2022-11-19 16:08:50 +08:00
|
|
|
|
const pages = ctx.locals.get('pages')
|
2021-07-04 20:21:31 +08:00
|
|
|
|
// wiki 所有页面
|
2024-01-19 01:05:44 +08:00
|
|
|
|
const wiki_pages = pages.filter(p => (p.wiki != null)).map(p => new WikiPage(p))
|
2023-12-06 13:20:04 +08:00
|
|
|
|
const wiki_list = Object.keys(wiki.tree)
|
2023-12-17 19:39:23 +08:00
|
|
|
|
// 上架的项目列表
|
2024-01-04 10:22:05 +08:00
|
|
|
|
wiki.shelf = ctx.locals.get('data').wiki || []
|
2023-12-17 19:39:23 +08:00
|
|
|
|
|
2021-07-26 22:26:46 +08:00
|
|
|
|
// 数据整合:项目标签
|
2022-11-19 19:54:37 +08:00
|
|
|
|
var all_tag_name = []
|
2023-12-06 13:20:04 +08:00
|
|
|
|
for (let id of wiki_list) {
|
|
|
|
|
let item = wiki.tree[id]
|
|
|
|
|
let tags = item.tags
|
2021-07-26 22:26:46 +08:00
|
|
|
|
if (tags) {
|
2023-12-06 13:20:04 +08:00
|
|
|
|
tags.forEach((tag, i) => {
|
|
|
|
|
if (all_tag_name.includes(tag) === false) {
|
|
|
|
|
all_tag_name.push(tag)
|
2021-07-26 22:26:46 +08:00
|
|
|
|
}
|
2023-12-06 13:20:04 +08:00
|
|
|
|
})
|
|
|
|
|
wiki.tree[id].tags = tags
|
2021-07-04 20:21:31 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-06 13:20:04 +08:00
|
|
|
|
|
2021-07-26 22:26:46 +08:00
|
|
|
|
// 补充项目名称和首页
|
2023-12-06 13:20:04 +08:00
|
|
|
|
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
|
2021-07-04 20:21:31 +08:00
|
|
|
|
}
|
2023-12-06 13:20:04 +08:00
|
|
|
|
if (item.name == undefined || item.name.length == 0) {
|
|
|
|
|
item.name = id
|
2022-10-27 22:02:47 +08:00
|
|
|
|
}
|
2021-07-04 20:21:31 +08:00
|
|
|
|
}
|
2023-12-06 13:20:04 +08:00
|
|
|
|
|
2021-07-04 20:21:31 +08:00
|
|
|
|
// 数据整合:每个项目的子页面
|
2023-12-06 13:22:07 +08:00
|
|
|
|
for (let i = 0; i < wiki_list.length; i++) {
|
|
|
|
|
let id = wiki_list[i];
|
2023-12-06 13:20:04 +08:00
|
|
|
|
let item = wiki.tree[id]
|
|
|
|
|
let sub_pages = wiki_pages.filter(p => p.wiki === id)
|
|
|
|
|
if (!sub_pages || sub_pages.length == 0) {
|
2023-12-06 13:22:07 +08:00
|
|
|
|
wiki_list.splice(i, 1)
|
|
|
|
|
delete wiki.tree[id]
|
2022-11-19 16:08:50 +08:00
|
|
|
|
continue
|
|
|
|
|
}
|
2023-12-06 13:20:04 +08:00
|
|
|
|
|
|
|
|
|
// 首页
|
|
|
|
|
// 未特别指定首页时,获取TOC第一页作为首页
|
|
|
|
|
if (item.homepage == null && item.toc != null) {
|
|
|
|
|
for (let id of Object.keys(item.toc)) {
|
2023-12-06 13:22:07 +08:00
|
|
|
|
const sec = item.toc[id]
|
|
|
|
|
for (let key of sec) {
|
2024-01-20 01:51:09 +08:00
|
|
|
|
let hs = sub_pages.filter(p => p.path_key == item.base_dir + key)
|
2023-12-06 13:22:07 +08:00
|
|
|
|
if (hs.length > 0) {
|
|
|
|
|
item.homepage = hs[0]
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (item.homepage != null) {
|
2023-12-06 13:20:04 +08:00
|
|
|
|
break
|
2021-07-25 22:47:18 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-06 13:20:04 +08:00
|
|
|
|
if (item.homepage == null) {
|
|
|
|
|
item.homepage = sub_pages[0]
|
|
|
|
|
}
|
|
|
|
|
item.homepage.is_homepage = true
|
|
|
|
|
// 内页分组
|
2022-11-19 19:54:37 +08:00
|
|
|
|
var sections = []
|
2023-12-06 13:20:04 +08:00
|
|
|
|
var others = sub_pages
|
|
|
|
|
if (item.toc) {
|
2023-12-06 13:22:07 +08:00
|
|
|
|
// 根据配置设置顺序
|
2023-12-06 13:20:04 +08:00
|
|
|
|
for (let title of Object.keys(item.toc)) {
|
2023-12-06 13:22:07 +08:00
|
|
|
|
var sec = { title: title, pages: []}
|
|
|
|
|
for (let key of item.toc[title]) {
|
2024-01-20 01:51:09 +08:00
|
|
|
|
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)
|
2023-12-06 13:20:04 +08:00
|
|
|
|
}
|
2023-12-06 13:22:07 +08:00
|
|
|
|
sections.push(sec)
|
|
|
|
|
}
|
|
|
|
|
if (others.length > 0 && others.filter(p => p.title?.length > 0).length > 0) {
|
2021-07-26 22:26:46 +08:00
|
|
|
|
sections.push({
|
2023-12-06 13:22:07 +08:00
|
|
|
|
title: '...',
|
2024-01-20 01:51:09 +08:00
|
|
|
|
pages: others.sort((p1, p2) => p1.title - p2.title)
|
2022-11-19 19:54:37 +08:00
|
|
|
|
})
|
2021-07-25 22:47:18 +08:00
|
|
|
|
}
|
2023-12-06 13:22:07 +08:00
|
|
|
|
} else {
|
|
|
|
|
// 自动设置顺序
|
2023-12-06 13:20:04 +08:00
|
|
|
|
sections.push({
|
2024-01-20 01:51:09 +08:00
|
|
|
|
pages: sub_pages.sort((p1, p2) => p1.title - p2.title)
|
2023-12-06 13:20:04 +08:00
|
|
|
|
})
|
|
|
|
|
}
|
2023-12-06 13:22:07 +08:00
|
|
|
|
|
|
|
|
|
// page number
|
|
|
|
|
var page_number = 0
|
|
|
|
|
for (let sec of sections) {
|
|
|
|
|
for (let page of sec.pages) {
|
|
|
|
|
page.page_number = page_number++
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-06 13:20:04 +08:00
|
|
|
|
item.sections = sections
|
|
|
|
|
item.pages = sub_pages
|
2021-07-04 20:21:31 +08:00
|
|
|
|
}
|
2023-12-06 13:22:07 +08:00
|
|
|
|
|
2021-07-26 22:26:46 +08:00
|
|
|
|
// 全站所有的项目标签
|
2022-11-19 19:54:37 +08:00
|
|
|
|
var all_tags = {}
|
2022-11-19 16:08:50 +08:00
|
|
|
|
all_tag_name.forEach((tag_name, i) => {
|
2023-12-17 19:39:23 +08:00
|
|
|
|
var items = []
|
2023-12-06 13:20:04 +08:00
|
|
|
|
for (let id of wiki_list) {
|
|
|
|
|
let item = wiki.tree[id]
|
2023-12-17 19:39:23 +08:00
|
|
|
|
// 过滤掉找不到页面的项目
|
|
|
|
|
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)
|
2021-07-04 20:21:31 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-19 16:08:50 +08:00
|
|
|
|
all_tags[tag_name] = {
|
|
|
|
|
name: tag_name,
|
2024-01-20 01:51:09 +08:00
|
|
|
|
path: (ctx.theme.config.site_tree.index_wiki.base_dir) + '/tags/' + tag_name + '/index.html',
|
2023-12-17 19:39:23 +08:00
|
|
|
|
items: items
|
2022-11-19 19:54:37 +08:00
|
|
|
|
}
|
|
|
|
|
})
|
2021-07-26 22:26:46 +08:00
|
|
|
|
|
2022-11-19 16:08:50 +08:00
|
|
|
|
// 关联相似项目
|
2023-12-06 13:20:04 +08:00
|
|
|
|
for (let id of wiki_list) {
|
|
|
|
|
let item = wiki.tree[id]
|
|
|
|
|
if (item.tags) {
|
2023-12-17 19:39:23 +08:00
|
|
|
|
var relatedItems = []
|
2023-12-06 13:20:04 +08:00
|
|
|
|
item.tags.forEach((tag_name, i) => {
|
2023-12-17 19:39:23 +08:00
|
|
|
|
let relatedOtherItems = all_tags[tag_name].items.filter(name => name != item.id)
|
|
|
|
|
if (relatedOtherItems.length > 0) {
|
|
|
|
|
relatedItems.push({
|
|
|
|
|
name: tag_name,
|
|
|
|
|
items: relatedOtherItems
|
|
|
|
|
})
|
|
|
|
|
}
|
2022-11-19 19:54:37 +08:00
|
|
|
|
})
|
2023-12-17 19:39:23 +08:00
|
|
|
|
item.relatedItems = relatedItems
|
2021-07-26 22:26:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 19:54:37 +08:00
|
|
|
|
wiki.all_tags = all_tags
|
|
|
|
|
wiki.all_pages = wiki_pages
|
|
|
|
|
ctx.theme.config.wiki = wiki
|
2022-11-19 16:08:50 +08:00
|
|
|
|
|
2022-11-19 19:54:37 +08:00
|
|
|
|
}
|