Skip to content

Commit af7fafc

Browse files
MasssiveJuice08tha00aarnphm
authored
feat(folder): add intermediate folders pages (#1295) (#110)
Co-authored-by: Thomas Hack <39602241+tha00@users.noreply.github.com> Co-authored-by: Aaron Pham <Aaronpham0103@gmail.com> Co-authored-by: Aaron Pham <contact@aarnphm.xyz>
1 parent b0320cf commit af7fafc

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

quartz/components/pages/FolderContent.tsx

+41-6
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } fro
22
import path from "path"
33

44
import style from "../styles/listPage.scss"
5-
import { PageList } from "../PageList"
6-
import { stripSlashes, simplifySlug } from "../../util/path"
5+
import { byDateAndAlphabetical, PageList, SortFn } from "../PageList"
6+
import { stripSlashes, simplifySlug, joinSegments, FullSlug } from "../../util/path"
77
import { Root } from "hast"
88
import { htmlToJsx } from "../../util/jsx"
99
import { i18n } from "../../i18n"
@@ -14,11 +14,13 @@ interface FolderContentOptions {
1414
* Whether to display number of folders
1515
*/
1616
showFolderCount: boolean
17-
sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number
17+
showSubfolders: boolean
18+
sort?: SortFn
1819
}
1920

2021
const defaultOptions: FolderContentOptions = {
2122
showFolderCount: true,
23+
showSubfolders: true,
2224
}
2325

2426
export default ((opts?: Partial<FolderContentOptions>) => {
@@ -27,14 +29,47 @@ export default ((opts?: Partial<FolderContentOptions>) => {
2729
const FolderContent: QuartzComponent = (props: QuartzComponentProps) => {
2830
const { tree, fileData, allFiles, cfg } = props
2931
const folderSlug = stripSlashes(simplifySlug(fileData.slug!))
30-
const allPagesInFolder = allFiles.filter((file) => {
32+
const folderParts = folderSlug.split(path.posix.sep)
33+
34+
const allPagesInFolder: QuartzPluginData[] = []
35+
const allPagesInSubfolders: Map<FullSlug, QuartzPluginData[]> = new Map()
36+
37+
allFiles.forEach((file) => {
3138
const fileSlug = stripSlashes(simplifySlug(file.slug!))
3239
const prefixed = fileSlug.startsWith(folderSlug) && fileSlug !== folderSlug
33-
const folderParts = folderSlug.split(path.posix.sep)
3440
const fileParts = fileSlug.split(path.posix.sep)
3541
const isDirectChild = fileParts.length === folderParts.length + 1
36-
return prefixed && isDirectChild
42+
43+
if (!prefixed) {
44+
return
45+
}
46+
47+
if (isDirectChild) {
48+
allPagesInFolder.push(file)
49+
} else if (options.showSubfolders) {
50+
const subfolderSlug = joinSegments(
51+
...fileParts.slice(0, folderParts.length + 1),
52+
) as FullSlug
53+
const pagesInFolder = allPagesInSubfolders.get(subfolderSlug) || []
54+
allPagesInSubfolders.set(subfolderSlug, [...pagesInFolder, file])
55+
}
3756
})
57+
58+
allPagesInSubfolders.forEach((files, subfolderSlug) => {
59+
const hasIndex = allPagesInFolder.some(
60+
(file) => subfolderSlug === stripSlashes(simplifySlug(file.slug!)),
61+
)
62+
if (!hasIndex) {
63+
const subfolderDates = files.sort(byDateAndAlphabetical(cfg))[0].dates
64+
const subfolderTitle = subfolderSlug.split(path.posix.sep).at(-1)!
65+
allPagesInFolder.push({
66+
slug: subfolderSlug,
67+
dates: subfolderDates,
68+
frontmatter: { title: subfolderTitle, tags: ["folder"] },
69+
})
70+
}
71+
})
72+
3873
const cssClasses: string[] = fileData.frontmatter?.cssclasses ?? []
3974
const classes = ["popover-hint", ...cssClasses].join(" ")
4075
const listProps = {

quartz/plugins/emitters/folderPage.tsx

+16-6
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,11 @@ export const FolderPage: QuartzEmitterPlugin<
7474

7575
const folders: Set<SimpleSlug> = new Set(
7676
allFiles.flatMap((data) => {
77-
const slug = data.slug
78-
const folderName = path.dirname(slug ?? "") as SimpleSlug
79-
if (slug && folderName !== "." && folderName !== "tags") {
80-
return [folderName]
81-
}
82-
return []
77+
return data.slug
78+
? _getFolders(data.slug).filter(
79+
(folderName) => folderName !== "." && folderName !== "tags",
80+
)
81+
: []
8382
}),
8483
)
8584

@@ -131,3 +130,14 @@ export const FolderPage: QuartzEmitterPlugin<
131130
},
132131
}
133132
}
133+
134+
function _getFolders(slug: FullSlug): SimpleSlug[] {
135+
var folderName = path.dirname(slug ?? "") as SimpleSlug
136+
const parentFolderNames = [folderName]
137+
138+
while (folderName !== ".") {
139+
folderName = path.dirname(folderName ?? "") as SimpleSlug
140+
parentFolderNames.push(folderName)
141+
}
142+
return parentFolderNames
143+
}

0 commit comments

Comments
 (0)