make layouts simpler to think about
This commit is contained in:
parent
93c4d4358d
commit
de372b4471
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
135
quartz.config.ts
135
quartz.config.ts
@ -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
39
quartz.layout.ts
Normal 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: [],
|
||||
}
|
@ -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
|
||||
|
@ -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[] = []
|
||||
|
@ -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[] = []
|
||||
|
Loading…
Reference in New Issue
Block a user