QuartzにはデフォルトでExplorerというノートの一覧を左サイドに表示する機能がある
この一覧を更新順にソートしたい
結論
contentIndex.tsx
内のdate
を削除している行をコメントアウトする
- delete content.date
+ // delete content.date
quartz.layout.ts
にソート関数を実装してExplorer
に与える
import { Options } from "./quartz/components/Explorer"
...
const sortFn: Options["sortFn"] = (a, b) => {
if (a.data?.date && b.data?.date) {
const aDate = new Date(a.data?.date)
const bDate = new Date(b.data?.date)
const order = bDate.getTime() - aDate.getTime()
if (order != 0) return order
}
return a.displayName.localeCompare(b.displayName)
}
...
export const defaultContentPageLayout: PageLayout = {
...
left: [
...
Component.Explorer({ sortFn }),
],
...
}
紆余曲折
軽く調べると、quartz.layout.ts
からソート関数を差し込めることがわかる
export const defaultContentPageLayout: PageLayout = {
...
left: [
...
Component.Explorer({ sortFn }),
],
}
ソート関数は以下のような形をしている
const sortFn: Options["sortFn"] = (a, b) => {
return 1 // or -1
}
a
とb
はFileTrieNode<ContentDetails>
型のオブジェクトである
ContentDetails
の定義を見てみると
export type ContentDetails = {
slug: FullSlug
filePath: FilePath
title: string
links: SimpleSlug[]
tags: string[]
content: string
richContent?: string
date?: Date
description?: string
}
date
あるじゃん!
じゃあということでソート関数を実装する
const sortFn: Options["sortFn"]: (a, b) => {
const aDate = a.data?.date
const bDate = b.data?.date
if (aDate && bDate) {
const order = bDate.getTime() - aDate.getTime()
if (order != 0) return order
}
return a.displayName.localeCompare(b.displayName)
}
これでビルドしてみるとdate
はundefined
ですよって言われる
なのでdate
が格納されるところを見に行く
実は、Explorer
はcontentIndex.json
を非同期に受け取って表示している
そのjson
が作られているところを見に行くと
const simplifiedIndex = Object.fromEntries(
Array.from(linkIndex).map(([slug, content]) => {
// remove description and from content index as nothing downstream
// actually uses it. we only keep it in the index as we need it
// for the RSS feed
delete content.description
delete content.date
return [slug, content]
}),
)
yield write({
ctx,
content: JSON.stringify(simplifiedIndex),
slug: fp,
ext: ".json",
})
なんとdate
が消されている!
これをコメントアウトする
今度こそ上手くいっただろうとビルドすると
date
にgetTime
メソッドなんてないですよって言われる
実は、jsonをパースする都合上ContentDetails
のdate
はDate
型にキャストされずにstring
型のままになっている
ソート関数側でDate
オブジェクトを作ってやると上手くいった
余談
このあと、フォルダ機能を使わないのと日付を見せてほしいという理由でRecentNotes
をいじって使うことにした
その結果ほとんどExplorer
と同じロジックを実装することになった
今思えばExplorer
の見た目を変えるほうがまだ修正コストが低かったかもしれない