diff --git a/docs/configuration.md b/docs/configuration.md index 763a27a92..047f6ca6b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -31,6 +31,7 @@ This part of the configuration concerns anything that can affect the whole site. - This should also include the subpath if you are [[hosting]] on GitHub pages without a custom domain. For example, if my repository is `jackyzha0/quartz`, GitHub pages would deploy to `https://jackyzha0.github.io/quartz` and the `baseUrl` would be `jackyzha0.github.io/quartz` - Note that Quartz 4 will avoid using this as much as possible and use relative URLs whenever it can to make sure your site works no matter _where_ you end up actually deploying it. - `ignorePatterns`: a list of [glob]() patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details. +- `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings. - `theme`: configure how the site looks. - `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here. - `header`: Font to use for headers diff --git a/quartz.config.ts b/quartz.config.ts index 447039d62..64e86dce0 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -11,6 +11,7 @@ const config: QuartzConfig = { }, baseUrl: "quartz.jzhao.xyz", ignorePatterns: ["private", "templates"], + defaultDateType: "created", theme: { typography: { header: "Schibsted Grotesk", diff --git a/quartz/cfg.ts b/quartz/cfg.ts index e3fee360f..21e03016a 100644 --- a/quartz/cfg.ts +++ b/quartz/cfg.ts @@ -1,3 +1,4 @@ +import { ValidDateType } from "./components/Date" import { QuartzComponent } from "./components/types" import { PluginTypes } from "./plugins/types" import { Theme } from "./util/theme" @@ -22,6 +23,8 @@ export interface GlobalConfiguration { analytics: Analytics /** Glob patterns to not search */ ignorePatterns: string[] + /** Whether to use created, modified, or published as the default type of date */ + defaultDateType: ValidDateType /** Base URL to use for CNAME files, sitemaps, and RSS feeds that require an absolute URL. * Quartz will avoid using this as much as possible and use relative URLs most of the time */ diff --git a/quartz/components/ContentMeta.tsx b/quartz/components/ContentMeta.tsx index 715c0f469..3e1b70112 100644 --- a/quartz/components/ContentMeta.tsx +++ b/quartz/components/ContentMeta.tsx @@ -1,15 +1,16 @@ -import { formatDate } from "./Date" +import { formatDate, getDate } from "./Date" import { QuartzComponentConstructor, QuartzComponentProps } from "./types" import readingTime from "reading-time" export default (() => { - function ContentMetadata({ fileData }: QuartzComponentProps) { + function ContentMetadata({ cfg, fileData }: QuartzComponentProps) { const text = fileData.text if (text) { const segments: string[] = [] const { text: timeTaken, words: _words } = readingTime(text) - if (fileData.dates?.modified) { - segments.push(formatDate(fileData.dates.modified)) + + if (fileData.dates) { + segments.push(formatDate(getDate(cfg, fileData)!)) } segments.push(timeTaken) diff --git a/quartz/components/Date.tsx b/quartz/components/Date.tsx index f4b284af9..0530a373a 100644 --- a/quartz/components/Date.tsx +++ b/quartz/components/Date.tsx @@ -1,7 +1,16 @@ +import { GlobalConfiguration } from "../cfg" +import { QuartzPluginData } from "../plugins/vfile" + interface Props { date: Date } +export type ValidDateType = keyof Required["dates"] + +export function getDate(cfg: GlobalConfiguration, data: QuartzPluginData): Date | undefined { + return data.dates?.[cfg.defaultDateType] +} + export function formatDate(d: Date): string { return d.toLocaleDateString("en-US", { year: "numeric", diff --git a/quartz/components/PageList.tsx b/quartz/components/PageList.tsx index c55b53478..eb34f02f7 100644 --- a/quartz/components/PageList.tsx +++ b/quartz/components/PageList.tsx @@ -1,31 +1,36 @@ import { FullSlug, resolveRelative } from "../util/path" import { QuartzPluginData } from "../plugins/vfile" -import { Date } from "./Date" +import { Date, getDate } from "./Date" import { QuartzComponentProps } from "./types" +import { GlobalConfiguration } from "../cfg" -export function byDateAndAlphabetical(f1: QuartzPluginData, f2: QuartzPluginData): number { - if (f1.dates && f2.dates) { - // sort descending by last modified - return f2.dates.modified.getTime() - f1.dates.modified.getTime() - } else if (f1.dates && !f2.dates) { - // prioritize files with dates - return -1 - } else if (!f1.dates && f2.dates) { - return 1 +export function byDateAndAlphabetical( + cfg: GlobalConfiguration, +): (f1: QuartzPluginData, f2: QuartzPluginData) => number { + return (f1, f2) => { + if (f1.dates && f2.dates) { + // sort descending + return getDate(cfg, f2)!.getTime() - getDate(cfg, f1)!.getTime() + } else if (f1.dates && !f2.dates) { + // prioritize files with dates + return -1 + } else if (!f1.dates && f2.dates) { + return 1 + } + + // otherwise, sort lexographically by title + const f1Title = f1.frontmatter?.title.toLowerCase() ?? "" + const f2Title = f2.frontmatter?.title.toLowerCase() ?? "" + return f1Title.localeCompare(f2Title) } - - // otherwise, sort lexographically by title - const f1Title = f1.frontmatter?.title.toLowerCase() ?? "" - const f2Title = f2.frontmatter?.title.toLowerCase() ?? "" - return f1Title.localeCompare(f2Title) } type Props = { limit?: number } & QuartzComponentProps -export function PageList({ fileData, allFiles, limit }: Props) { - let list = allFiles.sort(byDateAndAlphabetical) +export function PageList({ cfg, fileData, allFiles, limit }: Props) { + let list = allFiles.sort(byDateAndAlphabetical(cfg)) if (limit) { list = list.slice(0, limit) } @@ -41,7 +46,7 @@ export function PageList({ fileData, allFiles, limit }: Props) {
{page.dates && (

- +

)}
diff --git a/quartz/components/RecentNotes.tsx b/quartz/components/RecentNotes.tsx index 2b61b39cb..673d08458 100644 --- a/quartz/components/RecentNotes.tsx +++ b/quartz/components/RecentNotes.tsx @@ -3,7 +3,8 @@ import { FullSlug, SimpleSlug, resolveRelative } from "../util/path" import { QuartzPluginData } from "../plugins/vfile" import { byDateAndAlphabetical } from "./PageList" import style from "./styles/recentNotes.scss" -import { Date } from "./Date" +import { Date, getDate } from "./Date" +import { GlobalConfiguration } from "../cfg" interface Options { title: string @@ -13,18 +14,18 @@ interface Options { sort: (f1: QuartzPluginData, f2: QuartzPluginData) => number } -const defaultOptions: Options = { +const defaultOptions = (cfg: GlobalConfiguration): Options => ({ title: "Recent Notes", limit: 3, linkToMore: false, filter: () => true, - sort: byDateAndAlphabetical, -} + sort: byDateAndAlphabetical(cfg), +}) export default ((userOpts?: Partial) => { - const opts = { ...defaultOptions, ...userOpts } function RecentNotes(props: QuartzComponentProps) { - const { allFiles, fileData, displayClass } = props + const { allFiles, fileData, displayClass, cfg } = props + const opts = { ...defaultOptions(cfg), ...userOpts } const pages = allFiles.filter(opts.filter).sort(opts.sort) const remaining = Math.max(0, pages.length - opts.limit) return ( @@ -47,7 +48,7 @@ export default ((userOpts?: Partial) => {
{page.dates && (

- +

)}
    diff --git a/quartz/plugins/emitters/contentIndex.ts b/quartz/plugins/emitters/contentIndex.ts index 4610cd410..1c7feaea2 100644 --- a/quartz/plugins/emitters/contentIndex.ts +++ b/quartz/plugins/emitters/contentIndex.ts @@ -1,4 +1,5 @@ import { GlobalConfiguration } from "../../cfg" +import { getDate } from "../../components/Date" import { FilePath, FullSlug, SimpleSlug, simplifySlug } from "../../util/path" import { QuartzEmitterPlugin } from "../types" import path from "path" @@ -74,7 +75,7 @@ export const ContentIndex: QuartzEmitterPlugin> = (opts) => { const linkIndex: ContentIndex = new Map() for (const [_tree, file] of content) { const slug = file.data.slug! - const date = file.data.dates?.modified ?? new Date() + const date = getDate(ctx.cfg.configuration, file.data) ?? new Date() if (opts?.includeEmptyFiles || (file.data.text && file.data.text !== "")) { linkIndex.set(slug, { title: file.data.frontmatter?.title!,