vitepress-allyouneed 0.3.4 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/dist/index.cjs +137 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +137 -28
- package/dist/index.js.map +1 -1
- package/dist/markdown-it.cjs +41 -8
- package/dist/markdown-it.cjs.map +1 -1
- package/dist/markdown-it.d.cts +1 -1
- package/dist/markdown-it.d.ts +1 -1
- package/dist/markdown-it.js +41 -8
- package/dist/markdown-it.js.map +1 -1
- package/dist/{types-BLbN9Pg6.d.cts → types-CjyxPvQV.d.cts} +12 -0
- package/dist/{types-BLbN9Pg6.d.ts → types-CjyxPvQV.d.ts} +12 -0
- package/dist/vite.cjs +13 -0
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +13 -0
- package/dist/vite.js.map +1 -1
- package/dist/vitepress.cjs +137 -28
- package/dist/vitepress.cjs.map +1 -1
- package/dist/vitepress.d.cts +1 -1
- package/dist/vitepress.d.ts +1 -1
- package/dist/vitepress.js +137 -28
- package/dist/vitepress.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/);版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.3.6] - 2026-05-20
|
|
6
|
+
|
|
7
|
+
针对用户反馈"Perspectives 有时不加载 / sidebar 有时错"的间歇性问题做了系统排查,5 个真 bug。
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **Perspectives 在 `locales.root.themeConfig` 配置下消失**:VitePress 1.6 渲染时浅 merge `themeConfig` 与 `siteData.locales[k]?.themeConfig` —— locale 整个**替换**顶层 nav/sidebar。wrapper 之前 `if (lang === 'root') continue` 跳过 root,导致用户用标准 i18n 写法 `locales: { root: { themeConfig: { nav: [...] }}}` 时,顶层 Perspectives 被 root 的(未注入)nav 覆盖。现在所有 locale(含 root)都过 inject。
|
|
11
|
+
- **dev 模式下新增 / 删除文件后 sidebar/nav 不更新**:wrapper 只在 config time 跑一次 scan + 生成 sidebar,后续 hot-update 只刷新 Vite 插件的 index(用于 wikilink / asset / vault-data.json)。结构变化静默吞掉。现在 `handleHotUpdate` 检测到 `.md` 文件 add / remove 时 `console.warn` 提示"重启 dev 服务器才能反映 sidebar/nav 变化"。
|
|
12
|
+
- **空 `themeConfig.sidebar = {}` 或部分 per-path 配置下 Perspectives 在根路径消失**:`injectViewsSidebar` 老逻辑 `for (Object.keys(sidebar))` 在空 object 上跑 0 次,Perspectives 没塞任何路径;用户在 `/` 或非匹配路径访问时看不到。现在显式给 `/` key 兜底一份。
|
|
13
|
+
- **`themeConfig.nav` 是 function 时被替换为 `[Perspectives]`**:VitePress nav 支持 function(动态 / locale-aware)。老 `Array.isArray(fn) ? [...fn] : []` 把 function 错判成"无 nav",推 Perspectives 后用单元素数组覆盖用户函数。现在 `typeof === 'function'` 时 wrap 一层,运行时调用用户 fn + 追加 Perspectives;用户 fn 抛错时容错只返 Perspectives 并 warn。
|
|
14
|
+
- **perspective fallback sidebar 含标题为 `/` 的死项**:`buildPerspectivesFallbackSidebar` 过滤 `p !== base`,但 base 是 `/sub/` 时永远不等于 `/` → `/` 进 topPaths → seg 为空 → 渲染为 `text: '/'` 的死项。现在显式排除 `'/'` + 双保险 `if (!seg) continue`。
|
|
15
|
+
|
|
16
|
+
### Tests
|
|
17
|
+
- 新增 `tests/v036-perspective-locale.test.ts`,覆盖以上 5 个 bug。
|
|
18
|
+
|
|
19
|
+
## [0.3.5] - 2026-05-20
|
|
20
|
+
|
|
21
|
+
零配置导航更顺手:不写 `index.md` 也能从导航 / sidebar / 用户手写 wikilink 进到一个文件夹;默认 index 模板换成"文件管理器风格"(子文件夹在上、文件在下)。
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **`sidebarAuto.folderLinkFallback: 'first-file' | 'none'`(默认 `'first-file'`)**
|
|
26
|
+
控制"文件夹链接缺 index 时怎么办"。三处效果一致:
|
|
27
|
+
- 自动生成的 sidebar group:无 dirIndex 时,group title 链到该文件夹第一个文件;
|
|
28
|
+
- 自动生成的 nav tab:无 dirIndex 时,tab 链到第一个文件(不再 silently skip);
|
|
29
|
+
- 用户手写的 `[[folder/]]` wikilink:同样兜底到第一个文件,label 用文件夹名(不用 first file 的 basename)。
|
|
30
|
+
设为 `'none'` 退回老行为(无 link / 死链)。最常见用法:`autoFolderIndex: 'off'` + `folderLinkFallback: 'first-file'`,完全不在 vault 写 `index.md` 也能从导航走通。
|
|
31
|
+
> **注意 sidebar vs nav 的差异**:
|
|
32
|
+
> - **Sidebar group**:**空 frontmatter-only dirIndex** 是用户显式 opt-out 信号(读 frontmatter 中的 `sidebarTitle` / `sidebarCollapsed`,但 group **无 link**,只展开/折叠)。这种文件**不会**触发 first-file 兜底 —— 兜底只在**完全没有** dirIndex 文件时生效。
|
|
33
|
+
> - **Nav tab**:nav tab 没"展开/折叠"状态,空 dirIndex 不兜底就成了点不动的死 tab。所以 nav 一视同仁:空或无 dirIndex **都**走 first-file 兜底(若 `folderLinkFallback === 'first-file'`);兜底也找不到才 skip。
|
|
34
|
+
> - **`[[folder/]]` wikilink**:用户写 `[[folder/]]` 时本就期望"跳转",和 nav 同语义 —— 空 dirIndex 兜底到第一个文件。
|
|
35
|
+
- **`resolveWikilink` 加同名 dirIndex 路径变体** —— `[[Themen/]]` 现在会查 `Themen/Themen.md` 当作索引(对应 `pickDirIndexes` 同名优先策略)。
|
|
36
|
+
- **`[[folder/]]` 写法支持完整化**:之前 `[[Themen/]]` 由于 `target + '/index.md'` 拼出 `Themen//index.md` 双斜杠 bug,实际是死链。现在 normalize 时剥尾 `/` 并强制走 path-style 分支,变体查找正确。
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **默认 `autoFolderIndex` 模板 = "Folders 在上、Files 在下"**(像文件管理器 / Tags 视图)。
|
|
41
|
+
- 段标题改成 `## Folders` + `## Files`(原 `## Sections` + `## Pages`)。
|
|
42
|
+
- 子文件夹位置:**上面**(老模板在下面)。
|
|
43
|
+
- 子文件夹标题是否可点接 `sidebarAuto.groupLink`(等同 sidebar 配置语义):
|
|
44
|
+
- `'all'`(默认):所有子文件夹标题都用 wikilink 可点
|
|
45
|
+
- `'top-level'`:仅根 `index.md` 内可点;深层 `index.md` 内为纯文字
|
|
46
|
+
- `'off'`:全部纯文字
|
|
47
|
+
- 子文件夹的"可点目的地"再走 `folderLinkFallback` 兜底,所以即使子文件夹无 index,点了也能进。
|
|
48
|
+
- **`FolderIndexOptions` / `TemplateContext` 扩展**:新增 `groupLink` 字段;`TemplateContext` 新增 `isRoot` / `groupLink`。
|
|
49
|
+
- **`resolveWikilink` 的 `defaultLabel`**:wasFolderForm 时(`[[folder/]]`),label 用文件夹名,而不是兜底文件的 basename。
|
|
50
|
+
|
|
51
|
+
### Migration
|
|
52
|
+
|
|
53
|
+
老用户若觉得新默认行为"不对路":
|
|
54
|
+
```ts
|
|
55
|
+
sidebarAuto: {
|
|
56
|
+
folderLinkFallback: 'none', // 回到 v0.3.4 行为
|
|
57
|
+
autoFolderIndex: {
|
|
58
|
+
template: oldTemplate, // 自己写模板覆盖
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
5
63
|
## [0.3.4] - 2026-05-20
|
|
6
64
|
|
|
7
65
|
真实 Obsidian 物理笔记 vault 测试暴露的 9 个 bug + 3 个隐性问题的集中修复。
|
package/dist/index.cjs
CHANGED
|
@@ -661,12 +661,20 @@ function resolveWikilink(rawTarget, index, options, kind = "page", currentSource
|
|
|
661
661
|
headingPart = target.slice(hashIdx + 1).trim();
|
|
662
662
|
target = target.slice(0, hashIdx).trim();
|
|
663
663
|
}
|
|
664
|
+
const wasFolderForm = /\/$/.test(target);
|
|
665
|
+
if (wasFolderForm) target = target.replace(/\/+$/, "");
|
|
664
666
|
target = stripMarkdownExt(target);
|
|
665
|
-
const entry = lookupEntry(
|
|
667
|
+
const entry = lookupEntry(
|
|
668
|
+
target,
|
|
669
|
+
index,
|
|
670
|
+
options,
|
|
671
|
+
currentSourcePath,
|
|
672
|
+
wasFolderForm
|
|
673
|
+
);
|
|
666
674
|
if (!entry) {
|
|
667
675
|
return {
|
|
668
676
|
url: buildDeadUrl(rawTarget, options),
|
|
669
|
-
defaultLabel: defaultLabel(target, headingPart, void 0, options),
|
|
677
|
+
defaultLabel: defaultLabel(target, headingPart, void 0, options, wasFolderForm),
|
|
670
678
|
isDead: true,
|
|
671
679
|
hasUnmatchedAnchor: false,
|
|
672
680
|
kind
|
|
@@ -687,22 +695,25 @@ function resolveWikilink(rawTarget, index, options, kind = "page", currentSource
|
|
|
687
695
|
}
|
|
688
696
|
return {
|
|
689
697
|
url,
|
|
690
|
-
defaultLabel: defaultLabel(target, headingPart, entry, options),
|
|
698
|
+
defaultLabel: defaultLabel(target, headingPart, entry, options, wasFolderForm),
|
|
691
699
|
isDead: false,
|
|
692
700
|
hasUnmatchedAnchor,
|
|
693
701
|
target: entry,
|
|
694
702
|
kind
|
|
695
703
|
};
|
|
696
704
|
}
|
|
697
|
-
function lookupEntry(target, index, options, currentSourcePath) {
|
|
705
|
+
function lookupEntry(target, index, options, currentSourcePath, forcePathStyle = false) {
|
|
698
706
|
if (!target) return void 0;
|
|
699
|
-
if (target.includes("/")) {
|
|
707
|
+
if (target.includes("/") || forcePathStyle) {
|
|
708
|
+
const lastSeg = target.split("/").pop() ?? "";
|
|
700
709
|
const variants = [
|
|
701
710
|
target,
|
|
702
711
|
target + ".md",
|
|
703
712
|
target + ".markdown",
|
|
704
713
|
target + "/index.md",
|
|
705
|
-
target + "/index.markdown"
|
|
714
|
+
target + "/index.markdown",
|
|
715
|
+
// 同名文件夹索引(和 pickDirIndexes 优先级 1 对齐)
|
|
716
|
+
...lastSeg ? [target + "/" + lastSeg + ".md", target + "/" + lastSeg + ".markdown"] : []
|
|
706
717
|
];
|
|
707
718
|
for (const v of variants) {
|
|
708
719
|
const e = index.byRelativePath.get(v);
|
|
@@ -728,6 +739,11 @@ function lookupEntry(target, index, options, currentSourcePath) {
|
|
|
728
739
|
}
|
|
729
740
|
}
|
|
730
741
|
}
|
|
742
|
+
const folderFallback = options.sidebarAuto?.folderLinkFallback ?? "first-file";
|
|
743
|
+
if (folderFallback === "first-file") {
|
|
744
|
+
const first = findFirstFileInFolder(target, index);
|
|
745
|
+
if (first) return first;
|
|
746
|
+
}
|
|
731
747
|
return void 0;
|
|
732
748
|
}
|
|
733
749
|
const aliasKey = options.caseSensitive ? target : target.toLowerCase();
|
|
@@ -749,14 +765,31 @@ function lookupEntry(target, index, options, currentSourcePath) {
|
|
|
749
765
|
return void 0;
|
|
750
766
|
}
|
|
751
767
|
}
|
|
768
|
+
function findFirstFileInFolder(folderPath, index) {
|
|
769
|
+
const prefix = folderPath + "/";
|
|
770
|
+
const candidates = [];
|
|
771
|
+
for (const f of index.files.values()) {
|
|
772
|
+
if (f.relativePath.startsWith(prefix)) candidates.push(f);
|
|
773
|
+
}
|
|
774
|
+
if (candidates.length === 0) return void 0;
|
|
775
|
+
candidates.sort((a, b) => {
|
|
776
|
+
const da = a.relativePath.split("/").length;
|
|
777
|
+
const db = b.relativePath.split("/").length;
|
|
778
|
+
if (da !== db) return da - db;
|
|
779
|
+
return a.relativePath.localeCompare(b.relativePath);
|
|
780
|
+
});
|
|
781
|
+
return candidates[0];
|
|
782
|
+
}
|
|
752
783
|
function buildDeadUrl(rawTarget, options) {
|
|
753
784
|
const safe = encodeURIComponent(stripMarkdownExt(rawTarget).split("#")[0]);
|
|
754
785
|
return options.base + safe;
|
|
755
786
|
}
|
|
756
|
-
function defaultLabel(target, headingPart, entry, options) {
|
|
787
|
+
function defaultLabel(target, headingPart, entry, options, wasFolderForm = false) {
|
|
757
788
|
const lt = options.wikilinks.linkText;
|
|
758
789
|
let base;
|
|
759
|
-
if (
|
|
790
|
+
if (wasFolderForm) {
|
|
791
|
+
base = basename(target) || target;
|
|
792
|
+
} else if (typeof lt === "function") {
|
|
760
793
|
if (entry) {
|
|
761
794
|
base = lt(entry, target);
|
|
762
795
|
} else {
|
|
@@ -2391,15 +2424,28 @@ function viteAllYouNeed(userOptions = {}) {
|
|
|
2391
2424
|
},
|
|
2392
2425
|
handleHotUpdate(ctx) {
|
|
2393
2426
|
if (!index) return;
|
|
2427
|
+
const isMd = /\.(md|markdown)$/i.test(ctx.file);
|
|
2428
|
+
const wasIndexed = isMd && index.files.has(ctx.file);
|
|
2429
|
+
let structuralChange = null;
|
|
2394
2430
|
try {
|
|
2395
2431
|
const stat = import_node_fs7.default.statSync(ctx.file);
|
|
2396
2432
|
if (stat.isFile()) {
|
|
2397
2433
|
updateFile(index, ctx.file, resolved);
|
|
2434
|
+
const isNowIndexed = index.files.has(ctx.file);
|
|
2435
|
+
if (!wasIndexed && isNowIndexed) structuralChange = "add";
|
|
2398
2436
|
} else if (!import_node_fs7.default.existsSync(ctx.file)) {
|
|
2399
2437
|
removeFile(index, ctx.file, resolved);
|
|
2438
|
+
if (wasIndexed) structuralChange = "remove";
|
|
2400
2439
|
}
|
|
2401
2440
|
} catch {
|
|
2402
2441
|
removeFile(index, ctx.file, resolved);
|
|
2442
|
+
if (wasIndexed) structuralChange = "remove";
|
|
2443
|
+
}
|
|
2444
|
+
if (structuralChange) {
|
|
2445
|
+
const rel = toPosix(ctx.file).replace(toPosix(resolved.srcDir) + "/", "");
|
|
2446
|
+
console.warn(
|
|
2447
|
+
`vitepress-allyouneed: \u68C0\u6D4B\u5230\u7ED3\u6784\u53D8\u5316(${structuralChange === "add" ? "\u65B0\u589E" : "\u5220\u9664"} ${rel}),sidebar/nav \u5DF2\u88AB\u70D8\u7119\u5230 VitePress \u914D\u7F6E\u4E2D,**\u91CD\u542F dev \u670D\u52A1\u5668**\u624D\u80FD\u53CD\u6620;wikilink/asset \u5DF2\u5B9E\u65F6\u5237\u65B0\u3002`
|
|
2448
|
+
);
|
|
2403
2449
|
}
|
|
2404
2450
|
if (resolved.modules.views) {
|
|
2405
2451
|
try {
|
|
@@ -2513,6 +2559,11 @@ function injectViewsSidebar(sidebar, options) {
|
|
|
2513
2559
|
arr.push(group);
|
|
2514
2560
|
}
|
|
2515
2561
|
}
|
|
2562
|
+
if (!sidebar["/"]) {
|
|
2563
|
+
sidebar["/"] = [group];
|
|
2564
|
+
} else if (!sidebar["/"].some((it) => it.text === group.text)) {
|
|
2565
|
+
sidebar["/"].push(group);
|
|
2566
|
+
}
|
|
2516
2567
|
}
|
|
2517
2568
|
const prefix = options.views.urlPrefix ? options.views.urlPrefix.replace(/^\/+|\/+$/g, "") : "";
|
|
2518
2569
|
if (prefix) {
|
|
@@ -2534,10 +2585,11 @@ function buildPerspectivesFallbackSidebar(allSidebars, group, base, viewsPrefix)
|
|
|
2534
2585
|
const out = [{ text: "Home", link: "/" }];
|
|
2535
2586
|
const persSuffix = `/${viewsPrefix}/`;
|
|
2536
2587
|
const topPaths = Object.keys(allSidebars).filter(
|
|
2537
|
-
(p) => p !== base && !p.endsWith(persSuffix)
|
|
2588
|
+
(p) => p !== "/" && p !== base && !p.endsWith(persSuffix)
|
|
2538
2589
|
);
|
|
2539
2590
|
for (const p of topPaths) {
|
|
2540
2591
|
const seg = p.replace(/^\/|\/$/g, "").split("/").filter(Boolean).pop() ?? p;
|
|
2592
|
+
if (!seg) continue;
|
|
2541
2593
|
const text = seg.charAt(0).toUpperCase() + seg.slice(1);
|
|
2542
2594
|
const b = base.endsWith("/") ? base : base + "/";
|
|
2543
2595
|
const stripped = b !== "/" && p.startsWith(b) ? "/" + p.slice(b.length) : p;
|
|
@@ -2579,6 +2631,26 @@ function injectViewsNav(nav, options) {
|
|
|
2579
2631
|
link: it.link
|
|
2580
2632
|
}))
|
|
2581
2633
|
};
|
|
2634
|
+
if (typeof nav === "function") {
|
|
2635
|
+
const userFn = nav;
|
|
2636
|
+
return () => {
|
|
2637
|
+
let arr2;
|
|
2638
|
+
try {
|
|
2639
|
+
const r = userFn();
|
|
2640
|
+
arr2 = Array.isArray(r) ? [...r] : [];
|
|
2641
|
+
} catch (e) {
|
|
2642
|
+
console.warn(
|
|
2643
|
+
"vitepress-allyouneed: themeConfig.nav \u51FD\u6570\u6267\u884C\u5931\u8D25,\u4EC5\u8FD4\u56DE Perspectives \u4E0B\u62C9\u3002",
|
|
2644
|
+
e instanceof Error ? e.message : String(e)
|
|
2645
|
+
);
|
|
2646
|
+
arr2 = [];
|
|
2647
|
+
}
|
|
2648
|
+
if (!arr2.some((it) => it && it.text === navItem.text)) {
|
|
2649
|
+
arr2.push(navItem);
|
|
2650
|
+
}
|
|
2651
|
+
return arr2;
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2582
2654
|
const arr = Array.isArray(nav) ? [...nav] : [];
|
|
2583
2655
|
if (!arr.some((it) => it.text === navItem.text)) {
|
|
2584
2656
|
arr.push(navItem);
|
|
@@ -2761,7 +2833,8 @@ function resolveSidebarAutoOptions(user = {}) {
|
|
|
2761
2833
|
groupLink: user.groupLink ?? "all",
|
|
2762
2834
|
includePrefix: user.includePrefix,
|
|
2763
2835
|
excludePrefixes: user.excludePrefixes ?? [],
|
|
2764
|
-
foldersFirst: user.foldersFirst ?? false
|
|
2836
|
+
foldersFirst: user.foldersFirst ?? false,
|
|
2837
|
+
folderLinkFallback: user.folderLinkFallback ?? "first-file"
|
|
2765
2838
|
};
|
|
2766
2839
|
}
|
|
2767
2840
|
function defaultItemTitle(entry, strip) {
|
|
@@ -2923,8 +2996,13 @@ function renderNode(node, opts, depth, isRoot, index, options) {
|
|
|
2923
2996
|
collapsed: resolveGroupCollapsed(child.dirIndex, opts),
|
|
2924
2997
|
items: childItems
|
|
2925
2998
|
};
|
|
2926
|
-
if (
|
|
2927
|
-
|
|
2999
|
+
if (shouldLinkGroup(opts, isRoot)) {
|
|
3000
|
+
if (child.dirIndex && !child.dirIndexEmpty) {
|
|
3001
|
+
group.link = child.dirIndex.url;
|
|
3002
|
+
} else if (!child.dirIndex && opts.folderLinkFallback === "first-file") {
|
|
3003
|
+
const first = findFirstPageUrl(child, opts);
|
|
3004
|
+
if (first) group.link = first;
|
|
3005
|
+
}
|
|
2928
3006
|
}
|
|
2929
3007
|
folderItems.push(group);
|
|
2930
3008
|
}
|
|
@@ -3008,8 +3086,13 @@ function toFlatSidebar(root, opts) {
|
|
|
3008
3086
|
collapsed: resolveGroupCollapsed(d.dirIndex, opts),
|
|
3009
3087
|
items
|
|
3010
3088
|
};
|
|
3011
|
-
if (
|
|
3012
|
-
|
|
3089
|
+
if (shouldLinkGroup(opts, true)) {
|
|
3090
|
+
if (d.dirIndex && !d.dirIndexEmpty) {
|
|
3091
|
+
group.link = d.dirIndex.url;
|
|
3092
|
+
} else if (!d.dirIndex && opts.folderLinkFallback === "first-file") {
|
|
3093
|
+
const first = findFirstPageUrl(d, opts);
|
|
3094
|
+
if (first) group.link = first;
|
|
3095
|
+
}
|
|
3013
3096
|
}
|
|
3014
3097
|
out.push(group);
|
|
3015
3098
|
}
|
|
@@ -3042,7 +3125,12 @@ function toPerFolderSidebar(root, opts, options, index) {
|
|
|
3042
3125
|
/* isTopLevel */
|
|
3043
3126
|
true
|
|
3044
3127
|
)) {
|
|
3045
|
-
|
|
3128
|
+
let firstUrl = null;
|
|
3129
|
+
if (child.dirIndex && !child.dirIndexEmpty) {
|
|
3130
|
+
firstUrl = child.dirIndex.url;
|
|
3131
|
+
} else if (!child.dirIndex && opts.folderLinkFallback === "first-file") {
|
|
3132
|
+
firstUrl = findFirstPageUrl(child, opts);
|
|
3133
|
+
}
|
|
3046
3134
|
if (firstUrl) {
|
|
3047
3135
|
rootItems.push({ text: labelText, link: firstUrl });
|
|
3048
3136
|
} else {
|
|
@@ -3067,16 +3155,23 @@ function toPerFolderSidebar(root, opts, options, index) {
|
|
|
3067
3155
|
);
|
|
3068
3156
|
if (items.length === 0 && !child.dirIndex) continue;
|
|
3069
3157
|
const sidebar = [];
|
|
3070
|
-
|
|
3158
|
+
if (shouldLinkGroup(
|
|
3071
3159
|
opts,
|
|
3072
3160
|
/* isTopLevel */
|
|
3073
3161
|
true
|
|
3074
|
-
)
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3162
|
+
)) {
|
|
3163
|
+
let selfUrl = null;
|
|
3164
|
+
if (child.dirIndex && !child.dirIndexEmpty) {
|
|
3165
|
+
selfUrl = child.dirIndex.url;
|
|
3166
|
+
} else if (!child.dirIndex && opts.folderLinkFallback === "first-file") {
|
|
3167
|
+
selfUrl = findFirstPageUrl(child, opts);
|
|
3168
|
+
}
|
|
3169
|
+
if (selfUrl) {
|
|
3170
|
+
sidebar.push({
|
|
3171
|
+
text: computeGroupText(child.path, child.dirIndex, opts),
|
|
3172
|
+
link: selfUrl
|
|
3173
|
+
});
|
|
3174
|
+
}
|
|
3080
3175
|
}
|
|
3081
3176
|
sidebar.push(...items);
|
|
3082
3177
|
out[`/${key}/`] = sidebar;
|
|
@@ -3104,10 +3199,12 @@ function generateNav(index, options, autoOptions = {}) {
|
|
|
3104
3199
|
let link;
|
|
3105
3200
|
if (child.dirIndex && !child.dirIndexEmpty) {
|
|
3106
3201
|
link = stripBase(child.dirIndex.url, base);
|
|
3107
|
-
} else {
|
|
3202
|
+
} else if (opts.folderLinkFallback === "first-file") {
|
|
3108
3203
|
const first = findFirstPageUrl(child, opts);
|
|
3109
3204
|
if (!first) continue;
|
|
3110
3205
|
link = first;
|
|
3206
|
+
} else {
|
|
3207
|
+
continue;
|
|
3111
3208
|
}
|
|
3112
3209
|
const escapedPrefix = `/${key}/`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3113
3210
|
out.push({ text, link, activeMatch: "^" + escapedPrefix });
|
|
@@ -3277,7 +3374,9 @@ function generateFolderIndexes(options, folderOpts = {}) {
|
|
|
3277
3374
|
dirRelPath: dirRel,
|
|
3278
3375
|
title: humanize2(lastSeg, strip) || "Home",
|
|
3279
3376
|
files,
|
|
3280
|
-
subDirs
|
|
3377
|
+
subDirs,
|
|
3378
|
+
isRoot: dirRel === "",
|
|
3379
|
+
groupLink: folderOpts.groupLink ?? "all"
|
|
3281
3380
|
};
|
|
3282
3381
|
try {
|
|
3283
3382
|
import_node_fs8.default.writeFileSync(target, template(ctx), "utf8");
|
|
@@ -3358,6 +3457,7 @@ function humanize2(name, stripNumeric) {
|
|
|
3358
3457
|
}
|
|
3359
3458
|
function defaultTemplate(ctx) {
|
|
3360
3459
|
const prefix = ctx.dirRelPath === "" ? "" : `${ctx.dirRelPath}/`;
|
|
3460
|
+
const subDirLinkable = subFolderClickable(ctx.groupLink, ctx.isRoot);
|
|
3361
3461
|
const lines = [];
|
|
3362
3462
|
lines.push("---");
|
|
3363
3463
|
lines.push(`title: ${ctx.title}`);
|
|
@@ -3368,15 +3468,19 @@ function defaultTemplate(ctx) {
|
|
|
3368
3468
|
lines.push(`# ${ctx.title}`);
|
|
3369
3469
|
lines.push("");
|
|
3370
3470
|
if (ctx.subDirs.length > 0) {
|
|
3371
|
-
lines.push("##
|
|
3471
|
+
lines.push("## Folders");
|
|
3372
3472
|
lines.push("");
|
|
3373
3473
|
for (const d of ctx.subDirs) {
|
|
3374
|
-
|
|
3474
|
+
if (subDirLinkable) {
|
|
3475
|
+
lines.push(`- [[${prefix}${d.name}/|${d.title}]]`);
|
|
3476
|
+
} else {
|
|
3477
|
+
lines.push(`- ${d.title}`);
|
|
3478
|
+
}
|
|
3375
3479
|
}
|
|
3376
3480
|
lines.push("");
|
|
3377
3481
|
}
|
|
3378
3482
|
if (ctx.files.length > 0) {
|
|
3379
|
-
lines.push("##
|
|
3483
|
+
lines.push("## Files");
|
|
3380
3484
|
lines.push("");
|
|
3381
3485
|
for (const f of ctx.files) {
|
|
3382
3486
|
lines.push(`- [[${prefix}${f.relPath}|${f.title}]]`);
|
|
@@ -3385,6 +3489,11 @@ function defaultTemplate(ctx) {
|
|
|
3385
3489
|
}
|
|
3386
3490
|
return lines.join("\n");
|
|
3387
3491
|
}
|
|
3492
|
+
function subFolderClickable(groupLink, isRoot) {
|
|
3493
|
+
if (groupLink === "off") return false;
|
|
3494
|
+
if (groupLink === "top-level") return isRoot;
|
|
3495
|
+
return true;
|
|
3496
|
+
}
|
|
3388
3497
|
|
|
3389
3498
|
// src/core/scan-wikilinks.ts
|
|
3390
3499
|
var WIKILINK_RE3 = /(!?)\[\[([^\]\n]+)\]\]/g;
|
|
@@ -3534,6 +3643,7 @@ function defineConfigWithAllYouNeed(config, pluginOptions = {}) {
|
|
|
3534
3643
|
sidebarAuto.autoFolderIndex,
|
|
3535
3644
|
sidebarAuto.stripNumericPrefix
|
|
3536
3645
|
);
|
|
3646
|
+
folderOpts.groupLink = sidebarAuto.groupLink ?? "all";
|
|
3537
3647
|
if (folderOpts.mode !== "off") {
|
|
3538
3648
|
try {
|
|
3539
3649
|
generateFolderIndexes(resolvedForWrapper, folderOpts);
|
|
@@ -3604,7 +3714,6 @@ function defineConfigWithAllYouNeed(config, pluginOptions = {}) {
|
|
|
3604
3714
|
const localesForViews = config.locales;
|
|
3605
3715
|
if (localesForViews) {
|
|
3606
3716
|
for (const lang of Object.keys(localesForViews)) {
|
|
3607
|
-
if (lang === "root") continue;
|
|
3608
3717
|
const lc = localesForViews[lang];
|
|
3609
3718
|
if (!lc.themeConfig) lc.themeConfig = {};
|
|
3610
3719
|
if (lc.themeConfig.sidebar !== void 0) {
|