hexo-theme-stellar/scripts/events/lib/doc_tree.js

214 lines
5.6 KiB
JavaScript
Raw Permalink Normal View History

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)) {
2024-01-20 14:48:04 +08:00
if (key.endsWith('.DS_Store')) {
continue
}
2023-12-06 13:20:04 +08:00
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]
}
2024-02-12 23:12:29 +08:00
if ((typeof obj.tree == 'object') && obj.tree.constructor == Array) {
obj.tree = { '': obj.tree }
2023-12-06 13:20:04 +08:00
}
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))
2024-10-29 09:11:18 +08:00
const wiki_list = Object.keys(wiki.tree).filter(id => wiki_pages.some(p => p.wiki === id))
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)
// 首页
// 未特别指定首页时获取TOC第一页作为首页
2024-01-20 01:57:55 +08:00
var homepage = item.homepage
2024-02-12 23:12:29 +08:00
if (homepage == null && item.tree != null) {
for (let id of Object.keys(item.tree)) {
const sec = item.tree[id]
2023-12-06 13:22:07 +08:00
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) {
2024-01-20 01:57:55 +08:00
homepage = hs[0]
2023-12-06 13:22:07 +08:00
break
}
}
2024-01-20 01:57:55 +08:00
if (homepage != null) {
2023-12-06 13:20:04 +08:00
break
2021-07-25 22:47:18 +08:00
}
}
}
2024-01-20 01:57:55 +08:00
if (homepage == null) {
homepage = sub_pages[0]
2023-12-06 13:20:04 +08:00
}
2024-01-20 01:57:55 +08:00
if (typeof homepage == 'string') {
homepage = {path: homepage}
}
homepage.is_homepage = true
item.homepage = homepage
2023-12-06 13:20:04 +08:00
// 内页分组
2022-11-19 19:54:37 +08:00
var sections = []
2023-12-06 13:20:04 +08:00
var others = sub_pages
2024-02-12 23:12:29 +08:00
if (item.tree) {
2023-12-06 13:22:07 +08:00
// 根据配置设置顺序
2024-02-12 23:12:29 +08:00
for (let title of Object.keys(item.tree)) {
2023-12-06 13:22:07 +08:00
var sec = { title: title, pages: []}
2024-02-12 23:12:29 +08:00
for (let key of item.tree[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
}