make layouts simpler to think about

This commit is contained in:
Jacky Zhao 2023-07-25 23:37:24 -07:00
parent 45f9087f03
commit cc79502670
8 changed files with 117 additions and 122 deletions

View File

@ -4,17 +4,9 @@ title: Making your own plugins
This part of the documentation will assume you have some basic coding knowledge and will include code snippets that describe the interface of what Quartz plugins should look like.
## Transformers
![[quartz-transform-pipeline.png]]
```ts
export type QuartzTransformerPluginInstance = {
name: string
textTransform?: (src: string | Buffer) => string | Buffer
markdownPlugins?: () => PluggableList
htmlPlugins?: () => PluggableList
externalResources?: () => Partial<StaticResources>
}
```
## Transformers
## Filters

View File

@ -75,8 +75,10 @@ transformers: [
]
```
If you'd like to make your own plugins, read the guide on [[making plugins]] for more information.
### Layout
Certain emitters may also output [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) files. To make sure that
Certain emitters may also output [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) files. To enable easy customization, these emitters allow you to fully rearrange the layout of the page.
### Components

View File

@ -6,8 +6,6 @@ draft: true
- images in same folder are broken on shortest path mode
- watch mode for config/source code
- publish metadata https://help.obsidian.md/Editing+and+formatting/Metadata#Metadata+for+Obsidian+Publish
- metadata aliases: https://help.obsidian.md/Editing+and+formatting/Metadata#Predefined+metadata
- block links: https://help.obsidian.md/Linking+notes+and+files/Internal+links#Link+to+a+block+in+a+note
- note/header/block transcludes: https://help.obsidian.md/Linking+notes+and+files/Embedding+files

View File

@ -1,83 +1,46 @@
import { GlobalConfiguration, PageLayout, QuartzConfig } from "./quartz/cfg"
import * as Component from "./quartz/components"
import { QuartzConfig } from "./quartz/cfg"
import * as Plugin from "./quartz/plugins"
const generalConfiguration: GlobalConfiguration = {
pageTitle: "🪴 Quartz 4.0",
enableSPA: true,
enablePopovers: true,
analytics: {
provider: "plausible",
},
baseUrl: "quartz.jzhao.xyz",
ignorePatterns: ["private", "templates"],
theme: {
typography: {
header: "Schibsted Grotesk",
body: "Source Sans Pro",
code: "IBM Plex Mono",
},
colors: {
lightMode: {
light: "#faf8f8",
lightgray: "#e5e5e5",
gray: "#b8b8b8",
darkgray: "#4e4e4e",
dark: "#2b2b2b",
secondary: "#284b63",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
},
darkMode: {
light: "#161618",
lightgray: "#393639",
gray: "#646464",
darkgray: "#d4d4d4",
dark: "#ebebec",
secondary: "#7b97aa",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
},
},
},
}
const sharedPageComponents = {
head: Component.Head(),
header: [],
footer: Component.Footer({
links: {
GitHub: "https://github.com/jackyzha0/quartz",
"Discord Community": "https://discord.gg/cRFFHYye7t",
},
}),
}
const contentPageLayout: PageLayout = {
beforeBody: [Component.ArticleTitle(), Component.ReadingTime(), Component.TagList()],
left: [
Component.PageTitle(),
Component.MobileOnly(Component.Spacer()),
Component.Search(),
Component.Darkmode(),
Component.DesktopOnly(Component.TableOfContents()),
],
right: [Component.Graph(), Component.Backlinks()],
}
const listPageLayout: PageLayout = {
beforeBody: [Component.ArticleTitle()],
left: [
Component.PageTitle(),
Component.MobileOnly(Component.Spacer()),
Component.Search(),
Component.Darkmode(),
],
right: [],
}
const config: QuartzConfig = {
configuration: generalConfiguration,
configuration: {
pageTitle: "🪴 Quartz 4.0",
enableSPA: true,
enablePopovers: true,
analytics: {
provider: "plausible",
},
baseUrl: "quartz.jzhao.xyz",
ignorePatterns: ["private", "templates"],
theme: {
typography: {
header: "Schibsted Grotesk",
body: "Source Sans Pro",
code: "IBM Plex Mono",
},
colors: {
lightMode: {
light: "#faf8f8",
lightgray: "#e5e5e5",
gray: "#b8b8b8",
darkgray: "#4e4e4e",
dark: "#2b2b2b",
secondary: "#284b63",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
},
darkMode: {
light: "#161618",
lightgray: "#393639",
gray: "#646464",
darkgray: "#d4d4d4",
dark: "#ebebec",
secondary: "#7b97aa",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
},
},
},
},
plugins: {
transformers: [
Plugin.FrontMatter(),
@ -96,21 +59,9 @@ const config: QuartzConfig = {
emitters: [
Plugin.AliasRedirects(),
Plugin.ComponentResources({ fontOrigin: "googleFonts" }),
Plugin.ContentPage({
...sharedPageComponents,
...contentPageLayout,
pageBody: Component.Content(),
}),
Plugin.FolderPage({
...sharedPageComponents,
...listPageLayout,
pageBody: Component.FolderContent(),
}),
Plugin.TagPage({
...sharedPageComponents,
...listPageLayout,
pageBody: Component.TagContent(),
}),
Plugin.ContentPage(),
Plugin.FolderPage(),
Plugin.TagPage(),
Plugin.ContentIndex({
enableSiteMap: true,
enableRSS: true,

39
quartz.layout.ts Normal file
View File

@ -0,0 +1,39 @@
import { PageLayout } from "./quartz/cfg"
import * as Component from "./quartz/components"
// components shared across all pages
export const sharedPageComponents = {
head: Component.Head(),
header: [],
footer: Component.Footer({
links: {
GitHub: "https://github.com/jackyzha0/quartz",
"Discord Community": "https://discord.gg/cRFFHYye7t",
},
}),
}
// components for pages that display a single page (e.g. a single note)
export const defaultContentPageLayout: PageLayout = {
beforeBody: [Component.ArticleTitle(), Component.ReadingTime(), Component.TagList()],
left: [
Component.PageTitle(),
Component.MobileOnly(Component.Spacer()),
Component.Search(),
Component.Darkmode(),
Component.DesktopOnly(Component.TableOfContents()),
],
right: [Component.Graph(), Component.Backlinks()],
}
// components for pages that display lists of pages (e.g. tags or folders)
export const defaultListPageLayout: PageLayout = {
beforeBody: [Component.ArticleTitle()],
left: [
Component.PageTitle(),
Component.MobileOnly(Component.Spacer()),
Component.Search(),
Component.Darkmode(),
],
right: [],
}

View File

@ -5,22 +5,25 @@ import BodyConstructor from "../../components/Body"
import { pageResources, renderPage } from "../../components/renderPage"
import { FullPageLayout } from "../../cfg"
import { FilePath, canonicalizeServer } from "../../path"
import { defaultContentPageLayout, sharedPageComponents } from "../../../quartz.layout"
import { Content } from "../../components"
export const ContentPage: QuartzEmitterPlugin<FullPageLayout> = (opts) => {
if (!opts) {
throw new Error(
"ContentPage must be initialized with options specifiying the components to use",
)
export const ContentPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOpts) => {
const opts: FullPageLayout = {
...sharedPageComponents,
...defaultContentPageLayout,
pageBody: Content(),
...userOpts,
}
const { head: Head, header, beforeBody, pageBody: Content, left, right, footer: Footer } = opts
const { head: Head, header, beforeBody, pageBody, left, right, footer: Footer } = opts
const Header = HeaderConstructor()
const Body = BodyConstructor()
return {
name: "ContentPage",
getQuartzComponents() {
return [Head, Header, Body, ...header, ...beforeBody, Content, ...left, ...right, Footer]
return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer]
},
async emit(ctx, content, resources, emit): Promise<FilePath[]> {
const cfg = ctx.cfg.configuration

View File

@ -7,20 +7,25 @@ import { ProcessedContent, defaultProcessedContent } from "../vfile"
import { FullPageLayout } from "../../cfg"
import path from "path"
import { CanonicalSlug, FilePath, ServerSlug, canonicalizeServer, joinSegments } from "../../path"
import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout"
import { FolderContent } from "../../components"
export const FolderPage: QuartzEmitterPlugin<FullPageLayout> = (opts) => {
if (!opts) {
throw new Error("ErrorPage must be initialized with options specifiying the components to use")
export const FolderPage: QuartzEmitterPlugin<FullPageLayout> = (userOpts) => {
const opts: FullPageLayout = {
...sharedPageComponents,
...defaultListPageLayout,
pageBody: FolderContent(),
...userOpts,
}
const { head: Head, header, beforeBody, pageBody: Content, left, right, footer: Footer } = opts
const { head: Head, header, beforeBody, pageBody, left, right, footer: Footer } = opts
const Header = HeaderConstructor()
const Body = BodyConstructor()
return {
name: "FolderPage",
getQuartzComponents() {
return [Head, Header, Body, ...header, ...beforeBody, Content, ...left, ...right, Footer]
return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer]
},
async emit(ctx, content, resources, emit): Promise<FilePath[]> {
const fps: FilePath[] = []

View File

@ -12,20 +12,25 @@ import {
getAllSegmentPrefixes,
joinSegments,
} from "../../path"
import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout"
import { TagContent } from "../../components"
export const TagPage: QuartzEmitterPlugin<FullPageLayout> = (opts) => {
if (!opts) {
throw new Error("TagPage must be initialized with options specifiying the components to use")
export const TagPage: QuartzEmitterPlugin<FullPageLayout> = (userOpts) => {
const opts: FullPageLayout = {
...sharedPageComponents,
...defaultListPageLayout,
pageBody: TagContent(),
...userOpts,
}
const { head: Head, header, beforeBody, pageBody: Content, left, right, footer: Footer } = opts
const { head: Head, header, beforeBody, pageBody, left, right, footer: Footer } = opts
const Header = HeaderConstructor()
const Body = BodyConstructor()
return {
name: "TagPage",
getQuartzComponents() {
return [Head, Header, Body, ...header, ...beforeBody, Content, ...left, ...right, Footer]
return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer]
},
async emit(ctx, content, resources, emit): Promise<FilePath[]> {
const fps: FilePath[] = []