make layouts simpler to think about
This commit is contained in:
		
							parent
							
								
									45f9087f03
								
							
						
					
					
						commit
						cc79502670
					
				
					 8 changed files with 117 additions and 122 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue