diff --git a/quartz.config.ts b/quartz.config.ts
index 01412f91e..65539a84d 100644
--- a/quartz.config.ts
+++ b/quartz.config.ts
@@ -1,7 +1,9 @@
import { QuartzConfig } from "./quartz/cfg"
import Body from "./quartz/components/Body"
+import Darkmode from "./quartz/components/Darkmode"
import Head from "./quartz/components/Head"
-import Header from "./quartz/components/Header"
+import PageTitle from "./quartz/components/PageTitle"
+import Spacer from "./quartz/components/Spacer"
import {
ContentPage,
CreatedModifiedDate,
@@ -68,9 +70,9 @@ const config: QuartzConfig = {
],
emitters: [
new ContentPage({
- Head: Head,
- Header: Header,
- Body: Body
+ head: Head,
+ header: [PageTitle, Spacer, Darkmode],
+ body: Body
})
]
},
diff --git a/quartz/components/Body.tsx b/quartz/components/Body.tsx
index 1d9296b5e..92e66828a 100644
--- a/quartz/components/Body.tsx
+++ b/quartz/components/Body.tsx
@@ -1,15 +1,14 @@
-import { ComponentChildren } from "preact"
import clipboardScript from './scripts/clipboard.inline'
import clipboardStyle from './styles/clipboard.scss'
+import { QuartzComponentProps } from "./types"
-export interface BodyProps {
- title?: string
- children: ComponentChildren
-}
-
-export default function Body({ title, children }: BodyProps) {
+export default function Body({ fileData, children }: QuartzComponentProps) {
+ const title = fileData.frontmatter?.title
+ const displayTitle = fileData.slug === "index" ? undefined : title
return
- {title && {title}
}
+
+ {displayTitle &&
{displayTitle}
}
+
{children}
}
diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx
index 9e182c7f4..c56b8cbc0 100644
--- a/quartz/components/Head.tsx
+++ b/quartz/components/Head.tsx
@@ -1,18 +1,15 @@
import { resolveToRoot } from "../path"
-import { StaticResources } from "../resources"
+import { QuartzComponentProps } from "./types"
-export interface HeadProps {
- title: string
- description: string
- slug: string
- externalResources: StaticResources
-}
-
-export default function Head({ title, description, slug, externalResources }: HeadProps) {
+export default function Head({ fileData, externalResources }: QuartzComponentProps) {
+ const slug = fileData.slug!
+ const title = fileData.frontmatter?.title ?? "Untitled"
+ const description = fileData.description ?? "No description provided"
const { css, js } = externalResources
const baseDir = resolveToRoot(slug)
const iconPath = baseDir + "/static/icon.png"
const ogImagePath = baseDir + "/static/og-image.png"
+
return
{title}
diff --git a/quartz/components/Header.tsx b/quartz/components/Header.tsx
index 7005e64d0..8eb2d70df 100644
--- a/quartz/components/Header.tsx
+++ b/quartz/components/Header.tsx
@@ -1,20 +1,10 @@
-import { resolveToRoot } from "../path"
-import Darkmode from "./Darkmode"
import style from './styles/header.scss'
+import { QuartzComponentProps } from "./types"
-export interface HeaderProps {
- title: string
- slug: string
-}
-
-export default function Header({ title, slug }: HeaderProps) {
- const baseDir = resolveToRoot(slug)
+export default function Header({ children }: QuartzComponentProps) {
return
}
-Header.beforeDOMLoaded = Darkmode.beforeDOMLoaded
-Header.css = style + Darkmode.css
+Header.css = style
diff --git a/quartz/components/PageTitle.tsx b/quartz/components/PageTitle.tsx
new file mode 100644
index 000000000..080b74d1d
--- /dev/null
+++ b/quartz/components/PageTitle.tsx
@@ -0,0 +1,9 @@
+import { resolveToRoot } from "../path"
+import { QuartzComponentProps } from "./types"
+
+export default function({ cfg, fileData }: QuartzComponentProps) {
+ const title = cfg.siteTitle
+ const slug = fileData.slug!
+ const baseDir = resolveToRoot(slug)
+ return
+}
diff --git a/quartz/components/Spacer.tsx b/quartz/components/Spacer.tsx
new file mode 100644
index 000000000..02b10935e
--- /dev/null
+++ b/quartz/components/Spacer.tsx
@@ -0,0 +1,3 @@
+export default function() {
+ return
+}
diff --git a/quartz/components/types.ts b/quartz/components/types.ts
index 96ead5f90..8d7a79c1f 100644
--- a/quartz/components/types.ts
+++ b/quartz/components/types.ts
@@ -1,6 +1,16 @@
-import { ComponentType } from "preact"
+import { ComponentType, JSX } from "preact"
+import { StaticResources } from "../resources"
+import { QuartzPluginData } from "../plugins/vfile"
+import { GlobalConfiguration } from "../cfg"
-export type QuartzComponent = ComponentType & {
+export type QuartzComponentProps = {
+ externalResources: StaticResources
+ fileData: QuartzPluginData
+ cfg: GlobalConfiguration
+ children: QuartzComponent[] | JSX.Element[]
+}
+
+export type QuartzComponent = ComponentType & {
css?: string,
beforeDOMLoaded?: string,
afterDOMLoaded?: string,
diff --git a/quartz/plugins/emitters/contentPage.tsx b/quartz/plugins/emitters/contentPage.tsx
index c4b357c14..2ab914cd6 100644
--- a/quartz/plugins/emitters/contentPage.tsx
+++ b/quartz/plugins/emitters/contentPage.tsx
@@ -4,17 +4,16 @@ import { EmitCallback, QuartzEmitterPlugin } from "../types"
import { ProcessedContent } from "../vfile"
import { Fragment, jsx, jsxs } from 'preact/jsx-runtime'
import { render } from "preact-render-to-string"
-import { HeadProps } from "../../components/Head"
import { GlobalConfiguration } from "../../cfg"
-import { HeaderProps } from "../../components/Header"
import { QuartzComponent } from "../../components/types"
import { resolveToRoot } from "../../path"
-import { BodyProps } from "../../components/Body"
+import Header from "../../components/Header"
+import { QuartzComponentProps } from "../../components/types"
interface Options {
- Head: QuartzComponent
- Header: QuartzComponent
- Body: QuartzComponent
+ head: QuartzComponent
+ header: QuartzComponent[],
+ body: QuartzComponent
}
export class ContentPage extends QuartzEmitterPlugin {
@@ -26,21 +25,21 @@ export class ContentPage extends QuartzEmitterPlugin {
this.opts = opts
}
- getQuartzComponents(): QuartzComponent[] {
- return [...Object.values(this.opts)]
+ getQuartzComponents(): QuartzComponent[] {
+ return [this.opts.head, Header, ...this.opts.header, this.opts.body]
}
async emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emit: EmitCallback): Promise {
const fps: string[] = []
- const { Head, Header, Body } = this.opts
+ const { head: Head, header, body: Body } = this.opts
for (const [tree, file] of content) {
// @ts-ignore (preact makes it angry)
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
const baseDir = resolveToRoot(file.data.slug!)
const pageResources: StaticResources = {
- css: [baseDir + "/index.css", ...resources.css,],
+ css: [baseDir + "/index.css", ...resources.css],
js: [
{ src: baseDir + "/prescript.js", loadTime: "beforeDOMReady" },
...resources.js,
@@ -48,17 +47,23 @@ export class ContentPage extends QuartzEmitterPlugin {
]
}
- const title = file.data.frontmatter?.title
+ const componentData: QuartzComponentProps = {
+ fileData: file.data,
+ externalResources: pageResources,
+ cfg,
+ children: [content]
+ }
+
const doc =
-
+
-
- {content}
+
+ {header.map(HeaderComponent => )}
+
+
+ {content}
+
{pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(resource => )}
diff --git a/quartz/plugins/index.ts b/quartz/plugins/index.ts
index e904a00e8..01348c9e0 100644
--- a/quartz/plugins/index.ts
+++ b/quartz/plugins/index.ts
@@ -17,7 +17,7 @@ function joinScripts(scripts: string[]): string {
export function emitComponentResources(cfg: GlobalConfiguration, resources: StaticResources, plugins: PluginTypes, emit: EmitCallback) {
const fps: string[] = []
- const allComponents: Set> = new Set()
+ const allComponents: Set = new Set()
for (const emitter of plugins.emitters) {
const components = emitter.getQuartzComponents()
for (const component of components) {
diff --git a/quartz/plugins/transformers/description.ts b/quartz/plugins/transformers/description.ts
index 065d3bfe1..fa597993b 100644
--- a/quartz/plugins/transformers/description.ts
+++ b/quartz/plugins/transformers/description.ts
@@ -29,7 +29,9 @@ export class Description extends QuartzTransformerPlugin {
() => {
return async (tree: HTMLRoot, file) => {
const frontMatterDescription = file.data.frontmatter?.description
- const desc = frontMatterDescription ?? toString(tree)
+ const text = toString(tree)
+
+ const desc = frontMatterDescription ?? text
const sentences = desc.replace(/\s+/g, ' ').split('.')
let finalDesc = ""
let sentenceIdx = 0
@@ -40,6 +42,7 @@ export class Description extends QuartzTransformerPlugin {
}
file.data.description = finalDesc
+ file.data.text = text
}
}
]
@@ -49,6 +52,7 @@ export class Description extends QuartzTransformerPlugin {
declare module 'vfile' {
interface DataMap {
description: string
+ text: string
}
}
diff --git a/quartz/plugins/types.ts b/quartz/plugins/types.ts
index 80d6ceebc..11b07dbe1 100644
--- a/quartz/plugins/types.ts
+++ b/quartz/plugins/types.ts
@@ -26,7 +26,7 @@ export type EmitCallback = (data: EmitOptions) => Promise
export abstract class QuartzEmitterPlugin {
abstract name: string
abstract emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emitCallback: EmitCallback): Promise
- abstract getQuartzComponents(): QuartzComponent[]
+ abstract getQuartzComponents(): QuartzComponent[]
}
export interface PluginTypes {