From ea92ed4f45e6e863a432447a977c33c6319423bc Mon Sep 17 00:00:00 2001
From: Cao Mingjun <me@caomingjun.com>
Date: Wed, 10 Jul 2024 00:42:33 +0000
Subject: [PATCH] feat: Allow custom sorting of FolderPage and TagPage (#1250)
---
quartz/components/pages/TagContent.tsx | 196 ++++++++++++++++++++++++------------------------
1 files changed, 99 insertions(+), 97 deletions(-)
diff --git a/quartz/components/pages/TagContent.tsx b/quartz/components/pages/TagContent.tsx
index 9e04359..7598b13 100644
--- a/quartz/components/pages/TagContent.tsx
+++ b/quartz/components/pages/TagContent.tsx
@@ -7,107 +7,109 @@
import { htmlToJsx } from "../../util/jsx"
import { i18n } from "../../i18n"
-const numPages = 10
-const TagContent: QuartzComponent = (props: QuartzComponentProps) => {
- const { tree, fileData, allFiles, cfg } = props
- const slug = fileData.slug
+export default ((opts?: { sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number }) => {
+ const numPages = 10
+ const TagContent: QuartzComponent = (props: QuartzComponentProps) => {
+ const { tree, fileData, allFiles, cfg } = props
+ const slug = fileData.slug
- if (!(slug?.startsWith("tags/") || slug === "tags")) {
- throw new Error(`Component "TagContent" tried to render a non-tag page: ${slug}`)
- }
-
- const tag = simplifySlug(slug.slice("tags/".length) as FullSlug)
- const allPagesWithTag = (tag: string) =>
- allFiles.filter((file) =>
- (file.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes).includes(tag),
- )
-
- const content =
- (tree as Root).children.length === 0
- ? fileData.description
- : htmlToJsx(fileData.filePath!, tree)
- const cssClasses: string[] = fileData.frontmatter?.cssclasses ?? []
- const classes = ["popover-hint", ...cssClasses].join(" ")
- if (tag === "/") {
- const tags = [
- ...new Set(
- allFiles.flatMap((data) => data.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes),
- ),
- ].sort((a, b) => a.localeCompare(b))
- const tagItemMap: Map<string, QuartzPluginData[]> = new Map()
- for (const tag of tags) {
- tagItemMap.set(tag, allPagesWithTag(tag))
- }
- return (
- <div class={classes}>
- <article>
- <p>{content}</p>
- </article>
- <p>{i18n(cfg.locale).pages.tagContent.totalTags({ count: tags.length })}</p>
- <div>
- {tags.map((tag) => {
- const pages = tagItemMap.get(tag)!
- const listProps = {
- ...props,
- allFiles: pages,
- }
-
- const contentPage = allFiles.filter((file) => file.slug === `tags/${tag}`).at(0)
-
- const root = contentPage?.htmlAst
- const content =
- !root || root?.children.length === 0
- ? contentPage?.description
- : htmlToJsx(contentPage.filePath!, root)
-
- return (
- <div>
- <h2>
- <a class="internal tag-link" href={`../tags/${tag}`}>
- {tag}
- </a>
- </h2>
- {content && <p>{content}</p>}
- <div class="page-listing">
- <p>
- {i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}
- {pages.length > numPages && (
- <>
- {" "}
- <span>
- {i18n(cfg.locale).pages.tagContent.showingFirst({ count: numPages })}
- </span>
- </>
- )}
- </p>
- <PageList limit={numPages} {...listProps} />
- </div>
- </div>
- )
- })}
- </div>
- </div>
- )
- } else {
- const pages = allPagesWithTag(tag)
- const listProps = {
- ...props,
- allFiles: pages,
+ if (!(slug?.startsWith("tags/") || slug === "tags")) {
+ throw new Error(`Component "TagContent" tried to render a non-tag page: ${slug}`)
}
- return (
- <div class={classes}>
- <article>{content}</article>
- <div class="page-listing">
- <p>{i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}</p>
+ const tag = simplifySlug(slug.slice("tags/".length) as FullSlug)
+ const allPagesWithTag = (tag: string) =>
+ allFiles.filter((file) =>
+ (file.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes).includes(tag),
+ )
+
+ const content =
+ (tree as Root).children.length === 0
+ ? fileData.description
+ : htmlToJsx(fileData.filePath!, tree)
+ const cssClasses: string[] = fileData.frontmatter?.cssclasses ?? []
+ const classes = ["popover-hint", ...cssClasses].join(" ")
+ if (tag === "/") {
+ const tags = [
+ ...new Set(
+ allFiles.flatMap((data) => data.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes),
+ ),
+ ].sort((a, b) => a.localeCompare(b))
+ const tagItemMap: Map<string, QuartzPluginData[]> = new Map()
+ for (const tag of tags) {
+ tagItemMap.set(tag, allPagesWithTag(tag))
+ }
+ return (
+ <div class={classes}>
+ <article>
+ <p>{content}</p>
+ </article>
+ <p>{i18n(cfg.locale).pages.tagContent.totalTags({ count: tags.length })}</p>
<div>
- <PageList {...listProps} />
+ {tags.map((tag) => {
+ const pages = tagItemMap.get(tag)!
+ const listProps = {
+ ...props,
+ allFiles: pages,
+ }
+
+ const contentPage = allFiles.filter((file) => file.slug === `tags/${tag}`).at(0)
+
+ const root = contentPage?.htmlAst
+ const content =
+ !root || root?.children.length === 0
+ ? contentPage?.description
+ : htmlToJsx(contentPage.filePath!, root)
+
+ return (
+ <div>
+ <h2>
+ <a class="internal tag-link" href={`../tags/${tag}`}>
+ {tag}
+ </a>
+ </h2>
+ {content && <p>{content}</p>}
+ <div class="page-listing">
+ <p>
+ {i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}
+ {pages.length > numPages && (
+ <>
+ {" "}
+ <span>
+ {i18n(cfg.locale).pages.tagContent.showingFirst({ count: numPages })}
+ </span>
+ </>
+ )}
+ </p>
+ <PageList limit={numPages} {...listProps} sort={opts?.sort} />
+ </div>
+ </div>
+ )
+ })}
</div>
</div>
- </div>
- )
- }
-}
+ )
+ } else {
+ const pages = allPagesWithTag(tag)
+ const listProps = {
+ ...props,
+ allFiles: pages,
+ }
-TagContent.css = style + PageList.css
-export default (() => TagContent) satisfies QuartzComponentConstructor
+ return (
+ <div class={classes}>
+ <article>{content}</article>
+ <div class="page-listing">
+ <p>{i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}</p>
+ <div>
+ <PageList {...listProps} />
+ </div>
+ </div>
+ </div>
+ )
+ }
+ }
+
+ TagContent.css = style + PageList.css
+ return TagContent
+}) satisfies QuartzComponentConstructor
--
Gitblit v1.10.0