feat: add defaultDateType config

This commit is contained in:
Jacky Zhao 2023-08-24 08:56:40 -07:00
parent 98d82415dc
commit c36a9f3fb7
8 changed files with 52 additions and 30 deletions

View File

@ -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` - 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. - 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](<https://en.wikipedia.org/wiki/Glob_(programming)>) patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details. - `ignorePatterns`: a list of [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) 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. - `theme`: configure how the site looks.
- `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here. - `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here.
- `header`: Font to use for headers - `header`: Font to use for headers

View File

@ -11,6 +11,7 @@ const config: QuartzConfig = {
}, },
baseUrl: "quartz.jzhao.xyz", baseUrl: "quartz.jzhao.xyz",
ignorePatterns: ["private", "templates"], ignorePatterns: ["private", "templates"],
defaultDateType: "created",
theme: { theme: {
typography: { typography: {
header: "Schibsted Grotesk", header: "Schibsted Grotesk",

View File

@ -1,3 +1,4 @@
import { ValidDateType } from "./components/Date"
import { QuartzComponent } from "./components/types" import { QuartzComponent } from "./components/types"
import { PluginTypes } from "./plugins/types" import { PluginTypes } from "./plugins/types"
import { Theme } from "./util/theme" import { Theme } from "./util/theme"
@ -22,6 +23,8 @@ export interface GlobalConfiguration {
analytics: Analytics analytics: Analytics
/** Glob patterns to not search */ /** Glob patterns to not search */
ignorePatterns: string[] 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. /** 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 * Quartz will avoid using this as much as possible and use relative URLs most of the time
*/ */

View File

@ -1,15 +1,16 @@
import { formatDate } from "./Date" import { formatDate, getDate } from "./Date"
import { QuartzComponentConstructor, QuartzComponentProps } from "./types" import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
import readingTime from "reading-time" import readingTime from "reading-time"
export default (() => { export default (() => {
function ContentMetadata({ fileData }: QuartzComponentProps) { function ContentMetadata({ cfg, fileData }: QuartzComponentProps) {
const text = fileData.text const text = fileData.text
if (text) { if (text) {
const segments: string[] = [] const segments: string[] = []
const { text: timeTaken, words: _words } = readingTime(text) 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) segments.push(timeTaken)

View File

@ -1,7 +1,16 @@
import { GlobalConfiguration } from "../cfg"
import { QuartzPluginData } from "../plugins/vfile"
interface Props { interface Props {
date: Date date: Date
} }
export type ValidDateType = keyof Required<QuartzPluginData>["dates"]
export function getDate(cfg: GlobalConfiguration, data: QuartzPluginData): Date | undefined {
return data.dates?.[cfg.defaultDateType]
}
export function formatDate(d: Date): string { export function formatDate(d: Date): string {
return d.toLocaleDateString("en-US", { return d.toLocaleDateString("en-US", {
year: "numeric", year: "numeric",

View File

@ -1,12 +1,16 @@
import { FullSlug, resolveRelative } from "../util/path" import { FullSlug, resolveRelative } from "../util/path"
import { QuartzPluginData } from "../plugins/vfile" import { QuartzPluginData } from "../plugins/vfile"
import { Date } from "./Date" import { Date, getDate } from "./Date"
import { QuartzComponentProps } from "./types" import { QuartzComponentProps } from "./types"
import { GlobalConfiguration } from "../cfg"
export function byDateAndAlphabetical(f1: QuartzPluginData, f2: QuartzPluginData): number { export function byDateAndAlphabetical(
cfg: GlobalConfiguration,
): (f1: QuartzPluginData, f2: QuartzPluginData) => number {
return (f1, f2) => {
if (f1.dates && f2.dates) { if (f1.dates && f2.dates) {
// sort descending by last modified // sort descending
return f2.dates.modified.getTime() - f1.dates.modified.getTime() return getDate(cfg, f2)!.getTime() - getDate(cfg, f1)!.getTime()
} else if (f1.dates && !f2.dates) { } else if (f1.dates && !f2.dates) {
// prioritize files with dates // prioritize files with dates
return -1 return -1
@ -19,13 +23,14 @@ export function byDateAndAlphabetical(f1: QuartzPluginData, f2: QuartzPluginData
const f2Title = f2.frontmatter?.title.toLowerCase() ?? "" const f2Title = f2.frontmatter?.title.toLowerCase() ?? ""
return f1Title.localeCompare(f2Title) return f1Title.localeCompare(f2Title)
} }
}
type Props = { type Props = {
limit?: number limit?: number
} & QuartzComponentProps } & QuartzComponentProps
export function PageList({ fileData, allFiles, limit }: Props) { export function PageList({ cfg, fileData, allFiles, limit }: Props) {
let list = allFiles.sort(byDateAndAlphabetical) let list = allFiles.sort(byDateAndAlphabetical(cfg))
if (limit) { if (limit) {
list = list.slice(0, limit) list = list.slice(0, limit)
} }
@ -41,7 +46,7 @@ export function PageList({ fileData, allFiles, limit }: Props) {
<div class="section"> <div class="section">
{page.dates && ( {page.dates && (
<p class="meta"> <p class="meta">
<Date date={page.dates.modified} /> <Date date={getDate(cfg, page)!} />
</p> </p>
)} )}
<div class="desc"> <div class="desc">

View File

@ -3,7 +3,8 @@ import { FullSlug, SimpleSlug, resolveRelative } from "../util/path"
import { QuartzPluginData } from "../plugins/vfile" import { QuartzPluginData } from "../plugins/vfile"
import { byDateAndAlphabetical } from "./PageList" import { byDateAndAlphabetical } from "./PageList"
import style from "./styles/recentNotes.scss" import style from "./styles/recentNotes.scss"
import { Date } from "./Date" import { Date, getDate } from "./Date"
import { GlobalConfiguration } from "../cfg"
interface Options { interface Options {
title: string title: string
@ -13,18 +14,18 @@ interface Options {
sort: (f1: QuartzPluginData, f2: QuartzPluginData) => number sort: (f1: QuartzPluginData, f2: QuartzPluginData) => number
} }
const defaultOptions: Options = { const defaultOptions = (cfg: GlobalConfiguration): Options => ({
title: "Recent Notes", title: "Recent Notes",
limit: 3, limit: 3,
linkToMore: false, linkToMore: false,
filter: () => true, filter: () => true,
sort: byDateAndAlphabetical, sort: byDateAndAlphabetical(cfg),
} })
export default ((userOpts?: Partial<Options>) => { export default ((userOpts?: Partial<Options>) => {
const opts = { ...defaultOptions, ...userOpts }
function RecentNotes(props: QuartzComponentProps) { 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 pages = allFiles.filter(opts.filter).sort(opts.sort)
const remaining = Math.max(0, pages.length - opts.limit) const remaining = Math.max(0, pages.length - opts.limit)
return ( return (
@ -47,7 +48,7 @@ export default ((userOpts?: Partial<Options>) => {
</div> </div>
{page.dates && ( {page.dates && (
<p class="meta"> <p class="meta">
<Date date={page.dates.modified} /> <Date date={getDate(cfg, fileData)!} />
</p> </p>
)} )}
<ul class="tags"> <ul class="tags">

View File

@ -1,4 +1,5 @@
import { GlobalConfiguration } from "../../cfg" import { GlobalConfiguration } from "../../cfg"
import { getDate } from "../../components/Date"
import { FilePath, FullSlug, SimpleSlug, simplifySlug } from "../../util/path" import { FilePath, FullSlug, SimpleSlug, simplifySlug } from "../../util/path"
import { QuartzEmitterPlugin } from "../types" import { QuartzEmitterPlugin } from "../types"
import path from "path" import path from "path"
@ -74,7 +75,7 @@ export const ContentIndex: QuartzEmitterPlugin<Partial<Options>> = (opts) => {
const linkIndex: ContentIndex = new Map() const linkIndex: ContentIndex = new Map()
for (const [_tree, file] of content) { for (const [_tree, file] of content) {
const slug = file.data.slug! 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 !== "")) { if (opts?.includeEmptyFiles || (file.data.text && file.data.text !== "")) {
linkIndex.set(slug, { linkIndex.set(slug, {
title: file.data.frontmatter?.title!, title: file.data.frontmatter?.title!,