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.
 | 
					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
 | 
					## Transformers
 | 
				
			||||||
export type QuartzTransformerPluginInstance = {
 | 
					 | 
				
			||||||
  name: string
 | 
					 | 
				
			||||||
  textTransform?: (src: string | Buffer) => string | Buffer
 | 
					 | 
				
			||||||
  markdownPlugins?: () => PluggableList
 | 
					 | 
				
			||||||
  htmlPlugins?: () => PluggableList
 | 
					 | 
				
			||||||
  externalResources?: () => Partial<StaticResources>
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Filters
 | 
					## 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
 | 
					### 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
 | 
					### Components
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,6 @@ draft: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- images in same folder are broken on shortest path mode
 | 
					- images in same folder are broken on shortest path mode
 | 
				
			||||||
- watch mode for config/source code
 | 
					- 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
 | 
					- 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
 | 
					- note/header/block transcludes: https://help.obsidian.md/Linking+notes+and+files/Embedding+files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
import { GlobalConfiguration, PageLayout, QuartzConfig } from "./quartz/cfg"
 | 
					import { QuartzConfig } from "./quartz/cfg"
 | 
				
			||||||
import * as Component from "./quartz/components"
 | 
					 | 
				
			||||||
import * as Plugin from "./quartz/plugins"
 | 
					import * as Plugin from "./quartz/plugins"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const generalConfiguration: GlobalConfiguration = {
 | 
					const config: QuartzConfig = {
 | 
				
			||||||
 | 
					  configuration: {
 | 
				
			||||||
    pageTitle: "🪴 Quartz 4.0",
 | 
					    pageTitle: "🪴 Quartz 4.0",
 | 
				
			||||||
    enableSPA: true,
 | 
					    enableSPA: true,
 | 
				
			||||||
    enablePopovers: true,
 | 
					    enablePopovers: true,
 | 
				
			||||||
| 
						 | 
					@ -40,44 +40,7 @@ const generalConfiguration: GlobalConfiguration = {
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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,
 | 
					 | 
				
			||||||
  plugins: {
 | 
					  plugins: {
 | 
				
			||||||
    transformers: [
 | 
					    transformers: [
 | 
				
			||||||
      Plugin.FrontMatter(),
 | 
					      Plugin.FrontMatter(),
 | 
				
			||||||
| 
						 | 
					@ -96,21 +59,9 @@ const config: QuartzConfig = {
 | 
				
			||||||
    emitters: [
 | 
					    emitters: [
 | 
				
			||||||
      Plugin.AliasRedirects(),
 | 
					      Plugin.AliasRedirects(),
 | 
				
			||||||
      Plugin.ComponentResources({ fontOrigin: "googleFonts" }),
 | 
					      Plugin.ComponentResources({ fontOrigin: "googleFonts" }),
 | 
				
			||||||
      Plugin.ContentPage({
 | 
					      Plugin.ContentPage(),
 | 
				
			||||||
        ...sharedPageComponents,
 | 
					      Plugin.FolderPage(),
 | 
				
			||||||
        ...contentPageLayout,
 | 
					      Plugin.TagPage(),
 | 
				
			||||||
        pageBody: Component.Content(),
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
      Plugin.FolderPage({
 | 
					 | 
				
			||||||
        ...sharedPageComponents,
 | 
					 | 
				
			||||||
        ...listPageLayout,
 | 
					 | 
				
			||||||
        pageBody: Component.FolderContent(),
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
      Plugin.TagPage({
 | 
					 | 
				
			||||||
        ...sharedPageComponents,
 | 
					 | 
				
			||||||
        ...listPageLayout,
 | 
					 | 
				
			||||||
        pageBody: Component.TagContent(),
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
      Plugin.ContentIndex({
 | 
					      Plugin.ContentIndex({
 | 
				
			||||||
        enableSiteMap: true,
 | 
					        enableSiteMap: true,
 | 
				
			||||||
        enableRSS: 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 { pageResources, renderPage } from "../../components/renderPage"
 | 
				
			||||||
import { FullPageLayout } from "../../cfg"
 | 
					import { FullPageLayout } from "../../cfg"
 | 
				
			||||||
import { FilePath, canonicalizeServer } from "../../path"
 | 
					import { FilePath, canonicalizeServer } from "../../path"
 | 
				
			||||||
 | 
					import { defaultContentPageLayout, sharedPageComponents } from "../../../quartz.layout"
 | 
				
			||||||
 | 
					import { Content } from "../../components"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ContentPage: QuartzEmitterPlugin<FullPageLayout> = (opts) => {
 | 
					export const ContentPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOpts) => {
 | 
				
			||||||
  if (!opts) {
 | 
					  const opts: FullPageLayout = {
 | 
				
			||||||
    throw new Error(
 | 
					    ...sharedPageComponents,
 | 
				
			||||||
      "ContentPage must be initialized with options specifiying the components to use",
 | 
					    ...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 Header = HeaderConstructor()
 | 
				
			||||||
  const Body = BodyConstructor()
 | 
					  const Body = BodyConstructor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    name: "ContentPage",
 | 
					    name: "ContentPage",
 | 
				
			||||||
    getQuartzComponents() {
 | 
					    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[]> {
 | 
					    async emit(ctx, content, resources, emit): Promise<FilePath[]> {
 | 
				
			||||||
      const cfg = ctx.cfg.configuration
 | 
					      const cfg = ctx.cfg.configuration
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,20 +7,25 @@ import { ProcessedContent, defaultProcessedContent } from "../vfile"
 | 
				
			||||||
import { FullPageLayout } from "../../cfg"
 | 
					import { FullPageLayout } from "../../cfg"
 | 
				
			||||||
import path from "path"
 | 
					import path from "path"
 | 
				
			||||||
import { CanonicalSlug, FilePath, ServerSlug, canonicalizeServer, joinSegments } 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) => {
 | 
					export const FolderPage: QuartzEmitterPlugin<FullPageLayout> = (userOpts) => {
 | 
				
			||||||
  if (!opts) {
 | 
					  const opts: FullPageLayout = {
 | 
				
			||||||
    throw new Error("ErrorPage must be initialized with options specifiying the components to use")
 | 
					    ...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 Header = HeaderConstructor()
 | 
				
			||||||
  const Body = BodyConstructor()
 | 
					  const Body = BodyConstructor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    name: "FolderPage",
 | 
					    name: "FolderPage",
 | 
				
			||||||
    getQuartzComponents() {
 | 
					    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[]> {
 | 
					    async emit(ctx, content, resources, emit): Promise<FilePath[]> {
 | 
				
			||||||
      const fps: FilePath[] = []
 | 
					      const fps: FilePath[] = []
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,20 +12,25 @@ import {
 | 
				
			||||||
  getAllSegmentPrefixes,
 | 
					  getAllSegmentPrefixes,
 | 
				
			||||||
  joinSegments,
 | 
					  joinSegments,
 | 
				
			||||||
} from "../../path"
 | 
					} from "../../path"
 | 
				
			||||||
 | 
					import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout"
 | 
				
			||||||
 | 
					import { TagContent } from "../../components"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TagPage: QuartzEmitterPlugin<FullPageLayout> = (opts) => {
 | 
					export const TagPage: QuartzEmitterPlugin<FullPageLayout> = (userOpts) => {
 | 
				
			||||||
  if (!opts) {
 | 
					  const opts: FullPageLayout = {
 | 
				
			||||||
    throw new Error("TagPage must be initialized with options specifiying the components to use")
 | 
					    ...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 Header = HeaderConstructor()
 | 
				
			||||||
  const Body = BodyConstructor()
 | 
					  const Body = BodyConstructor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    name: "TagPage",
 | 
					    name: "TagPage",
 | 
				
			||||||
    getQuartzComponents() {
 | 
					    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[]> {
 | 
					    async emit(ctx, content, resources, emit): Promise<FilePath[]> {
 | 
				
			||||||
      const fps: FilePath[] = []
 | 
					      const fps: FilePath[] = []
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue