mirror of
https://github.com/jackyzha0/quartz.git
synced 2026-03-21 13:35:42 -05:00
feat(v5): add plugin system (#2295)
* feat(plugins): v5 plugin system * feat(plugins): explorer as community plugin * feat(plugins): graph as community plugin * chore: update package-lock.json * chore: update package-lock.json * docs: updated plugin-specific docs * chore: update package-lock.json * chore: update package-lock.json * chore: update package-lock.json * Implement Git-based plugin system with dogfooding for community plugins - Remove npm dependencies for @quartz-community/* plugins - Add gitLoader.ts for installing plugins from GitHub - Update quartz.layout.ts to import from .quartz/plugins/ - Add install-plugins.ts script for prebuild hook - Add .quartz/ to .gitignore * Add comprehensive Git-based plugin CLI with lockfile support - Create quartz.lock.json format for tracking exact plugin commits - Add 'npx quartz plugin' commands: install, add, remove, update, list, restore - Plugin state is fully reproducible via lockfile - No npm dependencies required for community plugins * Fix TypeScript errors in git-installed plugins - Install @quartz-community/types as devDependency - Fix plugin imports to define types locally - Fix search inline script fetchData bug - Format code with prettier * fix(types): install types from github * docs: updated plugin-specific docs * Update Dockerfile and add CI/CD documentation - Add plugin install step to Dockerfile - Create docs/ci-cd.md with pipeline configuration guide * Update GitHub Actions workflows for v5 branch and Git-based plugins - Change branch references from v4 to v5 - Add plugin caching to speed up builds - Use 'npx quartz plugin install' instead of 'restore' - Update Docker workflow branch trigger * Update quartz.lock.json with fixed plugin versions * fix(docker): install command * docs: add plugin migration analysis document Comprehensive analysis of which Quartz v4 components and plugins can be migrated to separate repositories, including: - Component analysis (25 components) - Plugin analysis (transformers, emitters, filters) - Migration strategies for different plugin types - Lessons learned from Explorer/Graph/Search migrations - Recommended migration order * chore: updated plugins * chore: updated plugins * chore: updated dependencies * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: tsconfig * feat: build installed plugins * chore: updated plugins * chore: updated plugins * chore: update explorer plugin with duplication fix * docs: Quartz v5 * chore: update graph plugin with navigation fix * fix: update explorer plugin with toggle fix * fix: update explorer plugin - ensure toggle buttons always work * fix: create plugin components once to prevent duplicate script registration * chore: updated plugins * chore: updated plugins * feat: migrate 7 feature components to community plugins (Phase B) Migrate ArticleTitle, TagList, PageTitle, Darkmode, ReaderMode, ContentMeta, and Footer from internal components to community plugins. Update layout to use Plugin.X() pattern, remove internal component files and their styles/scripts. Add MIGRATION_TASKS.md documenting the full migration roadmap. * chore: updated plugins * refactor: delete 6 internal component duplicates (Phase A) Remove Backlinks, Breadcrumbs, RecentNotes, Search, TableOfContents, Comments, and OverflowList — all replaced by community plugins. Delete associated styles (6) and scripts (3). Switch layout to use Plugin.Breadcrumbs() instead of Component.Breadcrumbs(). * refactor: unify QuartzComponent type to structural interface (Phase C) - Changed QuartzComponent from ComponentType<QuartzComponentProps> to callable type ((props: QuartzComponentProps) => any) - Added optional displayName property for better debugging - Removed ComponentType import from preact - Removed all 13 'as QuartzComponent' type casts from quartz.layout.ts - Community plugin components now directly assignable without casts * feat: add PageType plugin infrastructure (Phase D Step 4) * feat: add PageTypePluginEntry for cross-boundary type compatibility Introduce PageTypePluginEntry with never[] parameter types to accept both internal and community PageType plugins in config arrays without casts, working around branded FullSlug contravariance mismatch. * refactor: update dispatcher to cast PageTypePluginEntry at boundary Add getPageTypes() helper that casts config's PageTypePluginEntry[] to QuartzPageTypePluginInstance[] in one place. Cast VirtualPage.slug to FullSlug at emitPage/defaultProcessedContent call sites. * feat: integrate community PageType plugins (Phase D Step 6) Replace old page-rendering emitters with PageTypeDispatcher emitter and pageTypes array. Restructure quartz.layout.ts from three separate exports to unified layout object with defaults and byPageType record. Install content-page, folder-page, tag-page community plugins. * refactor: delete old page-rendering emitters Remove ContentPage, FolderPage, TagPage, and NotFoundPage emitters now replaced by community PageType plugins and the PageTypeDispatcher. * refactor: remove migrated page body components Delete Content, FolderContent, TagContent page components now provided by community PageType plugins. Update components barrel export. * fix: update lockfile to fixed folder-page and tag-page commits Points to commits that remove duplicate PageList/SortFn re-exports, fixing TS2300 duplicate identifier errors in generated plugin index. * chore: updated plugins * fix: populate ctx.trie in PageTypeDispatcher before rendering Components like FolderContent depend on ctx.trie for folder hierarchy. The dispatcher now lazily initializes it via trieFromAllFiles in emit and force-rebuilds it in partialEmit to reflect file changes. * chore: update lockfile to fixed folder-page commit * chore: updated plugins * chore: update explorer plugin to fix SPA folder navigation * feat: extract transformers to community plugins and fix type compatibility - Delete 12 internal transformer files (keep FrontMatter as internal) - Switch quartz.config.ts to use ExternalPlugin.* for all transformers - Align branded types with @quartz-community/types (_brand, FullSlug etc.) - Add vfile DataMap augmentations for fields from extracted transformers - Update all 29 plugins to @quartz-community/types v0.2.1 * Migrate filters to external plugins (remove-draft, explicit-publish) Delete internal RemoveDrafts and ExplicitPublish filter implementations, install them as community plugins, and update quartz.config.ts to use ExternalPlugin.RemoveDrafts(). * Migrate emitters to external plugins (alias-redirects, cname, favicon, content-index, og-image) * refactor: remove inline scripts/styles migrated to plugins Delete dead code: callout, checkbox, mermaid inline scripts and styles are now bundled by the obsidian-flavored-markdown plugin. Clipboard script and styles moved to the syntax-highlighting plugin. listPage.scss was unreferenced. Body.tsx simplified to a pure layout wrapper. * refactor: consolidate utils to re-export from @quartz-community/utils * fix: use dangerouslySetInnerHTML for inline CSS to prevent HTML-escaping Preact was escaping & characters in SCSS-compiled CSS (e.g. & nesting) into &, breaking CSS rules. Using dangerouslySetInnerHTML bypasses the escaping, matching how browsers expect style element content. * chore: update plugins with inline script transpilation fix * chore: updated plugins * docs: update plugin API sections for v5 community plugins * docs: rewrite documentation for v5 plugin system Update feature docs, hosting, CI/CD, getting started, configuration, layout, architecture, creating components, making plugins, and migration guide to reflect the v5 community plugin architecture. * docs: fix outdated v4 references in documentation * chore: remove completed migration planning docs * chore: updated plugins * chore: cleanup * chore: cleanup * chore: bump version to 5.0.0 * chore: updated dependencies * feat: integrate CanvasPage plugin with types, assets, config, layout, and documentation * chore: updated dependencies * chore: updated dependencies * chore: updated linter * chore: update canvas-page plugin to c942fcb * chore: updated plugins * chore: update canvas-page plugin to f88f1b9 * chore: updated plugins * chore: update canvas-page plugin to 079304c * chore: updated plugins * chore: canvas layout * chore: update canvas-page plugin to 38d49e1 * chore: updated plugins * chore: update canvas-page plugin to 505c099 * chore: updated plugins * chore: updated plugins * fix: Obsidian flavored markdown * fix: Obsidian flavored markdown * fix: Obsidian flavored markdown * chore: cleanup * chore: updated plugins * feat: configuration files * feat: Quartz TUI * feat(tui): YAML configuration * chore: tsup * chore: tsup * feat: support array categories in plugin manifests Plugins like note-properties export both transformer and component functionality. Allow PluginManifest.category to be a single value or an array, with config-loader resolving to the first processing category (transformer/filter/emitter/pageType) for dispatch. * refactor: remove built-in FrontMatter transformer Frontmatter processing is now handled by the note-properties plugin, which provides the same YAML/TOML parsing plus link extraction and a visual properties panel. The built-in transformer is no longer needed. * feat: add note-properties plugin to default configuration Register note-properties as the first plugin (order 5) in both the user config and the default config. Placed in beforeBody layout zone with priority 15 (between article-title at 10 and content-meta at 20). * docs: add plugin management strategy and syncer v5 notes Document the plugin management system design decisions and provide implementation guidance for the Quartz Syncer v5 integration. * feat: add bases-page plugin to default configuration Enable Obsidian Bases (.base) file support with bases page type and layout entry in both user and default config. * docs: update syncer notes with bases-page, note-properties, and spacer Add all three new plugins to the quick reference table (40 total). Add content, canvas, and bases page types to byPageType documentation. * chore: updated plugins * fix: update CI to Node 24 and regenerate lockfiles for clean install * fix: resolve type errors for CI checks * chore: updated plugins * chore: updated plugins * fix: plugin mapping from configuration * fix: CI * fix: CI * docs: rewrite Frontmatter documentation for note-properties plugin * chore: updated plugins * docs: Quartz v5 * chore: updated plugins * chore: updated plugins * refactor: extract TUI to standalone plugin repository * chore: linting * docs: Quartz v5 * feat: update and upgrade commands * chore: updated plugins * chore: updated plugins * chore: cleanup * chore: cleanup * chore: cleanup * chore: cleanup * chore: cleanup * fix: layout group priority * fix: view classes * fix: include virtual pages in content index for explorer visibility * docs: add board, gallery, and cards view examples to navigation page * chore: updated plugins * fix: include virtualPages in worker serializable build context * fix: set relativePath on virtual pages to prevent explorer crash * fix: exclude 404 * fix(links): virtual page links * fix(links): virtual page transclusion * docs: architecture overview * fix: only call scripts one per page * fix: type error in component registry instantiate method * fix: left layout order * fix(layout): remove tag-list by default * docs(plugins): updated plugin list defaults * fix(layout): priorities * feat: add PageFrame system for custom page layouts * feat: integrate PageFrame into rendering pipeline * feat: add frame resolution to page type dispatcher and config loader * style: add CSS grid overrides for full-width and minimal page frames * feat: set minimal frame for 404 and update canvas-page plugin * docs: add PageFrame system to architecture overview * fix: wrap frame.render() in array to satisfy Body children type * chore: format * fix: use absolute asset paths for 404 page so it works in subdirectories * fix(layout): priorities * docs: page frames * feat: add FrameRegistry for plugin-provided page frames Plugins can now register custom page frames via their manifest's 'frames' field. Frames are loaded alongside components during plugin initialization and resolved by name at render time with fallback to built-in frames. * feat(layout): page frames * fix(layout): linting * fix: inject frame CSS into page so plugin-provided frames render correctly * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * docs: canvas * chore: updated plugins * chore: updated plugins * chore: updated plugins * feat: add TreeTransform hook, fix multi-category plugins, and resolve cross-plugin dependencies - Add TreeTransform type and treeTransforms hook to pageType plugins, enabling render-time HAST tree mutations (e.g. bases-page inline codeblock resolution) - Fix config-loader to push multi-category plugins into ALL matching processing buckets instead of only the first match - Add side-effect import for component-only plugins so view registrations (e.g. leaflet-map via globalThis ViewRegistry) execute at load time - Add npm prune --omit=dev and cross-plugin peer dependency symlinking to buildPlugin() to prevent duplicate-singleton issues from nested node_modules * chore: format * chore: test docs * chore: updated plugins * fix: prevent HTML-escaping of inline style and script content in htmlToJsx Add dangerouslySetInnerHTML overrides for <style> and <script> elements so that CSS/JS injected by tree transforms is not HTML-escaped during preact-render-to-string serialization. * chore: update plugin lockfile for htmlToJsx migration * chore: update leaflet-map plugin (fix deferred L.Control) * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: updated plugins * chore: test npx quartz upgrade * feat(templates): add obsidian, ttrpg, blog templates * docs: move bases * docs: removed leaflet demo * feat(cli): configure baseUrl during create * docs: updated cli commands * docs: updated documentation for v5 * feat(cli): prune and resolve * chore: rebuild lockfile * docs: cli documentation * docs: plugin development and setup guide * chore: deleted redundant files * fix(build): fallback config * chore: updated lockfile * docs: removed outdated v3 setup * feat(cli): allow non-default branch plugins * docs: install branch commands * feat(cli): allow local plugins * docs: install local commands * feat: add render event type and listener for in-place DOM re-initialization * docs: add EncryptedPages plugin documentation * docs: add encrypted pages live demo page - New password-protected demo page (password: quartz) showing the plugin in action - Link to demo from EncryptedPages plugin page with password hint callout * feat: add encrypted-pages plugin to all templates - Enabled by default in default, obsidian, and ttrpg templates - Disabled by default in blog template * chore: updated plugins * chore: updated layouts * chore: updated plugins * feat: stacked pages * feat: added stacked page panes * docs: touch-ups
This commit is contained in:
parent
bc99b4a636
commit
ab346fa66a
11
.github/workflows/build-preview.yaml
vendored
11
.github/workflows/build-preview.yaml
vendored
@ -28,8 +28,19 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
- name: Cache Quartz plugins
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .quartz/plugins
|
||||
key: ${{ runner.os }}-plugins-${{ hashFiles('quartz.lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-plugins-
|
||||
|
||||
- run: npm ci
|
||||
|
||||
- name: Install Quartz plugins
|
||||
run: npx quartz plugin install
|
||||
|
||||
- name: Check types and style
|
||||
run: npm run check
|
||||
|
||||
|
||||
21
.github/workflows/ci.yaml
vendored
21
.github/workflows/ci.yaml
vendored
@ -3,10 +3,10 @@ name: Build and Test
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- v4
|
||||
- v5
|
||||
push:
|
||||
branches:
|
||||
- v4
|
||||
- v5
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@ -26,7 +26,7 @@ jobs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v5
|
||||
@ -36,8 +36,19 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
- name: Cache Quartz plugins
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .quartz/plugins
|
||||
key: ${{ runner.os }}-plugins-${{ hashFiles('quartz.lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-plugins-
|
||||
|
||||
- run: npm ci
|
||||
|
||||
- name: Install Quartz plugins
|
||||
run: npx quartz plugin install
|
||||
|
||||
- name: Check types and style
|
||||
run: npm run check
|
||||
|
||||
@ -48,7 +59,7 @@ jobs:
|
||||
run: npx quartz build --bundleInfo -d docs
|
||||
|
||||
publish-tag:
|
||||
if: ${{ github.repository == 'jackyzha0/quartz' && github.ref == 'refs/heads/v4' }}
|
||||
if: ${{ github.repository == 'jackyzha0/quartz' && github.ref == 'refs/heads/v5' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
@ -59,7 +70,7 @@ jobs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
- name: Get package version
|
||||
run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV
|
||||
- name: Create release tag
|
||||
|
||||
4
.github/workflows/docker-build-push.yaml
vendored
4
.github/workflows/docker-build-push.yaml
vendored
@ -2,10 +2,10 @@ name: Docker build & push image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [v4]
|
||||
branches: [v5]
|
||||
tags: ["v*"]
|
||||
pull_request:
|
||||
branches: [v4]
|
||||
branches: [v5]
|
||||
paths:
|
||||
- .github/workflows/docker-build-push.yaml
|
||||
- quartz/**
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,3 +9,5 @@ tsconfig.tsbuildinfo
|
||||
private/
|
||||
.replit
|
||||
replit.nix
|
||||
.quartz/
|
||||
quartz/cli/tui/dist/
|
||||
|
||||
16
.prettierrc
16
.prettierrc
@ -3,5 +3,19 @@
|
||||
"quoteProps": "as-needed",
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 2,
|
||||
"semi": false
|
||||
"semi": false,
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.canvas",
|
||||
"options": {
|
||||
"parser": "json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": "*.base",
|
||||
"options": {
|
||||
"parser": "yaml"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -2,7 +2,9 @@ FROM node:22-slim AS builder
|
||||
WORKDIR /usr/src/app
|
||||
COPY package.json .
|
||||
COPY package-lock.json* .
|
||||
RUN npm ci
|
||||
COPY quartz/ ./quartz/
|
||||
COPY quartz.lock.json .
|
||||
RUN npm ci; npx quartz plugin install
|
||||
|
||||
FROM node:22-slim
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Quartz v4
|
||||
# Quartz v5
|
||||
|
||||
> “[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming
|
||||
|
||||
|
||||
124
docs/Base.base
Normal file
124
docs/Base.base
Normal file
@ -0,0 +1,124 @@
|
||||
filters:
|
||||
and:
|
||||
- file.ext == "md"
|
||||
formulas:
|
||||
doc_type: |
|
||||
if(file.hasTag("plugin/transformer"), "transformer",
|
||||
if(file.hasTag("plugin/emitter"), "emitter",
|
||||
if(file.hasTag("plugin/filter"), "filter",
|
||||
if(file.hasTag("component"), "component",
|
||||
if(file.inFolder("features"), "feature",
|
||||
if(file.inFolder("advanced"), "advanced",
|
||||
if(file.inFolder("plugins"), "plugin",
|
||||
if(file.inFolder("getting-started"), "getting-started",
|
||||
if(file.inFolder("cli"), "cli", "guide")))))))))
|
||||
last_modified: file.mtime.relative()
|
||||
section: |
|
||||
if(file.inFolder("plugins"), "plugins",
|
||||
if(file.inFolder("features"), "features",
|
||||
if(file.inFolder("advanced"), "advanced",
|
||||
if(file.inFolder("getting-started"), "getting-started",
|
||||
if(file.inFolder("cli"), "cli",
|
||||
if(file.inFolder("tags"), "tags", "core"))))))
|
||||
properties:
|
||||
title:
|
||||
displayName: Title
|
||||
formula.doc_type:
|
||||
displayName: Type
|
||||
formula.last_modified:
|
||||
displayName: Updated
|
||||
formula.section:
|
||||
displayName: Section
|
||||
views:
|
||||
- type: table
|
||||
name: All Documentation
|
||||
groupBy:
|
||||
property: formula.section
|
||||
direction: ASC
|
||||
order:
|
||||
- file.name
|
||||
- title
|
||||
- formula.doc_type
|
||||
- formula.section
|
||||
- formula.last_modified
|
||||
sort:
|
||||
- property: formula.doc_type
|
||||
direction: ASC
|
||||
- property: file.name
|
||||
direction: ASC
|
||||
columnSize:
|
||||
file.name: 185
|
||||
note.title: 268
|
||||
formula.doc_type: 146
|
||||
formula.section: 276
|
||||
- type: table
|
||||
name: Plugins
|
||||
filters:
|
||||
or:
|
||||
- file.hasTag("plugin/transformer")
|
||||
- file.hasTag("plugin/emitter")
|
||||
- file.hasTag("plugin/filter")
|
||||
groupBy:
|
||||
property: formula.doc_type
|
||||
direction: ASC
|
||||
order:
|
||||
- file.name
|
||||
- title
|
||||
- formula.doc_type
|
||||
- formula.last_modified
|
||||
- type: table
|
||||
name: Components & Features
|
||||
filters:
|
||||
or:
|
||||
- file.hasTag("component")
|
||||
- file.inFolder("features")
|
||||
order:
|
||||
- file.name
|
||||
- title
|
||||
- formula.doc_type
|
||||
- formula.last_modified
|
||||
- type: list
|
||||
name: Recently Updated
|
||||
order:
|
||||
- file.name
|
||||
- formula.last_modified
|
||||
limit: 15
|
||||
- type: table
|
||||
name: Core Guides
|
||||
filters:
|
||||
not:
|
||||
- file.inFolder("plugins")
|
||||
- file.inFolder("features")
|
||||
- file.inFolder("advanced")
|
||||
- file.inFolder("getting-started")
|
||||
- file.inFolder("cli")
|
||||
- file.inFolder("tags")
|
||||
order:
|
||||
- file.name
|
||||
- title
|
||||
- formula.last_modified
|
||||
- type: board
|
||||
name: By Type (Board)
|
||||
groupBy:
|
||||
property: formula.doc_type
|
||||
direction: ASC
|
||||
order:
|
||||
- file.name
|
||||
- title
|
||||
- formula.last_modified
|
||||
- type: gallery
|
||||
name: Gallery
|
||||
order:
|
||||
- title
|
||||
- formula.doc_type
|
||||
- formula.section
|
||||
limit: 30
|
||||
- type: cards
|
||||
name: Cards
|
||||
order:
|
||||
- file.name
|
||||
- title
|
||||
- formula.doc_type
|
||||
- formula.section
|
||||
- formula.last_modified
|
||||
limit: 24
|
||||
321
docs/Canvas.canvas
Normal file
321
docs/Canvas.canvas
Normal file
@ -0,0 +1,321 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "group-node-types",
|
||||
"type": "group",
|
||||
"x": -30,
|
||||
"y": 260,
|
||||
"width": 1220,
|
||||
"height": 460,
|
||||
"color": "6",
|
||||
"label": "Node Types"
|
||||
},
|
||||
{
|
||||
"id": "group-config",
|
||||
"type": "group",
|
||||
"x": -30,
|
||||
"y": 1180,
|
||||
"width": 1220,
|
||||
"height": 360,
|
||||
"color": "2",
|
||||
"label": "Configuration"
|
||||
},
|
||||
{
|
||||
"id": "group-colors",
|
||||
"type": "group",
|
||||
"x": -30,
|
||||
"y": 790,
|
||||
"width": 1220,
|
||||
"height": 320,
|
||||
"color": "4",
|
||||
"label": "Preset Colors"
|
||||
},
|
||||
{
|
||||
"id": "group-edges",
|
||||
"type": "group",
|
||||
"x": -30,
|
||||
"y": 1610,
|
||||
"width": 1220,
|
||||
"height": 320,
|
||||
"color": "3",
|
||||
"label": "Edges & Connections"
|
||||
},
|
||||
{
|
||||
"id": "title",
|
||||
"type": "text",
|
||||
"text": "# CanvasPage Plugin\n\nThis plugin renders [JSON Canvas](https://jsoncanvas.org) (`.canvas`) files as interactive, pannable and zoomable canvas pages. It supports the full [JSON Canvas 1.0 spec](https://jsoncanvas.org/spec/1.0/).\n\nInstall: `npx quartz plugin add github:quartz-community/canvas-page`",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 560,
|
||||
"height": 200,
|
||||
"color": "5"
|
||||
},
|
||||
{
|
||||
"id": "text-node-demo",
|
||||
"type": "text",
|
||||
"text": "## Text Nodes\n\nText nodes render **Markdown** content with GFM support:\n\n- **Bold** and *italic* text\n- ~~Strikethrough~~ text\n- [External links](https://jsoncanvas.org)\n- `Inline code` blocks\n- Lists (like this one)\n\n### Headings Work Too\n\nAll standard Markdown syntax is rendered at build time.",
|
||||
"x": 0,
|
||||
"y": 300,
|
||||
"width": 360,
|
||||
"height": 280,
|
||||
"color": "1"
|
||||
},
|
||||
{
|
||||
"id": "file-node-info",
|
||||
"type": "text",
|
||||
"text": "## File Nodes\n\nFile nodes reference other pages in your vault. They appear as clickable links and support **popover previews** on hover.\n\nThe node below links to the CanvasPage documentation:",
|
||||
"x": 400,
|
||||
"y": 300,
|
||||
"width": 360,
|
||||
"height": 160,
|
||||
"color": "2"
|
||||
},
|
||||
{
|
||||
"id": "file-node-demo",
|
||||
"type": "file",
|
||||
"file": "plugins/CanvasPage.md",
|
||||
"x": 400,
|
||||
"y": 500,
|
||||
"width": 360,
|
||||
"height": 80,
|
||||
"color": "4"
|
||||
},
|
||||
{
|
||||
"id": "link-node-info",
|
||||
"type": "text",
|
||||
"text": "## Link Nodes\n\nLink nodes reference external URLs. The node below links to the JSON Canvas specification:",
|
||||
"x": 800,
|
||||
"y": 300,
|
||||
"width": 360,
|
||||
"height": 120,
|
||||
"color": "3"
|
||||
},
|
||||
{
|
||||
"id": "link-node-demo",
|
||||
"type": "link",
|
||||
"url": "https://jsoncanvas.org/spec/1.0/",
|
||||
"x": 800,
|
||||
"y": 460,
|
||||
"width": 360,
|
||||
"height": 80,
|
||||
"color": "5"
|
||||
},
|
||||
{
|
||||
"id": "color-1",
|
||||
"type": "text",
|
||||
"text": "**Color 1** — Red",
|
||||
"x": 0,
|
||||
"y": 830,
|
||||
"width": 180,
|
||||
"height": 80,
|
||||
"color": "1"
|
||||
},
|
||||
{
|
||||
"id": "color-2",
|
||||
"type": "text",
|
||||
"text": "**Color 2** — Orange",
|
||||
"x": 200,
|
||||
"y": 830,
|
||||
"width": 180,
|
||||
"height": 80,
|
||||
"color": "2"
|
||||
},
|
||||
{
|
||||
"id": "color-3",
|
||||
"type": "text",
|
||||
"text": "**Color 3** — Yellow",
|
||||
"x": 400,
|
||||
"y": 830,
|
||||
"width": 180,
|
||||
"height": 80,
|
||||
"color": "3"
|
||||
},
|
||||
{
|
||||
"id": "color-4",
|
||||
"type": "text",
|
||||
"text": "**Color 4** — Green",
|
||||
"x": 600,
|
||||
"y": 830,
|
||||
"width": 180,
|
||||
"height": 80,
|
||||
"color": "4"
|
||||
},
|
||||
{
|
||||
"id": "color-5",
|
||||
"type": "text",
|
||||
"text": "**Color 5** — Cyan",
|
||||
"x": 800,
|
||||
"y": 830,
|
||||
"width": 180,
|
||||
"height": 80,
|
||||
"color": "5"
|
||||
},
|
||||
{
|
||||
"id": "color-6",
|
||||
"type": "text",
|
||||
"text": "**Color 6** — Purple",
|
||||
"x": 1000,
|
||||
"y": 830,
|
||||
"width": 180,
|
||||
"height": 80,
|
||||
"color": "6"
|
||||
},
|
||||
{
|
||||
"id": "color-custom",
|
||||
"type": "text",
|
||||
"text": "**Custom hex color** — `#ff6600`",
|
||||
"x": 400,
|
||||
"y": 950,
|
||||
"width": 380,
|
||||
"height": 80,
|
||||
"color": "#ff6600"
|
||||
},
|
||||
{
|
||||
"id": "config-options",
|
||||
"type": "text",
|
||||
"text": "## Configuration Options\n\n- `enableInteraction` — Enable pan and zoom. Default: `true`\n- `initialZoom` — Initial zoom level. Default: `1`\n- `minZoom` — Minimum zoom level. Default: `0.1`\n- `maxZoom` — Maximum zoom level. Default: `5`\n- `defaultFullscreen` — Start in fullscreen mode. Default: `false`\n\nConfigure in `quartz.config.yaml`:\n\n```\nCanvasPage({ defaultFullscreen: false, initialZoom: 1 })\n```",
|
||||
"x": 0,
|
||||
"y": 1220,
|
||||
"width": 560,
|
||||
"height": 280
|
||||
},
|
||||
{
|
||||
"id": "config-fullscreen",
|
||||
"type": "text",
|
||||
"text": "## Fullscreen Mode\n\nClick the **expand button** (top-right corner) to toggle fullscreen mode. The canvas fills the entire viewport.\n\n- Press **Escape** to exit fullscreen\n- Set `defaultFullscreen: true` to start in fullscreen\n- The toggle button switches between expand and collapse icons\n\n## Quartz Integration\n\n- **Popover previews**: Hover over file nodes to see a preview\n- **Internal links**: File nodes link to pages in your vault\n- **Dark mode**: Canvas adapts to your theme settings",
|
||||
"x": 600,
|
||||
"y": 1220,
|
||||
"width": 560,
|
||||
"height": 280
|
||||
},
|
||||
{
|
||||
"id": "edge-source",
|
||||
"type": "text",
|
||||
"text": "## Edges\n\nEdges connect nodes with SVG paths. They support **labels**, **arrows**, and **colors**.",
|
||||
"x": 0,
|
||||
"y": 1650,
|
||||
"width": 300,
|
||||
"height": 120,
|
||||
"color": "1"
|
||||
},
|
||||
{
|
||||
"id": "edge-labeled",
|
||||
"type": "text",
|
||||
"text": "This edge has a **label** and an arrow marker.",
|
||||
"x": 450,
|
||||
"y": 1650,
|
||||
"width": 260,
|
||||
"height": 80,
|
||||
"color": "4"
|
||||
},
|
||||
{
|
||||
"id": "edge-colored",
|
||||
"type": "text",
|
||||
"text": "This edge has a **custom color** (`#ff6600`).",
|
||||
"x": 450,
|
||||
"y": 1780,
|
||||
"width": 260,
|
||||
"height": 80,
|
||||
"color": "2"
|
||||
},
|
||||
{
|
||||
"id": "edge-preset",
|
||||
"type": "text",
|
||||
"text": "Edges can use the same **preset colors** (1–6) as nodes, or custom **hex colors** like `#ff6600`.",
|
||||
"x": 850,
|
||||
"y": 1650,
|
||||
"width": 300,
|
||||
"height": 120,
|
||||
"color": "6"
|
||||
},
|
||||
{
|
||||
"id": "api-info",
|
||||
"type": "text",
|
||||
"text": "## API\n\n- **Category**: Page Type\n- **Function name**: `ExternalPlugin.CanvasPage()`\n- **Source**: [quartz-community/canvas-page](https://github.com/quartz-community/canvas-page)\n- **Install**: `npx quartz plugin add github:quartz-community/canvas-page`",
|
||||
"x": 0,
|
||||
"y": 2000,
|
||||
"width": 560,
|
||||
"height": 180
|
||||
},
|
||||
{
|
||||
"id": "spec-info",
|
||||
"type": "text",
|
||||
"text": "## JSON Canvas Spec\n\nThis plugin implements the [JSON Canvas 1.0](https://jsoncanvas.org/spec/1.0/) specification — an open file format for infinite canvas data.\n\nCanvas files use the `.canvas` extension and are standard JSON. They are natively supported by [Obsidian](https://obsidian.md).",
|
||||
"x": 600,
|
||||
"y": 2000,
|
||||
"width": 560,
|
||||
"height": 180
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "edge-title-to-types",
|
||||
"fromNode": "title",
|
||||
"fromSide": "bottom",
|
||||
"toNode": "group-node-types",
|
||||
"toSide": "top",
|
||||
"label": "supports"
|
||||
},
|
||||
{
|
||||
"id": "edge-info-to-file",
|
||||
"fromNode": "file-node-info",
|
||||
"fromSide": "bottom",
|
||||
"toNode": "file-node-demo",
|
||||
"toSide": "top",
|
||||
"color": "4"
|
||||
},
|
||||
{
|
||||
"id": "edge-info-to-link",
|
||||
"fromNode": "link-node-info",
|
||||
"fromSide": "bottom",
|
||||
"toNode": "link-node-demo",
|
||||
"toSide": "top",
|
||||
"color": "5"
|
||||
},
|
||||
{
|
||||
"id": "edge-types-to-colors",
|
||||
"fromNode": "group-node-types",
|
||||
"fromSide": "bottom",
|
||||
"toNode": "group-colors",
|
||||
"toSide": "top"
|
||||
},
|
||||
{
|
||||
"id": "edge-colors-to-config",
|
||||
"fromNode": "group-colors",
|
||||
"fromSide": "bottom",
|
||||
"toNode": "group-config",
|
||||
"toSide": "top"
|
||||
},
|
||||
{
|
||||
"id": "edge-config-to-edges",
|
||||
"fromNode": "group-config",
|
||||
"fromSide": "bottom",
|
||||
"toNode": "group-edges",
|
||||
"toSide": "top"
|
||||
},
|
||||
{
|
||||
"id": "edge-labeled-demo",
|
||||
"fromNode": "edge-source",
|
||||
"fromSide": "right",
|
||||
"toNode": "edge-labeled",
|
||||
"toSide": "left",
|
||||
"label": "labeled edge"
|
||||
},
|
||||
{
|
||||
"id": "edge-colored-demo",
|
||||
"fromNode": "edge-source",
|
||||
"fromSide": "right",
|
||||
"toNode": "edge-colored",
|
||||
"toSide": "left",
|
||||
"color": "#ff6600"
|
||||
},
|
||||
{
|
||||
"id": "edge-preset-demo",
|
||||
"fromNode": "edge-labeled",
|
||||
"fromSide": "right",
|
||||
"toNode": "edge-preset",
|
||||
"toSide": "left",
|
||||
"color": "6"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -11,7 +11,7 @@ This question is best answered by tracing what happens when a user (you!) runs `
|
||||
1. After running `npx quartz build`, npm will look at `package.json` to find the `bin` entry for `quartz` which points at `./quartz/bootstrap-cli.mjs`.
|
||||
2. This file has a [shebang](<https://en.wikipedia.org/wiki/Shebang_(Unix)>) line at the top which tells npm to execute it using Node.
|
||||
3. `bootstrap-cli.mjs` is responsible for a few things:
|
||||
1. Parsing the command-line arguments using [yargs](http://yargs.js.org/).
|
||||
1. Parsing the command-line arguments using [yargs](http://yargs.js.org/). The `plugin` subcommand is also handled here for managing external plugins.
|
||||
2. Transpiling and bundling the rest of Quartz (which is in Typescript) to regular JavaScript using [esbuild](https://esbuild.github.io/). The `esbuild` configuration here is slightly special as it also handles `.scss` file imports using [esbuild-sass-plugin v2](https://www.npmjs.com/package/esbuild-sass-plugin). Additionally, we bundle 'inline' client-side scripts (any `.inline.ts` file) that components declare using a custom `esbuild` plugin that runs another instance of `esbuild` which bundles for the browser instead of `node`. Modules of both types are imported as plain text.
|
||||
3. Running the local preview server if `--serve` is set. This starts two servers:
|
||||
1. A WebSocket server on port 3001 to handle hot-reload signals. This tracks all inbound connections and sends a 'rebuild' message a server-side change is detected (either content or configuration).
|
||||
@ -35,7 +35,7 @@ This question is best answered by tracing what happens when a user (you!) runs `
|
||||
4. Filter out unwanted content using plugins.
|
||||
5. Emit files using plugins.
|
||||
1. Gather all the static resources (e.g. external CSS, JS modules, etc.) each emitter plugin declares.
|
||||
2. Emitters that emit HTML files do a bit of extra work here as they need to transform the [hast](https://github.com/syntax-tree/hast) produced in the parse step to JSX. This is done using [hast-util-to-jsx-runtime](https://github.com/syntax-tree/hast-util-to-jsx-runtime) with the [Preact](https://preactjs.com/) runtime. Finally, the JSX is rendered to HTML using [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) which statically renders the JSX to HTML (i.e. doesn't care about `useState`, `useEffect`, or any other React/Preact interactive bits). Here, we also do a bunch of fun stuff like assemble the page [[layout]] from `quartz.layout.ts`, assemble all the inline scripts that actually get shipped to the client, and all the transpiled styles. The bulk of this logic can be found in `quartz/components/renderPage.tsx`. Other fun things of note:
|
||||
2. Emitters that emit HTML files do a bit of extra work here as they need to transform the [hast](https://github.com/syntax-tree/hast) produced in the parse step to JSX. This is done using [hast-util-to-jsx-runtime](https://github.com/syntax-tree/hast-util-to-jsx-runtime) with the [Preact](https://preactjs.com/) runtime. Finally, the JSX is rendered to HTML using [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) which statically renders the JSX to HTML (i.e. doesn't care about `useState`, `useEffect`, or any other React/Preact interactive bits). Here, we also do a bunch of fun stuff like assemble the page [[layout]] from `quartz.config.yaml`, assemble all the inline scripts that actually get shipped to the client, and all the transpiled styles. The bulk of this logic can be found in `quartz/components/renderPage.tsx`. Other fun things of note:
|
||||
1. CSS is minified and transformed using [Lightning CSS](https://github.com/parcel-bundler/lightningcss) to add vendor prefixes and do syntax lowering.
|
||||
2. Scripts are split into `beforeDOMLoaded` and `afterDOMLoaded` and are inserted in the `<head>` and `<body>` respectively.
|
||||
3. Finally, each emitter plugin is responsible for emitting and writing it's own emitted files to disk.
|
||||
@ -48,5 +48,79 @@ This question is best answered by tracing what happens when a user (you!) runs `
|
||||
3. Once the page is done loading, the page will then dispatch a custom synthetic browser event `"nav"`. This is used so client-side scripts declared by components can 'setup' anything that requires access to the page DOM.
|
||||
1. If the [[SPA Routing|enableSPA option]] is enabled in the [[configuration]], this `"nav"` event is also fired on any client-navigation to allow for components to unregister and reregister any event handlers and state.
|
||||
2. If it's not, we wire up the `"nav"` event to just be fired a single time after page load to allow for consistency across how state is setup across both SPA and non-SPA contexts.
|
||||
3. A separate `"render"` event can be dispatched when the DOM is updated in-place without a full navigation (e.g. after content decryption). Components that attach listeners to content elements should listen for both `"nav"` and `"render"`.
|
||||
|
||||
The architecture and design of the plugin system was intentionally left pretty vague here as this is described in much more depth in the guide on [[making plugins|making your own plugin]].
|
||||
## Plugin System
|
||||
|
||||
Page types define how a category of pages is rendered. They are configured in the `pageTypes` array in `quartz.config.yaml`.
|
||||
|
||||
Quartz v5 introduces a community plugin system. Plugins are standalone Git repositories that are cloned into `.quartz/plugins/` and re-exported through an auto-generated index file at `.quartz/plugins/index.ts`.
|
||||
|
||||
### Plugin Types
|
||||
|
||||
There are now four plugin categories:
|
||||
|
||||
- **Transformers**: Map over content (parse frontmatter, generate descriptions, syntax highlighting)
|
||||
- **Filters**: Filter content (remove drafts, explicit publish)
|
||||
- **Emitters**: Reduce over content (generate RSS, sitemaps, alias redirects, OG images)
|
||||
- **Page Types**: Define how pages are rendered. Each page type handles a specific kind of page (content notes, folder listings, tag listings, 404). The `PageTypeDispatcher` emitter routes pages to the appropriate page type plugin based on the content.
|
||||
|
||||
### Plugin Resolution
|
||||
|
||||
When `npx quartz plugin add github:quartz-community/explorer` is run:
|
||||
|
||||
1. The repository is cloned into `.quartz/plugins/explorer/`
|
||||
2. The plugin is built using `tsup` (defined in each plugin's `tsup.config.ts`)
|
||||
3. An auto-generated `.quartz/plugins/index.ts` re-exports all installed plugins
|
||||
4. The plugin's commit hash is recorded in `quartz.lock.json`
|
||||
|
||||
### Plugin CLI Commands
|
||||
|
||||
- `npx quartz plugin add github:quartz-community/<name>` — Install a community plugin
|
||||
- `npx quartz plugin update` — Update all plugins to latest commits
|
||||
- `npx quartz plugin restore` — Restore plugins from locked commits in `quartz.lock.json` (used in CI/CD)
|
||||
- `npx quartz plugin remove <name>` — Remove an installed plugin
|
||||
|
||||
### Plugin Structure
|
||||
|
||||
Each community plugin repository contains:
|
||||
|
||||
- `src/index.ts` — Plugin entry point exporting the plugin function
|
||||
- `tsup.config.ts` — Build configuration using tsup
|
||||
- `package.json` — Declares dependencies on `@quartz-community/types` and `@quartz-community/utils`
|
||||
|
||||
The architecture and design of the plugin system was intentionally left pretty vague here as this is described in much more depth in the guide on [[making plugins|creating plugins]].
|
||||
|
||||
## Page Frames
|
||||
|
||||
Page frames control the inner HTML structure of each page. While the outer shell (`<html>`, `<head>`, `<body>`, `#quartz-root`) is always the same (required for [[SPA Routing]]), the frame determines how layout slots are arranged inside the page.
|
||||
|
||||
The frame system lives in `quartz/components/frames/` and consists of:
|
||||
|
||||
- `types.ts` — Defines the `PageFrame` and `PageFrameProps` interfaces
|
||||
- `DefaultFrame.tsx` — Three-column layout (left sidebar, center, right sidebar, footer)
|
||||
- `FullWidthFrame.tsx` — No sidebars, single center column
|
||||
- `MinimalFrame.tsx` — No sidebars, no header/beforeBody, just content and footer
|
||||
- `registry.ts` — `FrameRegistry` singleton for plugin-registered frames
|
||||
- `index.ts` — `resolveFrame()` function and built-in frame registry
|
||||
|
||||
### Frame Registry
|
||||
|
||||
The `FrameRegistry` (`quartz/components/frames/registry.ts`) is a singleton that stores frames registered by community plugins. It mirrors the design of the `ComponentRegistry`. Plugins declare frames in their `package.json` manifest under the `"quartz"."frames"` field, and these are loaded by `quartz/plugins/loader/frameLoader.ts` during plugin initialization.
|
||||
|
||||
### Frame Resolution
|
||||
|
||||
The rendering pipeline in `quartz/components/renderPage.tsx` delegates to the resolved frame's `render()` function. Frame resolution happens in the `PageTypeDispatcher` emitter (`quartz/plugins/pageTypes/dispatcher.ts`) using this priority:
|
||||
|
||||
1. YAML config: `layout.byPageType.<name>.template`
|
||||
2. Plugin-registered frame: looked up by name in the `FrameRegistry`
|
||||
3. Built-in frame: looked up by name in the `builtinFrames` map
|
||||
4. Fallback: `"default"`
|
||||
|
||||
The active frame name is set as a `data-frame` attribute on the `.page` element, enabling frame-specific CSS overrides in `quartz/styles/base.scss`.
|
||||
|
||||
### Plugin-Provided Frames
|
||||
|
||||
Community plugins can ship their own frames by exporting them from a `./frames` subpath and declaring them in the plugin manifest. For example, the `canvas-page` plugin provides a `"canvas"` frame with a fullscreen layout and togglable sidebar. See [[making plugins#Providing Custom Frames]] for implementation details.
|
||||
|
||||
See [[layout#Page Frames]] for user-facing documentation and [[making plugins#Page Types]] for how to set frames in page type plugins.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Creating your own Quartz components
|
||||
title: Creating Component Plugins
|
||||
---
|
||||
|
||||
> [!warning]
|
||||
@ -20,17 +20,31 @@ However, HTML doesn't let you create reusable templates. If you wanted to create
|
||||
|
||||
In effect, components allow you to write a JavaScript function that takes some data and produces HTML as an output. **While Quartz doesn't use React, it uses the same component concept to allow you to easily express layout templates in your Quartz site.**
|
||||
|
||||
## An Example Component
|
||||
## Community Component Plugins
|
||||
|
||||
### Constructor
|
||||
In v5, most components are community plugins — standalone repositories that export a `QuartzComponent`. These plugins are decoupled from the core Quartz repository, allowing for easier maintenance and sharing.
|
||||
|
||||
Component files are written in `.tsx` files that live in the `quartz/components` folder. These are re-exported in `quartz/components/index.ts` so you can use them in layouts and other components more easily.
|
||||
### Getting Started
|
||||
|
||||
Each component file should have a default export that satisfies the `QuartzComponentConstructor` function signature. It's a function that takes in a single optional parameter `opts` and returns a Quartz Component. The type of the parameters `opts` is defined by the interface `Options` which you as the component creator also decide.
|
||||
To create a new component plugin, you can use the official plugin template:
|
||||
|
||||
In your component, you can use the values from the configuration option to change the rendering behaviour inside of your component. For example, the component in the code snippet below will not render if the `favouriteNumber` option is below 0.
|
||||
```shell
|
||||
git clone https://github.com/quartz-community/plugin-template.git my-component
|
||||
cd my-component
|
||||
npm install
|
||||
```
|
||||
|
||||
### Plugin Structure
|
||||
|
||||
A component plugin's `src/index.ts` typically exports a function (a constructor) that returns a `QuartzComponent`. This allows users to pass configuration options to your component.
|
||||
|
||||
```tsx title="src/index.ts"
|
||||
import {
|
||||
QuartzComponent,
|
||||
QuartzComponentConstructor,
|
||||
QuartzComponentProps,
|
||||
} from "@quartz-community/types"
|
||||
|
||||
```tsx {11-17}
|
||||
interface Options {
|
||||
favouriteNumber: number
|
||||
}
|
||||
@ -39,28 +53,25 @@ const defaultOptions: Options = {
|
||||
favouriteNumber: 42,
|
||||
}
|
||||
|
||||
export default ((userOpts?: Options) => {
|
||||
const opts = { ...userOpts, ...defaultOpts }
|
||||
function YourComponent(props: QuartzComponentProps) {
|
||||
if (opts.favouriteNumber < 0) {
|
||||
return null
|
||||
}
|
||||
const MyComponent: QuartzComponentConstructor<Options> = (userOpts?: Options) => {
|
||||
const opts = { ...defaultOptions, ...userOpts }
|
||||
|
||||
const Component: QuartzComponent = (props: QuartzComponentProps) => {
|
||||
if (opts.favouriteNumber < 0) return null
|
||||
return <p>My favourite number is {opts.favouriteNumber}</p>
|
||||
}
|
||||
|
||||
return YourComponent
|
||||
}) satisfies QuartzComponentConstructor
|
||||
return Component
|
||||
}
|
||||
|
||||
export default MyComponent
|
||||
```
|
||||
|
||||
### Props
|
||||
|
||||
The Quartz component itself (lines 11-17 highlighted above) looks like a React component. It takes in properties (sometimes called [props](https://react.dev/learn/passing-props-to-a-component)) and returns JSX.
|
||||
|
||||
All Quartz components accept the same set of props:
|
||||
|
||||
```tsx title="quartz/components/types.ts"
|
||||
// simplified for sake of demonstration
|
||||
```tsx
|
||||
export type QuartzComponentProps = {
|
||||
fileData: QuartzPluginData
|
||||
cfg: GlobalConfiguration
|
||||
@ -70,50 +81,29 @@ export type QuartzComponentProps = {
|
||||
}
|
||||
```
|
||||
|
||||
- `fileData`: Any metadata [[making plugins|plugins]] may have added to the current page.
|
||||
- `fileData`: Any metadata plugins may have added to the current page.
|
||||
- `fileData.slug`: slug of the current page.
|
||||
- `fileData.frontmatter`: any frontmatter parsed.
|
||||
- `cfg`: The `configuration` field in `quartz.config.ts`.
|
||||
- `tree`: the resulting [HTML AST](https://github.com/syntax-tree/hast) after processing and transforming the file. This is useful if you'd like to render the content using [hast-util-to-jsx-runtime](https://github.com/syntax-tree/hast-util-to-jsx-runtime) (you can find an example of this in `quartz/components/pages/Content.tsx`).
|
||||
- `cfg`: The `configuration` field in `quartz.config.yaml`.
|
||||
- `tree`: the resulting [HTML AST](https://github.com/syntax-tree/hast) after processing and transforming the file.
|
||||
- `allFiles`: Metadata for all files that have been parsed. Useful for doing page listings or figuring out the overall site structure.
|
||||
- `displayClass`: a utility class that indicates a preference from the user about how to render it in a mobile or desktop setting. Helpful if you want to conditionally hide a component on mobile or desktop.
|
||||
- `displayClass`: a utility class that indicates a preference from the user about how to render it in a mobile or desktop setting.
|
||||
|
||||
### Styling
|
||||
|
||||
Quartz components can also define a `.css` property on the actual function component which will get picked up by Quartz. This is expected to be a CSS string which can either be inlined or imported from a `.scss` file.
|
||||
In community plugins, styles are bundled with the plugin. You can define styles using the `.css` property on the component:
|
||||
|
||||
Note that inlined styles **must** be plain vanilla CSS:
|
||||
|
||||
```tsx {6-10} title="quartz/components/YourComponent.tsx"
|
||||
export default (() => {
|
||||
function YourComponent() {
|
||||
return <p class="red-text">Example Component</p>
|
||||
}
|
||||
|
||||
YourComponent.css = `
|
||||
p.red-text {
|
||||
color: red;
|
||||
}
|
||||
`
|
||||
|
||||
return YourComponent
|
||||
}) satisfies QuartzComponentConstructor
|
||||
```tsx
|
||||
Component.css = `
|
||||
.my-component { color: red; }
|
||||
`
|
||||
```
|
||||
|
||||
Imported styles, however, can be from SCSS files:
|
||||
For SCSS, you can import it and assign it to the `.css` property. The build system will handle the transformation:
|
||||
|
||||
```tsx {1-2,9} title="quartz/components/YourComponent.tsx"
|
||||
// assuming your stylesheet is in quartz/components/styles/YourComponent.scss
|
||||
import styles from "./styles/YourComponent.scss"
|
||||
|
||||
export default (() => {
|
||||
function YourComponent() {
|
||||
return <p>Example Component</p>
|
||||
}
|
||||
|
||||
YourComponent.css = styles
|
||||
return YourComponent
|
||||
}) satisfies QuartzComponentConstructor
|
||||
```tsx
|
||||
import styles from "./styles.scss"
|
||||
Component.css = styles
|
||||
```
|
||||
|
||||
> [!warning]
|
||||
@ -121,128 +111,108 @@ export default (() => {
|
||||
|
||||
### Scripts and Interactivity
|
||||
|
||||
What about interactivity? Suppose you want to add an-click handler for example. Like the `.css` property on the component, you can also declare `.beforeDOMLoaded` and `.afterDOMLoaded` properties that are strings that contain the script.
|
||||
For interactivity, you can declare `.beforeDOMLoaded` and `.afterDOMLoaded` properties on the component. These should be strings containing the JavaScript to be executed in the browser.
|
||||
|
||||
```tsx title="quartz/components/YourComponent.tsx"
|
||||
export default (() => {
|
||||
function YourComponent() {
|
||||
return <button id="btn">Click me</button>
|
||||
}
|
||||
- `.beforeDOMLoaded`: Executed _before_ the page is done loading. Used for prefetching or early initialization.
|
||||
- `.afterDOMLoaded`: Executed once the page has been completely loaded.
|
||||
|
||||
YourComponent.beforeDOMLoaded = `
|
||||
console.log("hello from before the page loads!")
|
||||
`
|
||||
|
||||
YourComponent.afterDOMLoaded = `
|
||||
document.getElementById('btn').onclick = () => {
|
||||
alert('button clicked!')
|
||||
}
|
||||
`
|
||||
return YourComponent
|
||||
}) satisfies QuartzComponentConstructor
|
||||
```
|
||||
|
||||
> [!hint]
|
||||
> For those coming from React, Quartz components are different from React components in that it only uses JSX for templating and layout. Hooks like `useEffect`, `useState`, etc. are not rendered and other properties that accept functions like `onClick` handlers will not work. Instead, do it using a regular JS script that modifies the DOM element directly.
|
||||
|
||||
As the names suggest, the `.beforeDOMLoaded` scripts are executed _before_ the page is done loading so it doesn't have access to any elements on the page. This is mostly used to prefetch any critical data.
|
||||
|
||||
The `.afterDOMLoaded` script executes once the page has been completely loaded. This is a good place to setup anything that should last for the duration of a site visit (e.g. getting something saved from local storage).
|
||||
|
||||
If you need to create an `afterDOMLoaded` script that depends on _page specific_ elements that may change when navigating to a new page, you can listen for the `"nav"` event that gets fired whenever a page loads (which may happen on navigation if [[SPA Routing]] is enabled).
|
||||
If you need to create an `afterDOMLoaded` script that depends on page-specific elements that may change when navigating, listen for the `"nav"` event:
|
||||
|
||||
```ts
|
||||
document.addEventListener("nav", () => {
|
||||
// do page specific logic here
|
||||
// e.g. attach event listeners
|
||||
const toggleSwitch = document.querySelector("#switch") as HTMLInputElement
|
||||
toggleSwitch.addEventListener("change", switchTheme)
|
||||
window.addCleanup(() => toggleSwitch.removeEventListener("change", switchTheme))
|
||||
if (toggleSwitch) {
|
||||
toggleSwitch.addEventListener("change", switchTheme)
|
||||
window.addCleanup(() => toggleSwitch.removeEventListener("change", switchTheme))
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
You can also add the equivalent of a `beforeunload` event for [[SPA Routing]] via the `prenav` event.
|
||||
You can also use the `"prenav"` event, which fires before the page is replaced during SPA navigation.
|
||||
|
||||
The `"render"` event fires when the DOM has been updated in-place without a full navigation — for example, after content decryption or dynamic DOM modifications by other plugins. If your component attaches event listeners to content elements, listen for `"render"` in addition to `"nav"` to ensure re-initialization:
|
||||
|
||||
```ts
|
||||
document.addEventListener("prenav", () => {
|
||||
// executed after an SPA navigation is triggered but
|
||||
// before the page is replaced
|
||||
// one usage pattern is to store things in sessionStorage
|
||||
// in the prenav and then conditionally load then in the consequent
|
||||
// nav
|
||||
})
|
||||
function setupMyComponent() {
|
||||
const elements = document.querySelectorAll(".my-interactive")
|
||||
for (const el of elements) {
|
||||
el.addEventListener("click", handleClick)
|
||||
window.addCleanup(() => el.removeEventListener("click", handleClick))
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("nav", setupMyComponent)
|
||||
document.addEventListener("render", setupMyComponent)
|
||||
```
|
||||
|
||||
It is best practice to track any event handlers via `window.addCleanup` to prevent memory leaks.
|
||||
This will get called on page navigation.
|
||||
It is best practice to track any event handlers via `window.addCleanup` to prevent memory leaks during SPA navigation.
|
||||
|
||||
#### Importing Code
|
||||
|
||||
Of course, it isn't always practical (nor desired!) to write your code as a string literal in the component.
|
||||
In community plugins, TypeScript scripts should be transpiled at build time. The plugin template includes an `inlineScriptPlugin` in `tsup.config.ts` that automatically transpiles `.inline.ts` files imported as text:
|
||||
|
||||
Quartz supports importing component code through `.inline.ts` files.
|
||||
```tsx title="src/index.ts"
|
||||
import script from "./script.inline.ts"
|
||||
|
||||
```tsx title="quartz/components/YourComponent.tsx"
|
||||
// @ts-ignore: typescript doesn't know about our inline bundling system
|
||||
// so we need to silence the error
|
||||
import script from "./scripts/graph.inline"
|
||||
|
||||
export default (() => {
|
||||
function YourComponent() {
|
||||
return <button id="btn">Click me</button>
|
||||
}
|
||||
|
||||
YourComponent.afterDOMLoaded = script
|
||||
return YourComponent
|
||||
}) satisfies QuartzComponentConstructor
|
||||
```
|
||||
|
||||
```ts title="quartz/components/scripts/graph.inline.ts"
|
||||
// any imports here are bundled for the browser
|
||||
import * as d3 from "d3"
|
||||
|
||||
document.getElementById("btn").onclick = () => {
|
||||
alert("button clicked!")
|
||||
const Component: QuartzComponent = (props) => {
|
||||
return <button id="btn">Click me</button>
|
||||
}
|
||||
Component.afterDOMLoaded = script
|
||||
```
|
||||
|
||||
Additionally, like what is shown in the example above, you can import packages in `.inline.ts` files. This will be bundled by Quartz and included in the actual script.
|
||||
The `inlineScriptPlugin` handles transpiling TypeScript to browser-compatible JavaScript during the build step, allowing you to write type-safe client-side code.
|
||||
|
||||
### Using a Component
|
||||
### Installing Your Component
|
||||
|
||||
After creating your custom component, re-export it in `quartz/components/index.ts`:
|
||||
Once your component is published (e.g., to GitHub or npm), users can install it using the Quartz CLI:
|
||||
|
||||
```ts title="quartz/components/index.ts" {4,10}
|
||||
import ArticleTitle from "./ArticleTitle"
|
||||
import Content from "./pages/Content"
|
||||
import Darkmode from "./Darkmode"
|
||||
import YourComponent from "./YourComponent"
|
||||
|
||||
export { ArticleTitle, Content, Darkmode, YourComponent }
|
||||
```shell
|
||||
npx quartz plugin add github:your-username/my-component
|
||||
```
|
||||
|
||||
Then, you can use it like any other component in `quartz.layout.ts` via `Component.YourComponent()`. See the [[configuration#Layout|layout]] section for more details.
|
||||
Then, they can add it to their `quartz.config.yaml`:
|
||||
|
||||
As Quartz components are just functions that return React components, you can compositionally use them in other Quartz components.
|
||||
|
||||
```tsx title="quartz/components/AnotherComponent.tsx"
|
||||
import YourComponentConstructor from "./YourComponent"
|
||||
|
||||
export default (() => {
|
||||
const YourComponent = YourComponentConstructor()
|
||||
|
||||
function AnotherComponent(props: QuartzComponentProps) {
|
||||
return (
|
||||
<div>
|
||||
<p>It's nested!</p>
|
||||
<YourComponent {...props} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return AnotherComponent
|
||||
}) satisfies QuartzComponentConstructor
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:your-username/my-component
|
||||
enabled: true
|
||||
options:
|
||||
favouriteNumber: 42
|
||||
layout:
|
||||
position: left
|
||||
priority: 60
|
||||
```
|
||||
|
||||
For advanced usage via the TS override in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||
import Plugin from "./.quartz/plugins"
|
||||
|
||||
const config = await loadQuartzConfig()
|
||||
export default config
|
||||
export const layout = await loadQuartzLayout({
|
||||
byPageType: {
|
||||
content: {
|
||||
left: [Plugin.MyComponent({ favouriteNumber: 42 })],
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Internal Components
|
||||
|
||||
Quartz also has internal components that provide layout utilities. These live in `quartz/components/` and are primarily used for structural purposes:
|
||||
|
||||
- `Component.Head()` — renders the `<head>` tag
|
||||
- `Component.Spacer()` — adds flexible space
|
||||
- `Component.Flex()` — flexible layout container
|
||||
- `Component.MobileOnly()` — shows component only on mobile
|
||||
- `Component.DesktopOnly()` — shows component only on desktop
|
||||
- `Component.ConditionalRender()` — conditionally renders based on page data
|
||||
|
||||
See [[layout-components]] for more details on these utilities.
|
||||
|
||||
> [!hint]
|
||||
> Look in `quartz/components` for more examples of components in Quartz as reference for your own components!
|
||||
> Look at existing community plugins like [Explorer](https://github.com/quartz-community/explorer) or [Darkmode](https://github.com/quartz-community/darkmode) for real-world examples.
|
||||
|
||||
@ -1,3 +1,10 @@
|
||||
---
|
||||
title: "Advanced"
|
||||
---
|
||||
|
||||
This section covers advanced topics for users who want to extend or deeply customize Quartz.
|
||||
|
||||
- **[[architecture]]** — How Quartz works under the hood: the parse, filter, and emit pipeline
|
||||
- **[[making plugins]]** — Build your own transformer, filter, emitter, or component plugin
|
||||
- **[[creating components]]** — Create custom layout components with JSX
|
||||
- **[[paths]]** — How Quartz resolves and transforms file paths
|
||||
|
||||
@ -18,20 +18,52 @@ type QuartzPluginInstance =
|
||||
| QuartzTransformerPluginInstance
|
||||
| QuartzFilterPluginInstance
|
||||
| QuartzEmitterPluginInstance
|
||||
| QuartzPageTypePluginInstance
|
||||
```
|
||||
|
||||
The following sections will go into detail for what methods can be implemented for each plugin type. Before we do that, let's clarify a few more ambiguous types:
|
||||
|
||||
- `BuildCtx` is defined in `quartz/ctx.ts`. It consists of
|
||||
- `BuildCtx` is defined in `@quartz-community/types`. It consists of
|
||||
- `argv`: The command line arguments passed to the Quartz [[build]] command
|
||||
- `cfg`: The full Quartz [[configuration]]
|
||||
- `allSlugs`: a list of all the valid content slugs (see [[paths]] for more information on what a slug is)
|
||||
- `StaticResources` is defined in `quartz/resources.tsx`. It consists of
|
||||
- `css`: a list of CSS style definitions that should be loaded. A CSS style is described with the `CSSResource` type which is also defined in `quartz/resources.tsx`. It accepts either a source URL or the inline content of the stylesheet.
|
||||
- `js`: a list of scripts that should be loaded. A script is described with the `JSResource` type which is also defined in `quartz/resources.tsx`. It allows you to define a load time (either before or after the DOM has been loaded), whether it should be a module, and either the source URL or the inline content of the script.
|
||||
- `StaticResources` is defined in `@quartz-community/types`. It consists of
|
||||
- `css`: a list of CSS style definitions that should be loaded. A CSS style is described with the `CSSResource` type. It accepts either a source URL or the inline content of the stylesheet.
|
||||
- `js`: a list of scripts that should be loaded. A script is described with the `JSResource` type. It allows you to define a load time (either before or after the DOM has been loaded), whether it should be a module, and either the source URL or the inline content of the script.
|
||||
- `additionalHead`: a list of JSX elements or functions that return JSX elements to be added to the `<head>` tag of the page. Functions receive the page's data as an argument and can conditionally render elements.
|
||||
|
||||
## Transformers
|
||||
## Getting Started
|
||||
|
||||
In v5, plugins are standalone repositories. The easiest way to create one is using the plugin template:
|
||||
|
||||
```shell
|
||||
# Use the plugin template to create a new repository on GitHub
|
||||
# Then clone it locally
|
||||
git clone https://github.com/your-username/my-plugin.git
|
||||
cd my-plugin
|
||||
npm install
|
||||
```
|
||||
|
||||
The template provides the build configuration (`tsup.config.ts`), TypeScript setup, and correct package structure.
|
||||
|
||||
## Plugin Structure
|
||||
|
||||
The basic file structure of a plugin is as follows:
|
||||
|
||||
```
|
||||
my-plugin/
|
||||
├── src/
|
||||
│ └── index.ts # Plugin entry point
|
||||
├── tsup.config.ts # Build configuration
|
||||
├── package.json # Dependencies and exports
|
||||
└── tsconfig.json # TypeScript configuration
|
||||
```
|
||||
|
||||
The plugin's `package.json` should declare dependencies on `@quartz-community/types` (for type definitions) and optionally `@quartz-community/utils` (for shared utilities).
|
||||
|
||||
## Plugin Types
|
||||
|
||||
### Transformers
|
||||
|
||||
Transformers **map** over content, taking a Markdown file and outputting modified content or adding metadata to the file itself.
|
||||
|
||||
@ -52,15 +84,15 @@ All transformer plugins must define at least a `name` field to register the plug
|
||||
- `htmlPlugins` defines a list of [rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md). Similar to how `remark` works, `rehype` is a tool that transforms HTML to HTML in a structured way.
|
||||
- `externalResources` defines any external resources the plugin may need to load on the client-side for it to work properly.
|
||||
|
||||
Normally for both `remark` and `rehype`, you can find existing plugins that you can use to . If you'd like to create your own `remark` or `rehype` plugin, checkout the [guide to creating a plugin](https://unifiedjs.com/learn/guide/create-a-plugin/) using `unified` (the underlying AST parser and transformer library).
|
||||
Normally for both `remark` and `rehype`, you can find existing plugins that you can use. If you'd like to create your own `remark` or `rehype` plugin, checkout the [guide to creating a plugin](https://unifiedjs.com/learn/guide/create-a-plugin/) using `unified` (the underlying AST parser and transformer library).
|
||||
|
||||
A good example of a transformer plugin that borrows from the `remark` and `rehype` ecosystems is the [[plugins/Latex|Latex]] plugin:
|
||||
|
||||
```ts title="quartz/plugins/transformers/latex.ts"
|
||||
```ts
|
||||
import remarkMath from "remark-math"
|
||||
import rehypeKatex from "rehype-katex"
|
||||
import rehypeMathjax from "rehype-mathjax/svg"
|
||||
import { QuartzTransformerPlugin } from "../types"
|
||||
import { QuartzTransformerPlugin } from "@quartz-community/types"
|
||||
|
||||
interface Options {
|
||||
renderEngine: "katex" | "mathjax"
|
||||
@ -109,6 +141,8 @@ export const Latex: QuartzTransformerPlugin<Options> = (opts?: Options) => {
|
||||
Another common thing that transformer plugins will do is parse a file and add extra data for that file:
|
||||
|
||||
```ts
|
||||
import { QuartzTransformerPlugin } from "@quartz-community/types"
|
||||
|
||||
export const AddWordCount: QuartzTransformerPlugin = () => {
|
||||
return {
|
||||
name: "AddWordCount",
|
||||
@ -140,45 +174,50 @@ declare module "vfile" {
|
||||
Finally, you can also perform transformations over Markdown or HTML ASTs using the `visit` function from the `unist-util-visit` package or the `findAndReplace` function from the `mdast-util-find-and-replace` package.
|
||||
|
||||
```ts
|
||||
import { visit } from "unist-util-visit"
|
||||
import { findAndReplace } from "mdast-util-find-and-replace"
|
||||
import { QuartzTransformerPlugin } from "@quartz-community/types"
|
||||
import { Link } from "mdast"
|
||||
|
||||
export const TextTransforms: QuartzTransformerPlugin = () => {
|
||||
return {
|
||||
name: "TextTransforms",
|
||||
markdownPlugins() {
|
||||
return [() => {
|
||||
return (tree, file) => {
|
||||
// replace _text_ with the italics version
|
||||
findAndReplace(tree, /_(.+)_/, (_value: string, ...capture: string[]) => {
|
||||
// inner is the text inside of the () of the regex
|
||||
const [inner] = capture
|
||||
// return an mdast node
|
||||
// https://github.com/syntax-tree/mdast
|
||||
return {
|
||||
type: "emphasis",
|
||||
children: [{ type: 'text', value: inner }]
|
||||
}
|
||||
})
|
||||
return [
|
||||
() => {
|
||||
return (tree, file) => {
|
||||
// replace _text_ with the italics version
|
||||
findAndReplace(tree, /_(.+)_/, (_value: string, ...capture: string[]) => {
|
||||
// inner is the text inside of the () of the regex
|
||||
const [inner] = capture
|
||||
// return an mdast node
|
||||
// https://github.com/syntax-tree/mdast
|
||||
return {
|
||||
type: "emphasis",
|
||||
children: [{ type: "text", value: inner }],
|
||||
}
|
||||
})
|
||||
|
||||
// remove all links (replace with just the link content)
|
||||
// match by 'type' field on an mdast node
|
||||
// https://github.com/syntax-tree/mdast#link in this example
|
||||
visit(tree, "link", (link: Link) => {
|
||||
return {
|
||||
type: "paragraph"
|
||||
children: [{ type: 'text', value: link.title }]
|
||||
}
|
||||
})
|
||||
}
|
||||
}]
|
||||
}
|
||||
// remove all links (replace with just the link content)
|
||||
// match by 'type' field on an mdast node
|
||||
// https://github.com/syntax-tree/mdast#link in this example
|
||||
visit(tree, "link", (link: Link) => {
|
||||
return {
|
||||
type: "paragraph",
|
||||
children: [{ type: "text", value: link.title }],
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
All transformer plugins can be found under `quartz/plugins/transformers`. If you decide to write your own transformer plugin, don't forget to re-export it under `quartz/plugins/transformers/index.ts`
|
||||
|
||||
A parting word: transformer plugins are quite complex so don't worry if you don't get them right away. Take a look at the built in transformers and see how they operate over content to get a better sense for how to accomplish what you are trying to do.
|
||||
|
||||
## Filters
|
||||
### Filters
|
||||
|
||||
Filters **filter** content, taking the output of all the transformers and determining what files to actually keep and what to discard.
|
||||
|
||||
@ -197,8 +236,8 @@ A filter plugin must define a `name` field and a `shouldPublish` function that t
|
||||
|
||||
For example, here is the built-in plugin for removing drafts:
|
||||
|
||||
```ts title="quartz/plugins/filters/draft.ts"
|
||||
import { QuartzFilterPlugin } from "../types"
|
||||
```ts
|
||||
import { QuartzFilterPlugin } from "@quartz-community/types"
|
||||
|
||||
export const RemoveDrafts: QuartzFilterPlugin<{}> = () => ({
|
||||
name: "RemoveDrafts",
|
||||
@ -210,7 +249,7 @@ export const RemoveDrafts: QuartzFilterPlugin<{}> = () => ({
|
||||
})
|
||||
```
|
||||
|
||||
## Emitters
|
||||
### Emitters
|
||||
|
||||
Emitters **reduce** over content, taking in a list of all the transformed and filtered content and creating output files.
|
||||
|
||||
@ -242,7 +281,7 @@ An emitter plugin must define a `name` field, an `emit` function, and a `getQuar
|
||||
- `partialEmit` is an optional function that enables incremental builds. It receives information about which files have changed (`changeEvents`) and can selectively rebuild only the necessary files. This is useful for optimizing build times in development mode. If `partialEmit` is undefined, it will default to the `emit` function.
|
||||
- `getQuartzComponents` declares which Quartz components the emitter uses to construct its pages.
|
||||
|
||||
Creating new files can be done via regular Node [fs module](https://nodejs.org/api/fs.html) (i.e. `fs.cp` or `fs.writeFile`) or via the `write` function in `quartz/plugins/emitters/helpers.ts` if you are creating files that contain text. `write` has the following signature:
|
||||
Creating new files can be done via regular Node [fs module](https://nodejs.org/api/fs.html) (i.e. `fs.cp` or `fs.writeFile`) or via the `write` function in `@quartz-community/utils` if you are creating files that contain text. `write` has the following signature:
|
||||
|
||||
```ts
|
||||
export type WriteOptions = (data: {
|
||||
@ -262,26 +301,23 @@ This is a thin wrapper around writing to the appropriate output folder and ensur
|
||||
If you are creating an emitter plugin that needs to render components, there are three more things to be aware of:
|
||||
|
||||
- Your component should use `getQuartzComponents` to declare a list of `QuartzComponents` that it uses to construct the page. See the page on [[creating components]] for more information.
|
||||
- You can use the `renderPage` function defined in `quartz/components/renderPage.tsx` to render Quartz components into HTML.
|
||||
- If you need to render an HTML AST to JSX, you can use the `htmlToJsx` function from `quartz/util/jsx.ts`. An example of this can be found in `quartz/components/pages/Content.tsx`.
|
||||
- You can use the `renderPage` function defined in `@quartz-community/utils` to render Quartz components into HTML.
|
||||
- If you need to render an HTML AST to JSX, you can use the `htmlToJsx` function from `@quartz-community/utils`.
|
||||
|
||||
For example, the following is a simplified version of the content page plugin that renders every single page.
|
||||
|
||||
```tsx title="quartz/plugins/emitters/contentPage.tsx"
|
||||
```tsx
|
||||
import { QuartzEmitterPlugin, FullPageLayout, QuartzComponentProps } from "@quartz-community/types"
|
||||
import { renderPage, canonicalizeServer, pageResources, write } from "@quartz-community/utils"
|
||||
|
||||
export const ContentPage: QuartzEmitterPlugin = () => {
|
||||
// construct the layout
|
||||
const layout: FullPageLayout = {
|
||||
...sharedPageComponents,
|
||||
...defaultContentPageLayout,
|
||||
pageBody: Content(),
|
||||
}
|
||||
const { head, header, beforeBody, pageBody, afterBody, left, right, footer } = layout
|
||||
return {
|
||||
name: "ContentPage",
|
||||
getQuartzComponents() {
|
||||
getQuartzComponents(ctx) {
|
||||
const { head, header, beforeBody, pageBody, afterBody, left, right, footer } = ctx.cfg.layout
|
||||
return [head, ...header, ...beforeBody, pageBody, ...afterBody, ...left, ...right, footer]
|
||||
},
|
||||
async emit(ctx, content, resources, emit): Promise<FilePath[]> {
|
||||
async emit(ctx, content, resources): Promise<FilePath[]> {
|
||||
const cfg = ctx.cfg.configuration
|
||||
const fps: FilePath[] = []
|
||||
const allFiles = content.map((c) => c[1].data)
|
||||
@ -297,8 +333,9 @@ export const ContentPage: QuartzEmitterPlugin = () => {
|
||||
allFiles,
|
||||
}
|
||||
|
||||
const content = renderPage(cfg, slug, componentData, opts, externalResources)
|
||||
const fp = await emit({
|
||||
const content = renderPage(cfg, slug, componentData, {}, externalResources)
|
||||
const fp = await write({
|
||||
ctx,
|
||||
content,
|
||||
slug: file.data.slug!,
|
||||
ext: ".html",
|
||||
@ -312,7 +349,190 @@ export const ContentPage: QuartzEmitterPlugin = () => {
|
||||
}
|
||||
```
|
||||
|
||||
Note that it takes in a `FullPageLayout` as the options. It's made by combining a `SharedLayout` and a `PageLayout` both of which are provided through the `quartz.layout.ts` file.
|
||||
Page types define how a category of pages is rendered. They are the primary way to add support for new file types or virtual pages in Quartz.
|
||||
|
||||
> [!hint]
|
||||
> Look in `quartz/plugins` for more examples of plugins in Quartz as reference for your own plugins!
|
||||
```ts
|
||||
export interface QuartzPageTypePluginInstance {
|
||||
name: string
|
||||
priority?: number
|
||||
fileExtensions?: string[]
|
||||
match: PageMatcher
|
||||
generate?: PageGenerator
|
||||
layout: string
|
||||
frame?: string
|
||||
body: QuartzComponentConstructor
|
||||
}
|
||||
```
|
||||
|
||||
- `name`: A unique identifier for this page type.
|
||||
- `priority`: Controls matching order when multiple page types could match a slug. Higher priority page types are checked first. Default: `0`.
|
||||
- `fileExtensions`: Array of file extensions this page type handles (e.g. `[".canvas"]`, `[".base"]`). Content files (`.md`) are handled by the default content page type.
|
||||
- `match`: A function that determines whether a given slug/file should be rendered by this page type.
|
||||
- `generate`: An optional function that produces virtual pages (pages not backed by files on disk, such as folder listings or tag indices).
|
||||
- `layout`: The layout configuration key (e.g. `"content"`, `"folder"`, `"tag"`). This determines which `byPageType` entry in `quartz.config.yaml` provides the layout overrides for this page type.
|
||||
- `frame`: The [[layout#Page Frames|page frame]] to use for this page type. Controls the overall HTML structure (e.g. `"default"`, `"full-width"`, `"minimal"`, or a custom frame provided by your plugin). If not set, defaults to `"default"`. Can be overridden per-page-type via `layout.byPageType.<name>.template` in `quartz.config.yaml`.
|
||||
- `body`: The Quartz component constructor that renders the page body content.
|
||||
|
||||
### Providing Custom Frames
|
||||
|
||||
Plugins can ship their own [[layout#Page Frames|page frames]] — custom page layouts that control how the HTML structure (sidebars, header, content area, footer) is arranged. This is useful for page types that need fundamentally different layouts (e.g. a fullscreen canvas, a presentation mode, a dashboard).
|
||||
|
||||
To provide a custom frame:
|
||||
|
||||
**1. Create the frame file:**
|
||||
|
||||
```tsx title="src/frames/MyFrame.tsx"
|
||||
import type { PageFrame, PageFrameProps } from "@quartz-community/types"
|
||||
import type { ComponentChildren } from "preact"
|
||||
|
||||
export const MyFrame: PageFrame = {
|
||||
name: "my-frame",
|
||||
css: `
|
||||
.page[data-frame="my-frame"] > #quartz-body {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas: "center";
|
||||
}
|
||||
`,
|
||||
render({ componentData, pageBody: Content, footer: Footer }: PageFrameProps): unknown {
|
||||
const renderSlot = (C: (props: typeof componentData) => unknown): ComponentChildren =>
|
||||
C(componentData) as ComponentChildren
|
||||
return (
|
||||
<div class="center">
|
||||
{(Content as any)(componentData)}
|
||||
{(Footer as any)(componentData)}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Key requirements:
|
||||
|
||||
- `name`: A unique string identifier. This is what page types and YAML config reference.
|
||||
- `render()`: Receives all layout slots (header, sidebars, content, footer) and returns JSX for the inner page structure.
|
||||
- `css` (optional): Frame-specific CSS. Scope it with `.page[data-frame="my-frame"]` selectors to avoid conflicts.
|
||||
|
||||
**2. Re-export the frame:**
|
||||
|
||||
```ts title="src/frames/index.ts"
|
||||
export { MyFrame } from "./MyFrame"
|
||||
```
|
||||
|
||||
**3. Declare the frame in `package.json`:**
|
||||
|
||||
```json title="package.json"
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
},
|
||||
"./frames": {
|
||||
"import": "./dist/frames/index.js",
|
||||
"types": "./dist/frames/index.d.ts"
|
||||
}
|
||||
},
|
||||
"quartz": {
|
||||
"frames": {
|
||||
"MyFrame": { "exportName": "MyFrame" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `"frames"` field in the `"quartz"` manifest maps export names to frame metadata. The key (e.g. `"MyFrame"`) must match the export name in `src/frames/index.ts`.
|
||||
|
||||
**4. Add the frame entry point to your build config:**
|
||||
|
||||
```ts title="tsup.config.ts"
|
||||
export default defineConfig({
|
||||
entry: ["src/index.ts", "src/frames/index.ts"],
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
**5. Reference the frame in your page type:**
|
||||
|
||||
```ts
|
||||
export const MyPageType: QuartzPageTypePlugin = () => ({
|
||||
name: "MyPageType",
|
||||
frame: "my-frame", // References the frame by its name property
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
When a user installs your plugin, Quartz automatically loads the frame from the `./frames` export and registers it in the Frame Registry. The frame is then available by name in any page type or YAML config override.
|
||||
|
||||
> [!tip]
|
||||
> See the [`canvas-page`](https://github.com/quartz-community/canvas-page) plugin for a complete real-world example of a plugin-provided frame.
|
||||
|
||||
## Building and Testing
|
||||
|
||||
```shell
|
||||
# Build the plugin
|
||||
npm run build
|
||||
# or
|
||||
npx tsup
|
||||
```
|
||||
|
||||
## Installing Your Plugin
|
||||
|
||||
```shell
|
||||
# In your Quartz project
|
||||
npx quartz plugin add github:your-username/my-plugin
|
||||
```
|
||||
|
||||
This clones the plugin, builds it, and adds it to both `quartz.config.yaml` and `quartz.lock.json`. You can then configure it in your config:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:your-username/my-plugin
|
||||
enabled: true
|
||||
```
|
||||
|
||||
Or via TS override in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
import * as ExternalPlugin from "./.quartz/plugins"
|
||||
// ...
|
||||
transformers: [ExternalPlugin.MyPlugin()]
|
||||
```
|
||||
|
||||
### Development Workflow
|
||||
|
||||
During plugin development, you'll frequently install and uninstall your plugin to test changes. The following commands help manage this cycle:
|
||||
|
||||
```shell
|
||||
# Remove your plugin and clean up
|
||||
npx quartz plugin remove my-plugin
|
||||
|
||||
# Re-add after making changes
|
||||
npx quartz plugin add github:your-username/my-plugin
|
||||
```
|
||||
|
||||
If you've updated your `quartz.config.yaml` to reference a plugin that isn't installed yet, you can install it without manually running `add`:
|
||||
|
||||
```shell
|
||||
# Install all config-referenced plugins missing from the lockfile
|
||||
npx quartz plugin resolve
|
||||
|
||||
# Preview first without making changes
|
||||
npx quartz plugin resolve --dry-run
|
||||
```
|
||||
|
||||
To clean up plugins that are installed but no longer referenced in your config:
|
||||
|
||||
```shell
|
||||
# Remove orphaned plugins
|
||||
npx quartz plugin prune
|
||||
|
||||
# Preview first without making changes
|
||||
npx quartz plugin prune --dry-run
|
||||
```
|
||||
|
||||
> [!tip]
|
||||
> Both `resolve` and `prune` fall back to `quartz.config.default.yaml` if no `quartz.config.yaml` is present. This is useful for CI environments where the default config is the source of truth. See [[cli/plugin#prune|prune]] and [[cli/plugin#resolve|resolve]] for full details.
|
||||
|
||||
## Component Plugins
|
||||
|
||||
For plugins that provide visual components (like Explorer, Graph, Search), see the [[creating components|creating component plugins]] guide.
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
---
|
||||
title: "Building your Quartz"
|
||||
---
|
||||
|
||||
Once you've [[index#🪴 Get Started|initialized]] Quartz, let's see what it looks like locally:
|
||||
|
||||
```bash
|
||||
npx quartz build --serve
|
||||
```
|
||||
|
||||
This will start a local web server to run your Quartz on your computer. Open a web browser and visit `http://localhost:8080/` to view it.
|
||||
|
||||
> [!hint] Flags and options
|
||||
> For full help options, you can run `npx quartz build --help`.
|
||||
>
|
||||
> Most of these have sensible defaults but you can override them if you have a custom setup:
|
||||
>
|
||||
> - `-d` or `--directory`: the content folder. This is normally just `content`
|
||||
> - `-v` or `--verbose`: print out extra logging information
|
||||
> - `-o` or `--output`: the output folder. This is normally just `public`
|
||||
> - `--serve`: run a local hot-reloading server to preview your Quartz
|
||||
> - `--port`: what port to run the local preview server on
|
||||
> - `--concurrency`: how many threads to use to parse notes
|
||||
|
||||
> [!warning] Not to be used for production
|
||||
> Serve mode is intended for local previews only.
|
||||
> For production workloads, see the page on [[hosting]].
|
||||
65
docs/cli/build.md
Normal file
65
docs/cli/build.md
Normal file
@ -0,0 +1,65 @@
|
||||
---
|
||||
title: quartz build
|
||||
aliases:
|
||||
- build
|
||||
---
|
||||
|
||||
The `build` command transforms your Markdown content into a static HTML website. It processes your files through the configured plugins and outputs the final site to a directory of your choice.
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Shorthand | Description | Default |
|
||||
| ----------------- | --------- | --------------------------------------------------------- | ----------------- |
|
||||
| `--directory` | `-d` | The directory containing your Quartz project | Current directory |
|
||||
| `--verbose` | `-v` | Enable detailed logging for debugging | `false` |
|
||||
| `--output` | `-o` | The directory where the built site will be saved | `public` |
|
||||
| `--serve` | | Start a local development server | `false` |
|
||||
| `--watch` | | Rebuild the site when files change | `false` |
|
||||
| `--port` | | The port for the development server | `8080` |
|
||||
| `--wsPort` | | The port for the WebSocket hot-reload server | `3001` |
|
||||
| `--baseDir` | | Set a base directory for the site (e.g. for GitHub Pages) | `/` |
|
||||
| `--remoteDevHost` | | The hostname to use for the development server | `localhost` |
|
||||
| `--bundleInfo` | | Output a JSON file with bundle size information | `false` |
|
||||
| `--concurrency` | | Number of worker threads to use for building | CPU core count |
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Build
|
||||
|
||||
Generate your site into the `public` folder.
|
||||
|
||||
```shell
|
||||
npx quartz build
|
||||
```
|
||||
|
||||
### Development Mode
|
||||
|
||||
Start a local server and watch for changes. This is the most common way to preview your site while writing.
|
||||
|
||||
```shell
|
||||
npx quartz build --serve
|
||||
```
|
||||
|
||||
### Custom Output and Port
|
||||
|
||||
Build to a specific folder and run the server on a different port.
|
||||
|
||||
```shell
|
||||
npx quartz build --serve --output dist --port 3000
|
||||
```
|
||||
|
||||
### Performance Tuning
|
||||
|
||||
If you have a very large vault, you can limit the number of concurrent workers to save memory.
|
||||
|
||||
```shell
|
||||
npx quartz build --concurrency 2
|
||||
```
|
||||
|
||||
## Development Server
|
||||
|
||||
The `--serve` flag starts a local web server. This server is intended for development and previewing only. It is not designed for production use. For information on how to deploy your site, see [[hosting]].
|
||||
|
||||
### Hot Reloading
|
||||
|
||||
When running with `--serve`, Quartz automatically enables `--watch`. It uses a WebSocket connection (on the port specified by `--wsPort`) to notify your browser when a file has changed. The browser will then automatically refresh to show the latest version of your content.
|
||||
84
docs/cli/create.md
Normal file
84
docs/cli/create.md
Normal file
@ -0,0 +1,84 @@
|
||||
---
|
||||
title: quartz create
|
||||
---
|
||||
|
||||
The `create` command initializes a new Quartz project. It helps you set up your content folder, choose a configuration template, set your site's base URL, and configure how Quartz should handle your Markdown files.
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Shorthand | Description |
|
||||
| ------------- | --------- | --------------------------------------------------------------------- |
|
||||
| `--template` | `-t` | Configuration template (`default`, `obsidian`, `ttrpg`, or `blog`) |
|
||||
| `--directory` | `-d` | The directory where Quartz will be initialized |
|
||||
| `--source` | `-s` | The source directory of your Markdown files |
|
||||
| `--strategy` | `-X` | How to handle the source files (`new`, `copy`, or `symlink`) |
|
||||
| `--links` | `-l` | How to resolve internal links (`absolute`, `shortest`, or `relative`) |
|
||||
| `--baseUrl` | `-b` | Base URL for your site (e.g. `mysite.github.io/quartz`) |
|
||||
| `--verbose` | `-v` | Enable detailed logging |
|
||||
|
||||
## Templates
|
||||
|
||||
When you run `quartz create`, you can choose a configuration template that pre-configures Quartz for your use case:
|
||||
|
||||
- **Default**: A clean Quartz setup with sensible defaults. Best for starting from scratch.
|
||||
- **Obsidian**: Optimized for Obsidian vaults with full Obsidian Flavored Markdown support (wikilinks, callouts, mermaid diagrams, etc.). Automatically sets link resolution to `shortest` and skips the link resolution prompt.
|
||||
- **TTRPG**: Builds on the Obsidian template with the addition of the [Leaflet map plugin](https://github.com/quartz-community/external-quartz-leaflet-map-plugin) and [ITS Theme](https://github.com/saberzero1/quartz-themes) (`its-theme.ttrpg-dnd`). Great for D&D and TTRPG wikis. Also skips the link resolution prompt.
|
||||
- **Blog**: A blog-focused setup with [recent notes](https://github.com/quartz-community/recent-notes) enabled (showing the 5 most recent posts with tags) and [comments](https://github.com/quartz-community/comments) enabled via giscus. You'll need to fill in the `TODO:` placeholder values in `quartz.config.yaml` with your own giscus repository details.
|
||||
|
||||
## Base URL
|
||||
|
||||
During setup, Quartz will ask for the base URL of your site. This is the URL where your site will be deployed (e.g. `mysite.github.io/quartz`).
|
||||
|
||||
- Do **not** include the protocol (`https://`) — if you do, it will be automatically stripped.
|
||||
- Trailing slashes are also removed automatically.
|
||||
- See [[configuration]] for more details on how `baseUrl` is used.
|
||||
|
||||
## Strategies
|
||||
|
||||
When you run `quartz create`, you must choose a strategy for your content:
|
||||
|
||||
- **new**: Creates a fresh, empty content folder. Use this if you are starting a new project from scratch.
|
||||
- **copy**: Copies all files from your source directory into the Quartz content folder. This is the safest option for existing vaults as it doesn't touch your original files.
|
||||
- **symlink**: Creates a symbolic link from the Quartz content folder to your source directory. Any changes you make in your source directory (e.g. in Obsidian) will be immediately reflected in Quartz.
|
||||
- **move**: Moves your files from the source directory into the Quartz content folder.
|
||||
|
||||
## Link Resolution
|
||||
|
||||
Quartz needs to know how to interpret the internal links in your Markdown files:
|
||||
|
||||
- **shortest**: Resolves links to the closest matching file name. This is the default for Obsidian.
|
||||
- **absolute**: Resolves links relative to the root of your content folder.
|
||||
- **relative**: Resolves links relative to the current file's location.
|
||||
|
||||
> [!note]
|
||||
> When using the **Obsidian** or **TTRPG** templates, link resolution is automatically set to `shortest` and the prompt is skipped.
|
||||
|
||||
## Interactive Walkthrough
|
||||
|
||||
If you run `npx quartz create` without any arguments, it will guide you through an interactive setup:
|
||||
|
||||
1. **Choose a template**: Select a configuration template (`Default`, `Obsidian`, `TTRPG`, or `Blog`).
|
||||
2. **Select a strategy**: Choose between `new`, `copy`, or `symlink`.
|
||||
3. **Enter base URL**: Provide the URL where your site will be hosted.
|
||||
4. **Select link resolution**: Choose how your links are formatted (skipped for Obsidian and TTRPG templates).
|
||||
5. **Finish**: Quartz will set up the directory structure and create your configuration.
|
||||
|
||||
## Example: Importing an Obsidian Vault
|
||||
|
||||
To create a Quartz project that links directly to an existing Obsidian vault:
|
||||
|
||||
```shell
|
||||
npx quartz create --template obsidian --strategy symlink --source ~/Documents/MyVault
|
||||
```
|
||||
|
||||
This command tells Quartz to use the Obsidian template (with full OFM support and shortest link resolution), look at your vault in `~/Documents/MyVault`, and use symbolic links so changes are synced.
|
||||
|
||||
## Example: Setting Up a Blog
|
||||
|
||||
To quickly set up a blog with recent notes and comments:
|
||||
|
||||
```shell
|
||||
npx quartz create --template blog --strategy new --baseUrl myblog.github.io
|
||||
```
|
||||
|
||||
After setup, edit `quartz.config.yaml` to fill in your giscus repository details in the comments plugin section.
|
||||
46
docs/cli/index.md
Normal file
46
docs/cli/index.md
Normal file
@ -0,0 +1,46 @@
|
||||
---
|
||||
title: CLI Reference
|
||||
---
|
||||
|
||||
The Quartz CLI is the primary way to interact with your Quartz project. It provides commands for creating new projects, building static sites, syncing with GitHub, and managing plugins.
|
||||
|
||||
You can run the CLI using `npx quartz`.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Command | Description | Example |
|
||||
| --------- | ------------------------------------------------------- | ------------------------ |
|
||||
| `create` | Initialize a new Quartz project with template selection | `npx quartz create` |
|
||||
| `build` | Generate static HTML files | `npx quartz build` |
|
||||
| `sync` | Sync content with GitHub | `npx quartz sync` |
|
||||
| `upgrade` | Upgrade Quartz to the latest version | `npx quartz upgrade` |
|
||||
| `update` | Update installed plugins | `npx quartz update` |
|
||||
| `plugin` | Manage Quartz plugins | `npx quartz plugin list` |
|
||||
| `tui` | Launch the interactive plugin manager | `npx quartz tui` |
|
||||
|
||||
## Commands
|
||||
|
||||
- [[cli/create|create]]: Initialize a new Quartz project with a choice of templates (default, obsidian, ttrpg, blog) and base URL configuration.
|
||||
- [[cli/build|build]]: Build your Quartz site into static HTML. Includes a development server.
|
||||
- [[cli/sync|sync]]: Push and pull changes between your local machine and GitHub.
|
||||
- [[cli/upgrade|upgrade]]: Upgrade the Quartz framework to the latest version.
|
||||
- [[cli/update|update]]: Update installed plugins to their latest versions.
|
||||
- [[cli/restore|restore]]: Recover your content folder from the local cache.
|
||||
- [[cli/migrate|migrate]]: Convert older configuration files to the new YAML format.
|
||||
- [[cli/plugin|plugin]]: Install, add, remove, prune, resolve, and configure plugins from the command line.
|
||||
- [[cli/tui|tui]]: Use a terminal interface to manage plugins and layout.
|
||||
|
||||
## Help and Versioning
|
||||
|
||||
To see a full list of available flags for any command, use the `--help` flag.
|
||||
|
||||
```shell
|
||||
npx quartz --help
|
||||
npx quartz build --help
|
||||
```
|
||||
|
||||
To check which version of Quartz you are currently running, use the `--version` flag.
|
||||
|
||||
```shell
|
||||
npx quartz --version
|
||||
```
|
||||
32
docs/cli/migrate.md
Normal file
32
docs/cli/migrate.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: quartz migrate
|
||||
---
|
||||
|
||||
The `migrate` command helps you transition your project from Quartz 4 to Quartz v5 by converting your configuration files.
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this command if you have an existing Quartz 4 project and want to upgrade to the new YAML-based configuration system introduced in v5.
|
||||
|
||||
## What it Does
|
||||
|
||||
When you run `npx quartz migrate`, the CLI performs several automated steps:
|
||||
|
||||
1. **Read Configuration**: It parses your existing `quartz.config.ts` and `quartz.layout.ts` files.
|
||||
2. **Map Plugins**: It identifies the plugins you are using and maps them to their v5 equivalents.
|
||||
3. **Generate YAML**: It creates a new `quartz.config.yaml` file that contains all your settings, theme colors, and plugin configurations.
|
||||
4. **Backup**: It keeps your old `.ts` files so you can refer back to them if needed.
|
||||
|
||||
```shell
|
||||
npx quartz migrate
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
After running the migration, you should check the following:
|
||||
|
||||
- **Theme Colors**: Ensure your custom colors were correctly transferred to the `theme` section of `quartz.config.yaml`.
|
||||
- **Plugin Options**: Verify that any custom options you passed to plugins (like `linkClickBehavior`) are present in the new config.
|
||||
- **Layout**: Check that your component order in the `layout` section matches your previous setup.
|
||||
|
||||
For a comprehensive guide on the entire migration process, including manual steps, see [[getting-started/migrating]].
|
||||
219
docs/cli/plugin.md
Normal file
219
docs/cli/plugin.md
Normal file
@ -0,0 +1,219 @@
|
||||
---
|
||||
title: quartz plugin
|
||||
---
|
||||
|
||||
The `plugin` command is the heart of the Quartz v5 plugin management system. it allows you to install, configure, and update plugins directly from the command line.
|
||||
|
||||
All plugins are stored in the `.quartz/plugins/` directory, and their versions are tracked in `quartz.lock.json`.
|
||||
|
||||
## Subcommands
|
||||
|
||||
### list
|
||||
|
||||
List all currently installed plugins and their versions.
|
||||
|
||||
```shell
|
||||
npx quartz plugin list
|
||||
```
|
||||
|
||||
### add
|
||||
|
||||
Add a new plugin from a Git repository.
|
||||
|
||||
```shell
|
||||
npx quartz plugin add github:username/repo
|
||||
```
|
||||
|
||||
To install from a specific branch or ref, append `#ref` to the source:
|
||||
|
||||
```shell
|
||||
npx quartz plugin add github:username/repo#my-branch
|
||||
npx quartz plugin add git+https://github.com/username/repo.git#my-branch
|
||||
npx quartz plugin add https://github.com/username/repo.git#my-branch
|
||||
```
|
||||
|
||||
You can also add a plugin from a local directory. This is useful for local development or airgapped environments:
|
||||
|
||||
```shell
|
||||
npx quartz plugin add ./path/to/my-plugin
|
||||
npx quartz plugin add ../sibling-plugin
|
||||
npx quartz plugin add /absolute/path/to/plugin
|
||||
```
|
||||
|
||||
Local plugins are symlinked into `.quartz/plugins/`, so any changes you make to the source directory are reflected immediately without re-installing.
|
||||
|
||||
When a branch is specified, it is stored in the lockfile. All subsequent commands (`install`, `update`, `restore`, `check`, `resolve`) will respect that branch automatically.
|
||||
|
||||
### remove
|
||||
|
||||
Remove an installed plugin.
|
||||
|
||||
```shell
|
||||
npx quartz plugin remove plugin-name
|
||||
```
|
||||
|
||||
### install
|
||||
|
||||
Install all plugins listed in your `quartz.lock.json` file. This is useful when setting up the project on a new machine.
|
||||
|
||||
```shell
|
||||
npx quartz plugin install
|
||||
```
|
||||
|
||||
### update
|
||||
|
||||
Update specific plugins or all plugins to their latest versions.
|
||||
|
||||
```shell
|
||||
npx quartz plugin update plugin-name
|
||||
npx quartz plugin update # updates all
|
||||
```
|
||||
|
||||
### restore
|
||||
|
||||
Restore plugins to the exact versions specified in the lockfile. Unlike `install`, this will downgrade plugins if the lockfile specifies an older version. This is recommended for CI/CD environments.
|
||||
|
||||
```shell
|
||||
npx quartz plugin restore
|
||||
```
|
||||
|
||||
### enable / disable
|
||||
|
||||
Toggle a plugin's status in your `quartz.config.yaml` without removing its files.
|
||||
|
||||
```shell
|
||||
npx quartz plugin enable plugin-name
|
||||
npx quartz plugin disable plugin-name
|
||||
```
|
||||
|
||||
### config
|
||||
|
||||
View or modify the configuration for a specific plugin.
|
||||
|
||||
```shell
|
||||
# View config
|
||||
npx quartz plugin config plugin-name
|
||||
|
||||
# Set a value
|
||||
npx quartz plugin config plugin-name --set key=value
|
||||
```
|
||||
|
||||
### check
|
||||
|
||||
Check if any of your installed plugins have updates available.
|
||||
|
||||
```shell
|
||||
npx quartz plugin check
|
||||
```
|
||||
|
||||
### prune
|
||||
|
||||
Remove installed plugins that are no longer referenced in your `quartz.config.yaml`. This is useful for cleaning up after removing plugin entries from your configuration.
|
||||
|
||||
```shell
|
||||
npx quartz plugin prune
|
||||
```
|
||||
|
||||
Use `--dry-run` to preview which plugins would be removed without making changes:
|
||||
|
||||
```shell
|
||||
npx quartz plugin prune --dry-run
|
||||
```
|
||||
|
||||
### resolve
|
||||
|
||||
Install plugins that are listed in your `quartz.config.yaml` but missing from the lockfile. This is the inverse of `prune` — it ensures your installed plugins match your configuration.
|
||||
|
||||
```shell
|
||||
npx quartz plugin resolve
|
||||
```
|
||||
|
||||
Use `--dry-run` to preview which plugins would be installed without making changes:
|
||||
|
||||
```shell
|
||||
npx quartz plugin resolve --dry-run
|
||||
```
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Adding and Enabling a Plugin
|
||||
|
||||
To add a new plugin and start using it:
|
||||
|
||||
1. Add the plugin: `npx quartz plugin add github:quartz-community/example`
|
||||
2. Enable it: `npx quartz plugin enable example`
|
||||
|
||||
### Updating Everything
|
||||
|
||||
To keep your plugins fresh:
|
||||
|
||||
```shell
|
||||
npx quartz plugin update
|
||||
```
|
||||
|
||||
### Managing Configuration
|
||||
|
||||
If you want to change a plugin setting without opening the YAML file:
|
||||
|
||||
```shell
|
||||
npx quartz plugin config explorer --set useSavedState=true
|
||||
```
|
||||
|
||||
### Cleaning Up Unused Plugins
|
||||
|
||||
If you've removed plugins from your config and want to clean up leftover files:
|
||||
|
||||
```shell
|
||||
npx quartz plugin prune --dry-run # preview first
|
||||
npx quartz plugin prune # remove orphaned plugins
|
||||
```
|
||||
|
||||
### Setting Up from Config
|
||||
|
||||
When setting up on a new machine or in CI, resolve any plugins referenced in your config that aren't yet installed:
|
||||
|
||||
```shell
|
||||
npx quartz plugin resolve
|
||||
```
|
||||
|
||||
### Testing with Branches
|
||||
|
||||
If a plugin author has a fix or feature on a separate branch, you can install it directly without waiting for a release to the default branch:
|
||||
|
||||
```shell
|
||||
# Install from a feature branch
|
||||
npx quartz plugin add github:username/repo#fix/some-bug
|
||||
|
||||
# Later, switch back to the default branch by re-adding without a ref
|
||||
npx quartz plugin remove repo
|
||||
npx quartz plugin add github:username/repo
|
||||
```
|
||||
|
||||
The branch ref is tracked in `quartz.lock.json`, so `update` and `check` will continue to follow the specified branch until the plugin is re-added without one.
|
||||
|
||||
Both `prune` and `resolve` will fall back to `quartz.config.default.yaml` if no `quartz.config.yaml` is present.
|
||||
|
||||
### Local Plugin Development
|
||||
|
||||
For local plugin development or airgapped environments, you can add a plugin from a local directory:
|
||||
|
||||
```shell
|
||||
npx quartz plugin add ./my-local-plugin
|
||||
```
|
||||
|
||||
Local plugins are symlinked into `.quartz/plugins/`, so changes reflect immediately. When you run `update`, local plugins are rebuilt (npm install + npm run build) without any git operations. The `check` command will show local plugins with a "local" status instead of checking for remote updates.
|
||||
|
||||
To switch a local plugin back to a git source:
|
||||
|
||||
```shell
|
||||
npx quartz plugin remove my-local-plugin
|
||||
npx quartz plugin add github:username/my-local-plugin
|
||||
```
|
||||
|
||||
## Interactive Mode
|
||||
|
||||
Running the plugin command without any subcommand will launch the [[cli/tui|TUI]], which provides a visual interface for all these operations.
|
||||
|
||||
```shell
|
||||
npx quartz plugin
|
||||
```
|
||||
29
docs/cli/restore.md
Normal file
29
docs/cli/restore.md
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
title: quartz restore
|
||||
---
|
||||
|
||||
The `restore` command is a safety mechanism that allows you to recover your content folder from a local cache.
|
||||
|
||||
## When to Use
|
||||
|
||||
You should use `restore` if:
|
||||
|
||||
- A `quartz upgrade` failed and corrupted your content.
|
||||
- You accidentally deleted files in your content folder.
|
||||
- You encountered complex merge conflicts that you want to undo.
|
||||
|
||||
## How it Works
|
||||
|
||||
Quartz maintains a hidden cache of your content folder. Every time you run certain commands, Quartz ensures that a backup of your Markdown files exists. The `restore` command simply copies these files back into your main content directory.
|
||||
|
||||
```shell
|
||||
npx quartz restore
|
||||
```
|
||||
|
||||
## Example Workflow
|
||||
|
||||
If an update fails and leaves your project in a broken state:
|
||||
|
||||
1. **Restore**: Run `npx quartz restore` to bring back your content.
|
||||
2. **Clean**: Use Git to reset any other broken code files.
|
||||
3. **Retry**: Attempt the update again or manually apply the changes you need.
|
||||
74
docs/cli/sync.md
Normal file
74
docs/cli/sync.md
Normal file
@ -0,0 +1,74 @@
|
||||
---
|
||||
title: quartz sync
|
||||
---
|
||||
|
||||
The `sync` command automates the process of pushing your local changes to GitHub and pulling updates from your remote repository. It simplifies the Git workflow for users who want to keep their site updated without running manual Git commands.
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Shorthand | Description | Default |
|
||||
| ------------- | --------- | ------------------------------------ | ----------------- |
|
||||
| `--directory` | `-d` | The directory of your Quartz project | Current directory |
|
||||
| `--verbose` | `-v` | Enable detailed logging | `false` |
|
||||
| `--commit` | | Whether to commit changes | `true` |
|
||||
| `--no-commit` | | Skip committing changes | `false` |
|
||||
| `--message` | `-m` | Custom commit message | `update content` |
|
||||
| `--push` | | Whether to push changes to remote | `true` |
|
||||
| `--no-push` | | Skip pushing changes | `false` |
|
||||
| `--pull` | | Whether to pull changes from remote | `true` |
|
||||
| `--no-pull` | | Skip pulling changes | `false` |
|
||||
|
||||
## Workflow
|
||||
|
||||
When you run `npx quartz sync`, Quartz performs the following steps:
|
||||
|
||||
1. **Pull**: It fetches and merges changes from your remote GitHub repository.
|
||||
2. **Add**: It stages all new and modified files in your project.
|
||||
3. **Commit**: It creates a new commit with your changes.
|
||||
4. **Push**: It sends your new commit to GitHub.
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Regular Sync
|
||||
|
||||
The most common usage is to simply run the command with no flags. This pulls, commits, and pushes everything.
|
||||
|
||||
```shell
|
||||
npx quartz sync
|
||||
```
|
||||
|
||||
### First Sync
|
||||
|
||||
If you have just set up a new repository and haven't pushed anything yet, you might want to skip the pull step.
|
||||
|
||||
```shell
|
||||
npx quartz sync --no-pull
|
||||
```
|
||||
|
||||
### Custom Commit Message
|
||||
|
||||
You can provide a more descriptive message for your changes.
|
||||
|
||||
```shell
|
||||
npx quartz sync --message "add new notes about gardening"
|
||||
```
|
||||
|
||||
### Sync from Another Device
|
||||
|
||||
If you are working on a different computer and just want to get the latest changes without pushing anything back yet.
|
||||
|
||||
```shell
|
||||
npx quartz sync --no-push --no-commit
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Git Buffer
|
||||
|
||||
If you have a very large number of changes, Git might occasionally fail due to buffer limits. If this happens, try syncing smaller batches of files or increasing your Git post buffer size.
|
||||
|
||||
### Autostash
|
||||
|
||||
Quartz uses `git pull --rebase --autostash` internally. This means if you have unstaged changes when you run `sync`, Quartz will temporarily hide them, pull the remote changes, and then bring your changes back. If a conflict occurs during this process, you will need to resolve it manually using standard Git tools.
|
||||
|
||||
For more information on initial setup, see [[getting-started/installation]].
|
||||
64
docs/cli/tui.md
Normal file
64
docs/cli/tui.md
Normal file
@ -0,0 +1,64 @@
|
||||
---
|
||||
title: quartz tui
|
||||
---
|
||||
|
||||
The `tui` command launches an interactive terminal user interface for managing your Quartz project. It provides a visual way to manage plugins, arrange your site layout, and edit general settings.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To use the TUI, you must have the following:
|
||||
|
||||
1. **Bun**: The TUI requires the Bun runtime. You can find installation instructions at [bun.sh](https://bun.sh/docs/installation).
|
||||
2. **TUI Plugin**: You must install the TUI plugin in your Quartz project.
|
||||
|
||||
### Installation
|
||||
|
||||
Run the following command to add the TUI plugin:
|
||||
|
||||
```shell
|
||||
npx quartz plugin add github:quartz-community/tui
|
||||
```
|
||||
|
||||
## Interface Panels
|
||||
|
||||
The TUI is divided into three main panels that you can navigate between.
|
||||
|
||||
### Plugins Panel
|
||||
|
||||
This panel allows you to browse all available and installed plugins. You can:
|
||||
|
||||
- Enable or disable plugins with a single keystroke.
|
||||
- Configure plugin-specific settings.
|
||||
- Install new plugins from the community or remove existing ones.
|
||||
|
||||
### Layout Panel
|
||||
|
||||
The Layout panel is where you define where components appear on your site. You can:
|
||||
|
||||
- Move components between different sections (e.g. `left`, `right`, `beforeBody`).
|
||||
- Reorder components within a section to change their vertical stack.
|
||||
- Set priorities for components to control their placement.
|
||||
|
||||
### Settings Panel
|
||||
|
||||
This panel provides a central place to edit your `quartz.config.yaml` settings. You can update:
|
||||
|
||||
- `pageTitle`
|
||||
- Theme colors and fonts
|
||||
- Analytics configuration
|
||||
- Deployment settings
|
||||
|
||||
## Navigation
|
||||
|
||||
The TUI uses standard terminal navigation keys:
|
||||
|
||||
- **Arrow Keys**: Move between items and panels.
|
||||
- **Enter**: Select an item or confirm a change.
|
||||
- **Esc**: Go back or cancel an action.
|
||||
- **Tab**: Cycle through different interface elements.
|
||||
|
||||
## Important Note
|
||||
|
||||
All changes made within the TUI are written directly to your `quartz.config.yaml` file. It is a good practice to have a clean Git state before using the TUI so you can easily review and undo any changes it makes.
|
||||
|
||||
For command-line based plugin management, see [[cli/plugin|quartz plugin]].
|
||||
38
docs/cli/update.md
Normal file
38
docs/cli/update.md
Normal file
@ -0,0 +1,38 @@
|
||||
---
|
||||
title: quartz update
|
||||
---
|
||||
|
||||
The `update` command updates your installed plugins to their latest versions. It is a convenient shortcut for `npx quartz plugin update`.
|
||||
|
||||
## Usage
|
||||
|
||||
Update all installed plugins:
|
||||
|
||||
```shell
|
||||
npx quartz update
|
||||
```
|
||||
|
||||
Update specific plugins by name:
|
||||
|
||||
```shell
|
||||
npx quartz update my-plugin another-plugin
|
||||
```
|
||||
|
||||
## How it Works
|
||||
|
||||
For each plugin, `update` fetches the latest commit from the plugin's remote repository and rebuilds it. If a plugin was installed from a specific branch (e.g., `github:user/repo#my-branch`), updates will track that branch instead of the default branch. Local plugins (added from a file path) are rebuilt without any git operations. The lockfile (`quartz.lock.json`) is updated with the new commit hashes.
|
||||
|
||||
This is functionally identical to running:
|
||||
|
||||
```shell
|
||||
npx quartz plugin update
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
The `update` command supports the standard [[cli/index|common flags]] (`--directory`, `--verbose`).
|
||||
|
||||
## See Also
|
||||
|
||||
- [[cli/upgrade|quartz upgrade]] — upgrade the Quartz framework itself
|
||||
- [[cli/plugin|quartz plugin]] — full plugin management (install, remove, enable, disable, etc.)
|
||||
46
docs/cli/upgrade.md
Normal file
46
docs/cli/upgrade.md
Normal file
@ -0,0 +1,46 @@
|
||||
---
|
||||
title: quartz upgrade
|
||||
---
|
||||
|
||||
The `upgrade` command upgrades the Quartz framework itself to the latest version by pulling changes from the official Quartz repository.
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
npx quartz upgrade
|
||||
```
|
||||
|
||||
## How it Works
|
||||
|
||||
When you run `npx quartz upgrade`, Quartz performs the following steps:
|
||||
|
||||
1. **Backs up your content** — your content folder is cached locally to prevent data loss.
|
||||
2. **Pulls the latest Quartz code** — fetches and merges from the official upstream repository (`upstream/v5`) using Git.
|
||||
3. **Shows version changes** — displays the version transition (e.g., `v5.0.0 → v5.1.0`) or confirms you're already up to date.
|
||||
4. **Updates dependencies** — runs `npm install` to ensure all packages match the new version.
|
||||
5. **Restores plugins** — reinstalls plugins from `quartz.lock.json` to ensure compatibility.
|
||||
6. **Checks plugin compatibility** — verifies that installed plugins are compatible with the new Quartz version.
|
||||
|
||||
## Handling Conflicts
|
||||
|
||||
Because Quartz allows you to customize almost every part of the code, upgrades can sometimes result in merge conflicts. This happens if you have modified a file that the Quartz team has also updated.
|
||||
|
||||
If a conflict occurs:
|
||||
|
||||
1. Git will mark the conflicting sections in the affected files.
|
||||
2. You will need to open these files and manually choose which changes to keep.
|
||||
3. After resolving the conflicts, you can commit the changes.
|
||||
|
||||
## Recovery
|
||||
|
||||
If an upgrade goes wrong or leaves your project in an unusable state, you can use the [[cli/restore|restore]] command to recover your content from the local cache.
|
||||
|
||||
## Flags
|
||||
|
||||
The `upgrade` command supports the standard [[cli/index|common flags]] (`--directory`, `--verbose`).
|
||||
|
||||
## See Also
|
||||
|
||||
- [[cli/update|quartz update]] — update installed plugins
|
||||
- [[getting-started/upgrading|Upgrading Quartz]] — detailed upgrading guide
|
||||
- [[cli/restore|quartz restore]] — recover content from cache
|
||||
60
docs/community.md
Normal file
60
docs/community.md
Normal file
@ -0,0 +1,60 @@
|
||||
---
|
||||
title: Community
|
||||
---
|
||||
|
||||
Quartz has a vibrant community of users and contributors. This page highlights community-created plugins, tools, and resources that extend Quartz.
|
||||
|
||||
> [!tip] Contributing
|
||||
> Know of a great community resource? Submit a pull request to add it to this page!
|
||||
|
||||
## Community Plugins
|
||||
|
||||
Third-party plugins that extend Quartz functionality. Install them with the [[cli/plugin|plugin CLI]]:
|
||||
|
||||
```bash
|
||||
npx quartz plugin install <github-url>
|
||||
```
|
||||
|
||||
<!-- Add community plugins here as they become available -->
|
||||
<!-- Format: - **[Plugin Name](link)** — Brief description -->
|
||||
|
||||
_No community plugins listed yet. Be the first to share yours!_
|
||||
|
||||
## Tools & Integrations
|
||||
|
||||
Tools, scripts, and integrations built by the community to work with Quartz.
|
||||
|
||||
<!-- Add tools here -->
|
||||
<!-- Format: - **[Tool Name](link)** — Brief description -->
|
||||
|
||||
_No community tools listed yet._
|
||||
|
||||
## Templates & Themes
|
||||
|
||||
Custom themes, CSS snippets, and starter templates for Quartz sites.
|
||||
|
||||
<!-- Add templates/themes here -->
|
||||
<!-- Format: - **[Name](link)** — Brief description -->
|
||||
|
||||
_No community templates listed yet._
|
||||
|
||||
## Guides & Tutorials
|
||||
|
||||
Community-written guides, blog posts, and tutorials about using Quartz.
|
||||
|
||||
<!-- Add guides here -->
|
||||
<!-- Format: - **[Title](link)** by Author — Brief description -->
|
||||
|
||||
_No community guides listed yet._
|
||||
|
||||
## Related Projects
|
||||
|
||||
Projects and tools in the digital garden / PKM ecosystem that pair well with Quartz.
|
||||
|
||||
- **[Obsidian](https://obsidian.md/)** — Knowledge base and note-taking app (recommended editor for Quartz content)
|
||||
|
||||
---
|
||||
|
||||
Looking to see sites built with Quartz? Check out the [[showcase|Quartz Showcase]].
|
||||
|
||||
Want to chat with other Quartz users? [Join the Discord community](https://discord.gg/cRFFHYye7t).
|
||||
@ -2,18 +2,21 @@
|
||||
title: Configuration
|
||||
---
|
||||
|
||||
Quartz is meant to be extremely configurable, even if you don't know any coding. Most of the configuration you should need can be done by just editing `quartz.config.ts` or changing [[layout|the layout]] in `quartz.layout.ts`.
|
||||
Quartz is meant to be extremely configurable, even if you don't know any coding. Most of the configuration you should need can be done by just editing `quartz.config.yaml`.
|
||||
|
||||
> [!tip]
|
||||
> If you edit Quartz configuration using a text-editor that has TypeScript language support like VSCode, it will warn you when you you've made an error in your configuration, helping you avoid configuration mistakes!
|
||||
> If you edit `quartz.config.yaml` using a text-editor with YAML language support like VSCode, it will warn you when you've made an error in your configuration, helping you avoid configuration mistakes!
|
||||
|
||||
The configuration of Quartz can be broken down into two main parts:
|
||||
|
||||
```ts title="quartz.config.ts"
|
||||
const config: QuartzConfig = {
|
||||
configuration: { ... },
|
||||
plugins: { ... },
|
||||
}
|
||||
```yaml title="quartz.config.yaml"
|
||||
configuration:
|
||||
pageTitle: "My Site"
|
||||
# ... general configuration
|
||||
plugins:
|
||||
- source: github:quartz-community/some-plugin
|
||||
enabled: true
|
||||
# ... plugin entries
|
||||
```
|
||||
|
||||
## General Configuration
|
||||
@ -39,8 +42,9 @@ This part of the configuration concerns anything that can affect the whole site.
|
||||
- `{ provider: 'rybbit', siteId: 'my-rybbit-id' }` (managed) or `{ provider: 'rybbit', siteId: 'my-rybbit-id', host: 'my-rybbit-domain.com' }` (self-hosted) use [Rybbit](https://rybbit.com);
|
||||
- `locale`: used for [[i18n]] and date formatting
|
||||
- `baseUrl`: this is used for sitemaps and RSS feeds that require an absolute URL to know where the canonical 'home' of your site lives. This is normally the deployed URL of your site (e.g. `quartz.jzhao.xyz` for this site). Do not include the protocol (i.e. `https://`) or any leading or trailing slashes.
|
||||
- You will be prompted to set this during [[cli/create|`npx quartz create`]]. The CLI automatically strips any `https://` or `http://` protocol prefixes and trailing slashes for you.
|
||||
- This should also include the subpath if you are [[hosting]] on GitHub pages without a custom domain. For example, if my repository is `jackyzha0/quartz`, GitHub pages would deploy to `https://jackyzha0.github.io/quartz` and the `baseUrl` would be `jackyzha0.github.io/quartz`.
|
||||
- Note that Quartz 4 will avoid using this as much as possible and use relative URLs whenever it can to make sure your site works no matter _where_ you end up actually deploying it.
|
||||
- Note that Quartz 5 will avoid using this as much as possible and use relative URLs whenever it can to make sure your site works no matter _where_ you end up actually deploying it.
|
||||
- `ignorePatterns`: a list of [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details.
|
||||
- `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings.
|
||||
- `theme`: configure how the site looks.
|
||||
@ -67,47 +71,124 @@ You can think of Quartz plugins as a series of transformations over content.
|
||||
|
||||
![[quartz transform pipeline.png]]
|
||||
|
||||
```ts title="quartz.config.ts"
|
||||
plugins: {
|
||||
transformers: [...],
|
||||
filters: [...],
|
||||
emitters: [...],
|
||||
}
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/created-modified-date
|
||||
enabled: true
|
||||
order: 10 # controls execution order
|
||||
- source: github:quartz-community/syntax-highlighting
|
||||
enabled: true
|
||||
order: 20
|
||||
# ... more plugins
|
||||
```
|
||||
|
||||
Plugins are categorized by their type (transformer, filter, emitter, pageType) based on their manifest. The `order` field controls execution order within each category.
|
||||
|
||||
> [!note]
|
||||
> For advanced TS override of plugin configuration, you can modify `quartz.ts`:
|
||||
>
|
||||
> ```ts title="quartz.ts"
|
||||
> import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||
>
|
||||
> const config = await loadQuartzConfig({
|
||||
> // override any configuration field here
|
||||
> })
|
||||
> export default config
|
||||
> export const layout = await loadQuartzLayout()
|
||||
> ```
|
||||
|
||||
- [[tags/plugin/transformer|Transformers]] **map** over content (e.g. parsing frontmatter, generating a description)
|
||||
- [[tags/plugin/filter|Filters]] **filter** content (e.g. filtering out drafts)
|
||||
- [[tags/plugin/emitter|Emitters]] **reduce** over content (e.g. creating an RSS feed or pages that list all files with a specific tag)
|
||||
- **Page Types** define how different types of pages are rendered (content pages, folder listings, tag listings). Each page type can use a different [[layout#Page Frames|page frame]] to control its overall HTML structure.
|
||||
|
||||
You can customize the behaviour of Quartz by adding, removing and reordering plugins in the `transformers`, `filters` and `emitters` fields.
|
||||
The `layout.byPageType` section in `quartz.config.yaml` can also set a `template` field to override the page frame for a specific page type:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
layout:
|
||||
byPageType:
|
||||
canvas:
|
||||
template: minimal # Override the page frame for canvas pages
|
||||
```
|
||||
|
||||
See [[layout#Page Frames]] for details on available frames and how frame resolution works.
|
||||
|
||||
### Internal vs External Plugins
|
||||
|
||||
Quartz distinguishes between internal plugins that are bundled with Quartz and community plugins that are installed separately.
|
||||
|
||||
In `quartz.config.yaml`, community plugins are referenced by their GitHub source:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/explorer
|
||||
enabled: true
|
||||
- source: github:quartz-community/syntax-highlighting
|
||||
enabled: true
|
||||
options:
|
||||
theme:
|
||||
light: github-light
|
||||
dark: github-dark
|
||||
```
|
||||
|
||||
Internal plugins (like `FrontMatter`) are bundled with Quartz. Community plugins are installed separately and referenced by their `github:org/repo` source.
|
||||
|
||||
### Community Plugins
|
||||
|
||||
To install a community plugin, you can use the following command:
|
||||
|
||||
```shell
|
||||
npx quartz plugin add github:quartz-community/explorer
|
||||
```
|
||||
|
||||
This adds the plugin to `quartz.config.yaml` and installs it to `.quartz/plugins/`.
|
||||
|
||||
To install all plugins referenced in your config that aren't yet installed (useful when cloning a project or setting up CI):
|
||||
|
||||
```shell
|
||||
npx quartz plugin resolve
|
||||
```
|
||||
|
||||
To remove installed plugins that are no longer in your config:
|
||||
|
||||
```shell
|
||||
npx quartz plugin prune
|
||||
```
|
||||
|
||||
Both commands support `--dry-run` to preview changes. See [[cli/plugin|the plugin CLI reference]] for full details.
|
||||
|
||||
### Usage
|
||||
|
||||
You can customize the behaviour of Quartz by adding, removing and reordering plugins in `quartz.config.yaml`. Each plugin entry specifies its source, whether it's enabled, execution order, and any options:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/note-properties
|
||||
enabled: true
|
||||
options:
|
||||
includeAll: false
|
||||
includedProperties:
|
||||
- description
|
||||
- tags
|
||||
- aliases
|
||||
order: 5
|
||||
- source: github:quartz-community/created-modified-date
|
||||
enabled: true
|
||||
options:
|
||||
priority:
|
||||
- frontmatter
|
||||
- git
|
||||
- filesystem
|
||||
order: 10
|
||||
- source: github:quartz-community/latex
|
||||
enabled: true
|
||||
options:
|
||||
renderEngine: katex
|
||||
order: 80
|
||||
```
|
||||
|
||||
> [!note]
|
||||
> Each node is modified by every transformer _in order_. Some transformers are position sensitive, so you may need to pay particular attention to whether they need to come before or after certain other plugins.
|
||||
|
||||
You should take care to add the plugin to the right entry corresponding to its plugin type. For example, to add the [[ExplicitPublish]] plugin (a [[tags/plugin/filter|Filter]]), you would add the following line:
|
||||
|
||||
```ts title="quartz.config.ts"
|
||||
filters: [
|
||||
...
|
||||
Plugin.ExplicitPublish(),
|
||||
...
|
||||
],
|
||||
```
|
||||
|
||||
To remove a plugin, you should remove all occurrences of it in the `quartz.config.ts`.
|
||||
|
||||
To customize plugins further, some plugins may also have their own configuration settings that you can pass in. If you do not pass in a configuration, the plugin will use its default settings.
|
||||
|
||||
For example, the [[plugins/Latex|Latex]] plugin allows you to pass in a field specifying the `renderEngine` to choose between Katex and MathJax.
|
||||
|
||||
```ts title="quartz.config.ts"
|
||||
transformers: [
|
||||
Plugin.FrontMatter(), // use default options
|
||||
Plugin.Latex({ renderEngine: "katex" }), // set some custom options
|
||||
]
|
||||
```
|
||||
|
||||
Some plugins are included by default in the [`quartz.config.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz.config.ts), but there are more available.
|
||||
> For advanced options that require JavaScript (e.g. callback functions), use the TS override in `quartz.ts`. See the plugin-specific documentation for details.
|
||||
|
||||
You can see a list of all plugins and their configuration options [[tags/plugin|here]].
|
||||
|
||||
@ -115,22 +196,35 @@ If you'd like to make your own plugins, see the [[making plugins|making custom p
|
||||
|
||||
## Fonts
|
||||
|
||||
Fonts can be specified as a `string` or a `FontSpecification`:
|
||||
Fonts can be specified as a simple string or with advanced options in `quartz.config.yaml`:
|
||||
|
||||
```ts
|
||||
// string
|
||||
typography: {
|
||||
header: "Schibsted Grotesk",
|
||||
...
|
||||
}
|
||||
|
||||
// FontSpecification
|
||||
typography: {
|
||||
header: {
|
||||
name: "Schibsted Grotesk",
|
||||
weights: [400, 700],
|
||||
includeItalic: true,
|
||||
},
|
||||
...
|
||||
}
|
||||
```yaml title="quartz.config.yaml"
|
||||
configuration:
|
||||
theme:
|
||||
typography:
|
||||
header: Schibsted Grotesk
|
||||
body: Source Sans Pro
|
||||
code: IBM Plex Mono
|
||||
```
|
||||
|
||||
For more control over font weights and italics, use the TS override in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.ts"
|
||||
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||
|
||||
const config = await loadQuartzConfig({
|
||||
theme: {
|
||||
typography: {
|
||||
header: {
|
||||
name: "Schibsted Grotesk",
|
||||
weights: [400, 700],
|
||||
includeItalic: true,
|
||||
},
|
||||
body: "Source Sans Pro",
|
||||
code: "IBM Plex Mono",
|
||||
},
|
||||
},
|
||||
})
|
||||
export default config
|
||||
export const layout = await loadQuartzLayout()
|
||||
```
|
||||
|
||||
21
docs/features/Bases.md
Normal file
21
docs/features/Bases.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Bases Support
|
||||
tags:
|
||||
- component
|
||||
---
|
||||
|
||||
Quartz supports rendering [Obsidian Bases](https://obsidian.md/changelog/2025-04-15-desktop-v1.8.0/) (`.base` files) as interactive database-like views. Bases files define queries over your vault's notes and display the results in configurable views such as tables, lists, cards, galleries, and boards.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
Bases support is provided by the [[BasesPage]] plugin. See the plugin page for configuration options, built-in views, the expression engine, and how to extend with custom views.
|
||||
|
||||
## Demo
|
||||
|
||||
![[Base.base]]
|
||||
|
||||
## Customization
|
||||
|
||||
- Install: `npx quartz plugin add github:quartz-community/bases-page`
|
||||
- Source: [`quartz-community/bases-page`](https://github.com/quartz-community/bases-page)
|
||||
21
docs/features/Canvas.md
Normal file
21
docs/features/Canvas.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Canvas Support
|
||||
tags:
|
||||
- component
|
||||
---
|
||||
|
||||
Quartz supports rendering [JSON Canvas](https://jsoncanvas.org) (`.canvas`) files as interactive, pannable and zoomable canvas pages. This brings your Obsidian canvas files to the web, preserving text nodes, file references, link nodes, group nodes, and edges with full visual fidelity.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
Canvas support is provided by the [[CanvasPage]] plugin. See the plugin page for configuration options and a full list of supported features.
|
||||
|
||||
## Demo
|
||||
|
||||
![[Canvas.canvas]]
|
||||
|
||||
## Customization
|
||||
|
||||
- Install: `npx quartz plugin add github:quartz-community/canvas-page`
|
||||
- Source: [`quartz-community/canvas-page`](https://github.com/quartz-community/canvas-page)
|
||||
@ -1,3 +1,9 @@
|
||||
---
|
||||
title: "Docker Support"
|
||||
tags:
|
||||
- feature
|
||||
---
|
||||
|
||||
Quartz comes shipped with a Docker image that will allow you to preview your Quartz locally without installing Node.
|
||||
|
||||
You can run the below one-liner to run Quartz in Docker.
|
||||
|
||||
@ -70,10 +70,9 @@ For example:
|
||||
|
||||
### Using mhchem
|
||||
|
||||
Add the following import to the top of `quartz/plugins/transformers/latex.ts` (before all the other
|
||||
imports):
|
||||
If you are using the community Latex plugin, you can add `mhchem` support by forking the plugin repository and adding the following import to the top of `src/index.ts` (before all the other imports):
|
||||
|
||||
```ts title="quartz/plugins/transformers/latex.ts"
|
||||
```ts title="src/index.ts"
|
||||
import "katex/contrib/mhchem"
|
||||
```
|
||||
|
||||
|
||||
@ -12,6 +12,188 @@ It also ships with support for [frontmatter parsing](https://help.obsidian.md/Ed
|
||||
|
||||
Finally, Quartz also provides [[CrawlLinks]] plugin, which allows you to customize Quartz's link resolution behaviour to match Obsidian.
|
||||
|
||||
## Supported Features
|
||||
|
||||
### Wikilinks
|
||||
|
||||
Internal links using the `[[page]]` syntax are converted to regular links. See [[wikilinks]] for more details. All variations are supported:
|
||||
|
||||
```markdown
|
||||
[[Page]] Link to a page
|
||||
[[Page|Custom text]] Link with alias
|
||||
[[Page#Heading]] Link to a heading
|
||||
[[Page#Heading|Custom text]] Link to a heading with alias
|
||||
[[Page#^block-id]] Link to a block reference
|
||||
![[Page]] Embed (transclude) a page
|
||||
![[image.png]] Embed an image
|
||||
![[image.png|alt 100x200]] Embed with alt text and dimensions
|
||||
```
|
||||
|
||||
Inside tables, pipes in wikilinks can be escaped with a backslash:
|
||||
|
||||
```markdown
|
||||
| Column |
|
||||
| --------------- |
|
||||
| [[page\|alias]] |
|
||||
```
|
||||
|
||||
### Highlights
|
||||
|
||||
Wrap text in `==` to highlight it:
|
||||
|
||||
```markdown
|
||||
This is ==highlighted text== in a sentence.
|
||||
```
|
||||
|
||||
This renders as: This is ==highlighted text== in a sentence.
|
||||
|
||||
### Comments
|
||||
|
||||
Obsidian-style comments are stripped from the output:
|
||||
|
||||
```markdown
|
||||
This is visible. %%This is a comment and won't appear.%%
|
||||
```
|
||||
|
||||
This renders as: This is visible. %%This is a comment and won't appear.%%
|
||||
|
||||
Multi-line comments are also supported:
|
||||
|
||||
```markdown
|
||||
%%
|
||||
This entire block
|
||||
is a comment.
|
||||
%%
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
Tags starting with `#` are parsed and linked to tag pages:
|
||||
|
||||
```markdown
|
||||
#tag #nested/tag #tag-with-dashes
|
||||
```
|
||||
|
||||
For example: #feature/transformer
|
||||
|
||||
> [!note]
|
||||
> Pure numeric tags like `#123` are ignored, matching Obsidian behaviour.
|
||||
|
||||
### Callouts
|
||||
|
||||
[[callouts|Obsidian callouts]] are fully supported, including collapsible variants:
|
||||
|
||||
```markdown
|
||||
> [!note]
|
||||
> This is a note callout.
|
||||
|
||||
> [!warning]- Collapsed by default
|
||||
> This content is hidden initially.
|
||||
|
||||
> [!tip]+ Expanded by default
|
||||
> This content is visible initially.
|
||||
```
|
||||
|
||||
> [!example] Live example
|
||||
> This is a live callout rendered from Obsidian-flavored Markdown.
|
||||
|
||||
All built-in callout types are supported: `note`, `abstract`, `info`, `todo`, `tip`, `success`, `question`, `warning`, `failure`, `danger`, `bug`, `example`, and `quote`, along with their aliases.
|
||||
|
||||
### Task Lists and Custom Task Characters
|
||||
|
||||
Standard checkboxes work out of the box. With `enableCheckbox: true`, you also get support for custom task characters that are popular in the Obsidian community:
|
||||
|
||||
```markdown
|
||||
- [ ] Unchecked
|
||||
- [x] Checked
|
||||
- [?] Question
|
||||
- [!] Important
|
||||
- [>] Forwarded
|
||||
- [/] In progress
|
||||
- [-] Cancelled
|
||||
- [s] Special
|
||||
```
|
||||
|
||||
Each custom character is preserved as a `data-task` attribute on the rendered element, allowing CSS-based styling per character.
|
||||
|
||||
- [ ] Unchecked
|
||||
- [x] Checked
|
||||
- [?] Question
|
||||
- [!] Important
|
||||
|
||||
### Mermaid Diagrams
|
||||
|
||||
[[Mermaid diagrams|Mermaid]] code blocks are rendered as diagrams:
|
||||
|
||||
````markdown
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Start] --> B{Decision}
|
||||
B -->|Yes| C[OK]
|
||||
B -->|No| D[Cancel]
|
||||
```
|
||||
````
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Start] --> B{Decision}
|
||||
B -->|Yes| C[OK]
|
||||
B -->|No| D[Cancel]
|
||||
```
|
||||
|
||||
### YouTube Embeds
|
||||
|
||||
YouTube videos can be embedded using standard image syntax with a YouTube URL:
|
||||
|
||||
```markdown
|
||||

|
||||

|
||||
```
|
||||
|
||||
For example, the following embed is rendered from ``:
|
||||
|
||||

|
||||
|
||||
### Tweet Embeds
|
||||
|
||||
Tweets from Twitter/X are embedded as static blockquotes with a link to the original:
|
||||
|
||||
```markdown
|
||||

|
||||

|
||||
```
|
||||
|
||||
For example, the following embed is rendered from ``:
|
||||
|
||||

|
||||
|
||||
### Block References
|
||||
|
||||
Block references allow linking to specific blocks within a page:
|
||||
|
||||
```markdown
|
||||
Content paragraph. ^my-block
|
||||
|
||||
[[Page#^my-block]]
|
||||
```
|
||||
|
||||
### Obsidian URI Links
|
||||
|
||||
Links using the `obsidian://` protocol are marked with a CSS class (`obsidian-uri`) and a `data-obsidian-uri` attribute, so you can style them differently from regular links.
|
||||
|
||||
### Video Embeds
|
||||
|
||||
Video files can be embedded using standard image syntax:
|
||||
|
||||
```markdown
|
||||

|
||||

|
||||
```
|
||||
|
||||
### Embed in HTML
|
||||
|
||||
By default, Obsidian does not render its Markdown syntax inside HTML blocks. Quartz extends this with the `enableInHtmlEmbed` option, which parses wikilinks, highlights, and tags inside raw HTML nodes.
|
||||
|
||||
## Configuration
|
||||
|
||||
This functionality is provided by the [[ObsidianFlavoredMarkdown]], [[Frontmatter]] and [[CrawlLinks]] plugins. See the plugin pages for customization options.
|
||||
|
||||
@ -8,18 +8,42 @@ tags:
|
||||
|
||||
Because the Markdown generated by ox-hugo is not pure Markdown but Hugo specific, we need to transform it to fit into Quartz. This is done by the [[OxHugoFlavoredMarkdown]] plugin. Even though this plugin was written with `ox-hugo` in mind, it should work for any Hugo specific Markdown.
|
||||
|
||||
```typescript title="quartz.config.ts"
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/obsidian-flavored-markdown
|
||||
enabled: true
|
||||
order: 30
|
||||
- source: github:quartz-community/ox-hugo
|
||||
enabled: true
|
||||
order: 25 # must come before obsidian-flavored-markdown
|
||||
- source: github:quartz-community/github-flavored-markdown
|
||||
enabled: true
|
||||
order: 40
|
||||
- source: github:quartz-community/note-properties
|
||||
enabled: true
|
||||
options:
|
||||
delimiters: "+++"
|
||||
language: toml # if using toml frontmatter
|
||||
order: 5
|
||||
```
|
||||
|
||||
For the TS override approach:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
plugins: {
|
||||
transformers: [
|
||||
Plugin.FrontMatter({ delims: "+++", language: "toml" }), // if toml frontmatter
|
||||
ExternalPlugin.FrontMatter({ delims: "+++", language: "toml" }),
|
||||
// ...
|
||||
Plugin.OxHugoFlavouredMarkdown(),
|
||||
Plugin.GitHubFlavoredMarkdown(),
|
||||
ExternalPlugin.OxHugoFlavouredMarkdown(),
|
||||
ExternalPlugin.GitHubFlavoredMarkdown(),
|
||||
// ...
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
> [!note]
|
||||
> In YAML, plugin execution order is controlled by the `order` field. Lower numbers execute first. Ensure `ox-hugo` has a lower `order` than `obsidian-flavored-markdown`.
|
||||
|
||||
## Usage
|
||||
|
||||
Quartz by default doesn't understand `org-roam` files as they aren't Markdown. You're responsible for using an external tool like `ox-hugo` to export the `org-roam` files as Markdown content to Quartz and managing the static assets so that they're available in the final output.
|
||||
|
||||
@ -9,19 +9,31 @@ tags:
|
||||
Quartz supports transforming the special Markdown syntax from Roam Research (like `{{[[components]]}}` and other formatting) into
|
||||
regular Markdown via the [[RoamFlavoredMarkdown]] plugin.
|
||||
|
||||
```typescript title="quartz.config.ts"
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/roam
|
||||
enabled: true
|
||||
order: 25 # must come before obsidian-flavored-markdown
|
||||
- source: github:quartz-community/obsidian-flavored-markdown
|
||||
enabled: true
|
||||
order: 30
|
||||
```
|
||||
|
||||
For the TS override approach:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
plugins: {
|
||||
transformers: [
|
||||
// ...
|
||||
Plugin.RoamFlavoredMarkdown(),
|
||||
Plugin.ObsidianFlavoredMarkdown(),
|
||||
ExternalPlugin.RoamFlavoredMarkdown(),
|
||||
ExternalPlugin.ObsidianFlavoredMarkdown(),
|
||||
// ...
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
> [!warning]
|
||||
> As seen above placement of `Plugin.RoamFlavoredMarkdown()` within `quartz.config.ts` is very important. It must come before `Plugin.ObsidianFlavoredMarkdown()`.
|
||||
> In YAML, plugin execution order is controlled by the `order` field. Ensure `roam` has a lower `order` value than `obsidian-flavored-markdown` so it runs first.
|
||||
|
||||
## Customization
|
||||
|
||||
|
||||
@ -1,7 +1,13 @@
|
||||
---
|
||||
title: "SPA Routing"
|
||||
tags:
|
||||
- feature
|
||||
---
|
||||
|
||||
Single-page-app style rendering. This prevents flashes of unstyled content and improves the smoothness of Quartz.
|
||||
|
||||
Under the hood, this is done by hijacking page navigations and instead fetching the HTML via a `GET` request and then diffing and selectively replacing parts of the page using [micromorph](https://github.com/natemoo-re/micromorph). This allows us to change the content of the page without fully refreshing the page, reducing the amount of content that the browser needs to load.
|
||||
|
||||
## Configuration
|
||||
|
||||
- Disable SPA Routing: set the `enableSPA` field of the [[configuration]] in `quartz.config.ts` to be `false`.
|
||||
- Disable SPA Routing: set the `enableSPA` field of the [[configuration]] in `quartz.config.yaml` to be `false`.
|
||||
|
||||
@ -6,10 +6,12 @@ tags:
|
||||
|
||||
A backlink for a note is a link from another note to that note. Links in the backlink pane also feature rich [[popover previews]] if you have that feature enabled.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Customization
|
||||
|
||||
- Removing backlinks: delete all usages of `Component.Backlinks()` from `quartz.layout.ts`.
|
||||
- Hide when empty: hide `Backlinks` if given page doesn't contain any backlinks (default to `true`). To disable this, use `Component.Backlinks({ hideWhenEmpty: false })`.
|
||||
- Component: `quartz/components/Backlinks.tsx`
|
||||
- Style: `quartz/components/styles/backlinks.scss`
|
||||
- Script: `quartz/components/scripts/search.inline.ts`
|
||||
- Removing backlinks: remove the `backlinks` entry from `quartz.config.yaml` or set `enabled: false`.
|
||||
- Hide when empty: hide `Backlinks` if given page doesn't contain any backlinks (default to `true`). To disable this, set `hideWhenEmpty: false` in the plugin options in `quartz.config.yaml`.
|
||||
- Install: `npx quartz plugin add github:quartz-community/backlinks`
|
||||
- Source: [`quartz-community/backlinks`](https://github.com/quartz-community/backlinks)
|
||||
|
||||
@ -8,28 +8,46 @@ Breadcrumbs provide a way to navigate a hierarchy of pages within your site usin
|
||||
|
||||
By default, the element at the very top of your page is the breadcrumb navigation bar (can also be seen at the top on this page!).
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Customization
|
||||
|
||||
Most configuration can be done by passing in options to `Component.Breadcrumbs()`.
|
||||
Most configuration can be done via the `options` section of the breadcrumbs plugin entry in `quartz.config.yaml`.
|
||||
|
||||
For example, here's what the default configuration looks like:
|
||||
|
||||
```typescript title="quartz.layout.ts"
|
||||
Component.Breadcrumbs({
|
||||
spacerSymbol: "❯", // symbol between crumbs
|
||||
rootName: "Home", // name of first/root element
|
||||
resolveFrontmatterTitle: true, // whether to resolve folder names through frontmatter titles
|
||||
showCurrentPage: true, // whether to display the current page in the breadcrumbs
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/breadcrumbs
|
||||
enabled: true
|
||||
options:
|
||||
spacerSymbol: "❯"
|
||||
rootName: Home
|
||||
resolveFrontmatterTitle: true
|
||||
showCurrentPage: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 5
|
||||
```
|
||||
|
||||
For the TS override approach:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
ExternalPlugin.Breadcrumbs({
|
||||
spacerSymbol: "❯",
|
||||
rootName: "Home",
|
||||
resolveFrontmatterTitle: true,
|
||||
showCurrentPage: true,
|
||||
})
|
||||
```
|
||||
|
||||
When passing in your own options, you can omit any or all of these fields if you'd like to keep the default value for that field.
|
||||
|
||||
You can also adjust where the breadcrumbs will be displayed by adjusting the [[layout]] (moving `Component.Breadcrumbs()` up or down)
|
||||
You can also adjust where the breadcrumbs will be displayed by changing the `layout.position` field in the plugin entry in `quartz.config.yaml` (see [[layout]]).
|
||||
|
||||
Want to customize it even more?
|
||||
|
||||
- Removing breadcrumbs: delete all usages of `Component.Breadcrumbs()` from `quartz.layout.ts`.
|
||||
- Component: `quartz/components/Breadcrumbs.tsx`
|
||||
- Style: `quartz/components/styles/breadcrumbs.scss`
|
||||
- Script: inline at `quartz/components/Breadcrumbs.tsx`
|
||||
- Removing breadcrumbs: remove the `breadcrumbs` entry from `quartz.config.yaml` or set `enabled: false`.
|
||||
- Install: `npx quartz plugin add github:quartz-community/breadcrumbs`
|
||||
- Source: [`quartz-community/breadcrumbs`](https://github.com/quartz-community/breadcrumbs)
|
||||
|
||||
@ -6,6 +6,9 @@ tags:
|
||||
|
||||
Quartz also has the ability to hook into various providers to enable readers to leave comments on your site.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
![[giscus-example.png]]
|
||||
|
||||
As of today, only [Giscus](https://giscus.app/) is supported out of the box but PRs to support other providers are welcome!
|
||||
@ -30,28 +33,54 @@ After entering both your repository and selecting the discussion category, Giscu
|
||||
|
||||
![[giscus-results.png]]
|
||||
|
||||
Finally, in `quartz.layout.ts`, edit the `afterBody` field of `sharedPageComponents` to include the following options but with the values you got from above:
|
||||
Finally, in `quartz.config.yaml`, add the comments plugin with the following options (using the values you got from above):
|
||||
|
||||
```ts title="quartz.layout.ts"
|
||||
afterBody: [
|
||||
Component.Comments({
|
||||
provider: 'giscus',
|
||||
options: {
|
||||
// from data-repo
|
||||
repo: 'jackyzha0/quartz',
|
||||
// from data-repo-id
|
||||
repoId: 'MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg',
|
||||
// from data-category
|
||||
category: 'Announcements',
|
||||
// from data-category-id
|
||||
categoryId: 'DIC_kwDOFxRnmM4B-Xg6',
|
||||
// from data-lang
|
||||
lang: 'en'
|
||||
}
|
||||
}),
|
||||
],
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/comments
|
||||
enabled: true
|
||||
options:
|
||||
provider: giscus
|
||||
options:
|
||||
repo: jackyzha0/quartz
|
||||
repoId: MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg
|
||||
category: Announcements
|
||||
categoryId: DIC_kwDOFxRnmM4B-Xg6
|
||||
lang: en
|
||||
layout:
|
||||
position: afterBody
|
||||
priority: 10
|
||||
```
|
||||
|
||||
For the TS override approach:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
// If using quartz.ts overrides instead of YAML:
|
||||
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||
|
||||
const config = await loadQuartzConfig()
|
||||
export default config
|
||||
export const layout = await loadQuartzLayout({
|
||||
defaults: {
|
||||
afterBody: [
|
||||
ExternalPlugin.Comments({
|
||||
provider: "giscus",
|
||||
options: {
|
||||
repo: "jackyzha0/quartz",
|
||||
repoId: "MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg",
|
||||
category: "Announcements",
|
||||
categoryId: "DIC_kwDOFxRnmM4B-Xg6",
|
||||
lang: "en",
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
> [!note]
|
||||
> Install the comments plugin first: `npx quartz plugin add github:quartz-community/comments`
|
||||
|
||||
### Customization
|
||||
|
||||
Quartz also exposes a few of the other Giscus options as well and you can provide them the same way `repo`, `repoId`, `category`, and `categoryId` are provided.
|
||||
@ -106,19 +135,39 @@ Quartz supports custom theme for Giscus. To use a custom CSS theme, place the `.
|
||||
|
||||
For example, if you have a light theme `light-theme.css`, a dark theme `dark-theme.css`, and your Quartz site is hosted at `https://example.com/`:
|
||||
|
||||
```ts
|
||||
afterBody: [
|
||||
Component.Comments({
|
||||
provider: 'giscus',
|
||||
options: {
|
||||
// Other options
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/comments
|
||||
enabled: true
|
||||
options:
|
||||
provider: giscus
|
||||
options:
|
||||
# Other options...
|
||||
themeUrl: "https://example.com/static/giscus" # corresponds to quartz/static/giscus/
|
||||
lightTheme: light-theme # corresponds to light-theme.css in quartz/static/giscus/
|
||||
darkTheme: dark-theme # corresponds to dark-theme.css in quartz/static/giscus/
|
||||
```
|
||||
|
||||
themeUrl: "https://example.com/static/giscus", // corresponds to quartz/static/giscus/
|
||||
lightTheme: "light-theme", // corresponds to light-theme.css in quartz/static/giscus/
|
||||
darkTheme: "dark-theme", // corresponds to dark-theme.css quartz/static/giscus/
|
||||
}
|
||||
}),
|
||||
],
|
||||
```ts title="quartz.ts (override)"
|
||||
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||
|
||||
const config = await loadQuartzConfig()
|
||||
export default config
|
||||
export const layout = await loadQuartzLayout({
|
||||
defaults: {
|
||||
afterBody: [
|
||||
ExternalPlugin.Comments({
|
||||
provider: "giscus",
|
||||
options: {
|
||||
// Other options...
|
||||
themeUrl: "https://example.com/static/giscus",
|
||||
lightTheme: "light-theme",
|
||||
darkTheme: "dark-theme",
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
#### Conditionally display comments
|
||||
|
||||
@ -6,12 +6,14 @@ tags:
|
||||
|
||||
Quartz supports darkmode out of the box that respects the user's theme preference. Any future manual toggles of the darkmode switch will be saved in the browser's local storage so it can be persisted across future page loads.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Customization
|
||||
|
||||
- Removing darkmode: delete all usages of `Component.Darkmode()` from `quartz.layout.ts`.
|
||||
- Component: `quartz/components/Darkmode.tsx`
|
||||
- Style: `quartz/components/styles/darkmode.scss`
|
||||
- Script: `quartz/components/scripts/darkmode.inline.ts`
|
||||
- Removing darkmode: remove the `darkmode` entry from `quartz.config.yaml` or set `enabled: false`.
|
||||
- Install: `npx quartz plugin add github:quartz-community/darkmode`
|
||||
- Source: [`quartz-community/darkmode`](https://github.com/quartz-community/darkmode)
|
||||
|
||||
You can also listen to the `themechange` event to perform any custom logic when the theme changes.
|
||||
|
||||
|
||||
@ -6,6 +6,30 @@ tags:
|
||||
|
||||
Quartz features an explorer that allows you to navigate all files and folders on your site. It supports nested folders and is highly customizable.
|
||||
|
||||
> [!info]
|
||||
> The Explorer is now a community plugin. This demonstrates how external plugins can extend Quartz functionality while serving as a reference implementation for plugin developers.
|
||||
|
||||
## Installation
|
||||
|
||||
The Explorer is available as a community plugin from GitHub:
|
||||
|
||||
```bash
|
||||
npm install github:quartz-community/explorer --legacy-peer-deps
|
||||
```
|
||||
|
||||
Then add it to your `quartz.config.yaml`:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/explorer
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 50
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
By default, it shows all folders and files on your page. To display the explorer in a different spot, you can edit the [[layout]].
|
||||
|
||||
Display names for folders get determined by the `title` frontmatter field in `folder/index.md` (more detail in [[authoring content | Authoring Content]]). If this file does not exist or does not contain frontmatter, the local folder name will be used instead.
|
||||
@ -17,42 +41,63 @@ Display names for folders get determined by the `title` frontmatter field in `fo
|
||||
|
||||
## Customization
|
||||
|
||||
Most configuration can be done by passing in options to `Component.Explorer()`.
|
||||
Most configuration can be done by passing in options to `Explorer()`.
|
||||
|
||||
For example, here's what the default configuration looks like:
|
||||
|
||||
```typescript title="quartz.layout.ts"
|
||||
Component.Explorer({
|
||||
title: "Explorer", // title of the explorer component
|
||||
folderClickBehavior: "collapse", // what happens when you click a folder ("link" to navigate to folder page on click or "collapse" to collapse folder on click)
|
||||
folderDefaultState: "collapsed", // default state of folders ("collapsed" or "open")
|
||||
useSavedState: true, // whether to use local storage to save "state" (which folders are opened) of explorer
|
||||
// omitted but shown later
|
||||
sortFn: ...,
|
||||
filterFn: ...,
|
||||
mapFn: ...,
|
||||
// what order to apply functions in
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/explorer
|
||||
enabled: true
|
||||
options:
|
||||
title: Explorer
|
||||
folderClickBehavior: collapse # "link" to navigate or "collapse" to toggle
|
||||
folderDefaultState: collapsed # "collapsed" or "open"
|
||||
useSavedState: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 50
|
||||
```
|
||||
|
||||
For advanced options like custom sort, filter, and map functions, use the TS override in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.ts"
|
||||
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||
import { Explorer } from "@quartz-community/explorer"
|
||||
|
||||
// Advanced: pass callback functions that can't be expressed in YAML
|
||||
Explorer({
|
||||
sortFn: (a, b) => {
|
||||
/* ... */
|
||||
},
|
||||
filterFn: (node) => {
|
||||
/* ... */
|
||||
},
|
||||
mapFn: (node) => {
|
||||
/* ... */
|
||||
},
|
||||
order: ["filter", "map", "sort"],
|
||||
})
|
||||
|
||||
const config = await loadQuartzConfig()
|
||||
export default config
|
||||
export const layout = await loadQuartzLayout()
|
||||
```
|
||||
|
||||
When passing in your own options, you can omit any or all of these fields if you'd like to keep the default value for that field.
|
||||
|
||||
Want to customize it even more?
|
||||
|
||||
- Removing explorer: remove `Component.Explorer()` from `quartz.layout.ts`
|
||||
- Removing explorer: remove the `explorer` entry from `quartz.config.yaml` or set `enabled: false`
|
||||
- (optional): After removing the explorer component, you can move the [[table of contents | Table of Contents]] component back to the `left` part of the layout
|
||||
- Changing `sort`, `filter` and `map` behavior: explained in [[#Advanced customization]]
|
||||
- Component: `quartz/components/Explorer.tsx`
|
||||
- Style: `quartz/components/styles/explorer.scss`
|
||||
- Script: `quartz/components/scripts/explorer.inline.ts`
|
||||
|
||||
## Advanced customization
|
||||
|
||||
This component allows you to fully customize all of its behavior. You can pass a custom `sort`, `filter` and `map` function.
|
||||
All functions you can pass work with the `FileTrieNode` class, which has the following properties:
|
||||
|
||||
```ts title="quartz/components/Explorer.tsx"
|
||||
```ts title="@quartz-community/explorer"
|
||||
class FileTrieNode {
|
||||
isFolder: boolean
|
||||
children: Array<FileTrieNode>
|
||||
@ -60,7 +105,7 @@ class FileTrieNode {
|
||||
}
|
||||
```
|
||||
|
||||
```ts title="quartz/plugins/emitters/contentIndex.tsx"
|
||||
```ts
|
||||
export type ContentDetails = {
|
||||
slug: FullSlug
|
||||
title: string
|
||||
@ -74,7 +119,7 @@ Every function you can pass is optional. By default, only a `sort` function will
|
||||
|
||||
```ts title="Default sort function"
|
||||
// Sort order: folders first, then files. Sort folders and files alphabetically
|
||||
Component.Explorer({
|
||||
Explorer({
|
||||
sortFn: (a, b) => {
|
||||
if ((!a.isFolder && !b.isFolder) || (a.isFolder && b.isFolder)) {
|
||||
return a.displayName.localeCompare(b.displayName, undefined, {
|
||||
@ -114,8 +159,20 @@ These examples show the basic usage of `sort`, `map` and `filter`.
|
||||
|
||||
Using this example, the explorer will alphabetically sort everything.
|
||||
|
||||
```ts title="quartz.layout.ts"
|
||||
Component.Explorer({
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/explorer
|
||||
enabled: true
|
||||
options:
|
||||
# Simple options go in YAML
|
||||
title: Explorer
|
||||
folderDefaultState: collapsed
|
||||
```
|
||||
|
||||
Custom sort functions require the TS override:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
Explorer({
|
||||
sortFn: (a, b) => {
|
||||
return a.displayName.localeCompare(b.displayName)
|
||||
},
|
||||
@ -126,8 +183,8 @@ Component.Explorer({
|
||||
|
||||
Using this example, the display names of all `FileNodes` (folders + files) will be converted to full upper case.
|
||||
|
||||
```ts title="quartz.layout.ts"
|
||||
Component.Explorer({
|
||||
```ts title="quartz.ts (override)"
|
||||
Explorer({
|
||||
mapFn: (node) => {
|
||||
node.displayName = node.displayName.toUpperCase()
|
||||
return node
|
||||
@ -135,13 +192,16 @@ Component.Explorer({
|
||||
})
|
||||
```
|
||||
|
||||
> [!note]
|
||||
> The `mapFn`, `filterFn`, and `sortFn` options require JavaScript callback functions and cannot be expressed in YAML. Use the TS override for these.
|
||||
|
||||
### Remove list of elements (`filter`)
|
||||
|
||||
Using this example, you can remove elements from your explorer by providing an array of folders/files to exclude.
|
||||
Note that this example filters on the title but you can also do it via slug or any other field available on `FileTrieNode`.
|
||||
|
||||
```ts title="quartz.layout.ts"
|
||||
Component.Explorer({
|
||||
```ts title="quartz.ts (override)"
|
||||
Explorer({
|
||||
filterFn: (node) => {
|
||||
// set containing names of everything you want to filter out
|
||||
const omit = new Set(["authoring content", "tags", "advanced"])
|
||||
@ -158,8 +218,8 @@ Component.Explorer({
|
||||
|
||||
You can access the tags of a file by `node.data.tags`.
|
||||
|
||||
```ts title="quartz.layout.ts"
|
||||
Component.Explorer({
|
||||
```ts title="quartz.ts (override)"
|
||||
Explorer({
|
||||
filterFn: (node) => {
|
||||
// exclude files with the tag "explorerexclude"
|
||||
return node.data?.tags?.includes("explorerexclude") !== true
|
||||
@ -172,8 +232,8 @@ Component.Explorer({
|
||||
By default, the explorer will filter out the `tags` folder.
|
||||
To override the default filter function, you can set the filter function to `undefined`.
|
||||
|
||||
```ts title="quartz.layout.ts"
|
||||
Component.Explorer({
|
||||
```ts title="quartz.ts (override)"
|
||||
Explorer({
|
||||
filterFn: undefined, // apply no filter function, every file and folder will visible
|
||||
})
|
||||
```
|
||||
@ -181,24 +241,24 @@ Component.Explorer({
|
||||
## Advanced examples
|
||||
|
||||
> [!tip]
|
||||
> When writing more complicated functions, the `layout` file can start to look very cramped.
|
||||
> When writing more complicated functions, the `quartz.ts` file can start to look very cramped.
|
||||
> You can fix this by defining your sort functions outside of the component
|
||||
> and passing it in.
|
||||
>
|
||||
> ```ts title="quartz.layout.ts"
|
||||
> import { Options } from "./quartz/components/Explorer"
|
||||
> ```ts title="quartz.ts"
|
||||
> import { ExplorerOptions } from "@quartz-community/explorer/components"
|
||||
>
|
||||
> export const mapFn: Options["mapFn"] = (node) => {
|
||||
> export const mapFn: ExplorerOptions["mapFn"] = (node) => {
|
||||
> // implement your function here
|
||||
> }
|
||||
> export const filterFn: Options["filterFn"] = (node) => {
|
||||
> export const filterFn: ExplorerOptions["filterFn"] = (node) => {
|
||||
> // implement your function here
|
||||
> }
|
||||
> export const sortFn: Options["sortFn"] = (a, b) => {
|
||||
> export const sortFn: ExplorerOptions["sortFn"] = (a, b) => {
|
||||
> // implement your function here
|
||||
> }
|
||||
>
|
||||
> Component.Explorer({
|
||||
> Explorer({
|
||||
> // ... your other options
|
||||
> mapFn,
|
||||
> filterFn,
|
||||
@ -208,10 +268,10 @@ Component.Explorer({
|
||||
|
||||
### Add emoji prefix
|
||||
|
||||
To add emoji prefixes (📁 for folders, 📄 for files), you could use a map function like this:
|
||||
To add emoji prefixes (📁 for folders, 📄 for files), you could use a map function in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.layout.ts"
|
||||
Component.Explorer({
|
||||
```ts title="quartz.ts (override)"
|
||||
Explorer({
|
||||
mapFn: (node) => {
|
||||
if (node.isFolder) {
|
||||
node.displayName = "📁 " + node.displayName
|
||||
|
||||
@ -6,6 +6,9 @@ tags:
|
||||
|
||||
Full-text search in Quartz is powered by [Flexsearch](https://github.com/nextapps-de/flexsearch). It's fast enough to return search results in under 10ms for Quartzs as large as half a million words.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
It can be opened by either clicking on the search bar or pressing `⌘`/`ctrl` + `K`. The top 5 search results are shown on each query. Matching subterms are highlighted and the most relevant 30 words are excerpted. Clicking on a search result will navigate to that page.
|
||||
|
||||
To search content by tags, you can either press `⌘`/`ctrl` + `shift` + `K` or start your query with `#` (e.g. `#components`).
|
||||
@ -23,8 +26,6 @@ It properly tokenizes Chinese, Korean, and Japenese characters and constructs se
|
||||
|
||||
## Customization
|
||||
|
||||
- Removing search: delete all usages of `Component.Search()` from `quartz.layout.ts`.
|
||||
- Component: `quartz/components/Search.tsx`
|
||||
- Style: `quartz/components/styles/search.scss`
|
||||
- Script: `quartz/components/scripts/search.inline.ts`
|
||||
- You can edit `contextWindowWords`, `numSearchResults` or `numTagResults` to suit your needs
|
||||
- Removing search: remove the `search` entry from `quartz.config.yaml` or set `enabled: false`.
|
||||
- Install: `npx quartz plugin add github:quartz-community/search`
|
||||
- Source: [`quartz-community/search`](https://github.com/quartz-community/search)
|
||||
|
||||
@ -9,6 +9,30 @@ Quartz features a graph-view that can show both a local graph view and a global
|
||||
- The local graph view shows files that either link to the current file or are linked from the current file. In other words, it shows all notes that are _at most_ one hop away.
|
||||
- The global graph view can be toggled by clicking the graph icon on the top-right of the local graph view. It shows _all_ the notes in your graph and how they connect to each other.
|
||||
|
||||
> [!info]
|
||||
> The Graph View is now a community plugin. This demonstrates how external plugins can extend Quartz functionality while serving as a reference implementation for plugin developers.
|
||||
|
||||
## Installation
|
||||
|
||||
The Graph View is available as a community plugin from GitHub:
|
||||
|
||||
```bash
|
||||
npm install github:quartz-community/graph --legacy-peer-deps
|
||||
```
|
||||
|
||||
Then add it to your `quartz.config.yaml`:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/graph
|
||||
enabled: true
|
||||
layout:
|
||||
position: right
|
||||
priority: 10
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
By default, the node radius is proportional to the total number of incoming and outgoing internal links from that file.
|
||||
|
||||
Additionally, similar to how browsers highlight visited links a different colour, the graph view will also show nodes that you have visited in a different colour.
|
||||
@ -18,48 +42,50 @@ Additionally, similar to how browsers highlight visited links a different colour
|
||||
|
||||
## Customization
|
||||
|
||||
Most configuration can be done by passing in options to `Component.Graph()`.
|
||||
Most configuration can be done by passing in options to `Graph()`.
|
||||
|
||||
For example, here's what the default configuration looks like:
|
||||
|
||||
```typescript title="quartz.layout.ts"
|
||||
Component.Graph({
|
||||
localGraph: {
|
||||
drag: true, // whether to allow panning the view around
|
||||
zoom: true, // whether to allow zooming in and out
|
||||
depth: 1, // how many hops of notes to display
|
||||
scale: 1.1, // default view scale
|
||||
repelForce: 0.5, // how much nodes should repel each other
|
||||
centerForce: 0.3, // how much force to use when trying to center the nodes
|
||||
linkDistance: 30, // how long should the links be by default?
|
||||
fontSize: 0.6, // what size should the node labels be?
|
||||
opacityScale: 1, // how quickly do we fade out the labels when zooming out?
|
||||
removeTags: [], // what tags to remove from the graph
|
||||
showTags: true, // whether to show tags in the graph
|
||||
enableRadial: false, // whether to constrain the graph, similar to Obsidian
|
||||
},
|
||||
globalGraph: {
|
||||
drag: true,
|
||||
zoom: true,
|
||||
depth: -1,
|
||||
scale: 0.9,
|
||||
repelForce: 0.5,
|
||||
centerForce: 0.3,
|
||||
linkDistance: 30,
|
||||
fontSize: 0.6,
|
||||
opacityScale: 1,
|
||||
removeTags: [], // what tags to remove from the graph
|
||||
showTags: true, // whether to show tags in the graph
|
||||
enableRadial: true, // whether to constrain the graph, similar to Obsidian
|
||||
},
|
||||
})
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/graph
|
||||
enabled: true
|
||||
options:
|
||||
localGraph:
|
||||
drag: true
|
||||
zoom: true
|
||||
depth: 1
|
||||
scale: 1.1
|
||||
repelForce: 0.5
|
||||
centerForce: 0.3
|
||||
linkDistance: 30
|
||||
fontSize: 0.6
|
||||
opacityScale: 1
|
||||
removeTags: []
|
||||
showTags: true
|
||||
enableRadial: false
|
||||
globalGraph:
|
||||
drag: true
|
||||
zoom: true
|
||||
depth: -1
|
||||
scale: 0.9
|
||||
repelForce: 0.5
|
||||
centerForce: 0.3
|
||||
linkDistance: 30
|
||||
fontSize: 0.6
|
||||
opacityScale: 1
|
||||
removeTags: []
|
||||
showTags: true
|
||||
focusOnHover: true
|
||||
enableRadial: true
|
||||
layout:
|
||||
position: right
|
||||
priority: 10
|
||||
```
|
||||
|
||||
When passing in your own options, you can omit any or all of these fields if you'd like to keep the default value for that field.
|
||||
|
||||
Want to customize it even more?
|
||||
|
||||
- Removing graph view: delete all usages of `Component.Graph()` from `quartz.layout.ts`.
|
||||
- Component: `quartz/components/Graph.tsx`
|
||||
- Style: `quartz/components/styles/graph.scss`
|
||||
- Script: `quartz/components/scripts/graph.inline.ts`
|
||||
- Removing graph view: remove the `graph` entry from `quartz.config.yaml` or set `enabled: false`
|
||||
- Component source: https://github.com/quartz-community/graph
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
title: Internationalization
|
||||
---
|
||||
|
||||
Internationalization allows users to translate text in the Quartz interface into various supported languages without needing to make extensive code changes. This can be changed via the `locale` [[configuration]] field in `quartz.config.ts`.
|
||||
Internationalization allows users to translate text in the Quartz interface into various supported languages without needing to make extensive code changes. This can be changed via the `locale` [[configuration]] field in `quartz.config.yaml`.
|
||||
|
||||
The locale field generally follows a certain format: `{language}-{REGION}`
|
||||
|
||||
@ -10,7 +10,7 @@ The locale field generally follows a certain format: `{language}-{REGION}`
|
||||
- `{REGION}` is usually a [2-letter uppercase region code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
|
||||
|
||||
> [!tip] Interested in contributing?
|
||||
> We [gladly welcome translation PRs](https://github.com/jackyzha0/quartz/tree/v4/quartz/i18n/locales)! To contribute a translation, do the following things:
|
||||
> We [gladly welcome translation PRs](https://github.com/jackyzha0/quartz/tree/v5/quartz/i18n/locales)! To contribute a translation, do the following things:
|
||||
>
|
||||
> 1. In the `quartz/i18n/locales` folder, copy the `en-US.ts` file.
|
||||
> 2. Rename it to `{language}-{REGION}.ts` so it matches a locale of the format shown above.
|
||||
|
||||
@ -1,3 +1,48 @@
|
||||
---
|
||||
title: Feature List
|
||||
---
|
||||
|
||||
Quartz comes with a wide variety of features out of the box. Most features are powered by [[configuration#Plugins|plugins]] that can be configured, enabled, or disabled via `quartz.config.yaml`.
|
||||
|
||||
## Content Features
|
||||
|
||||
- [[Obsidian compatibility]] — Full support for Obsidian-flavored Markdown
|
||||
- [[wikilinks]] — Link between notes using `[[wikilinks]]` syntax
|
||||
- [[callouts]] — Obsidian-style callout blocks
|
||||
- [[Latex]] — LaTeX math rendering
|
||||
- [[Mermaid diagrams]] — Diagram support via Mermaid
|
||||
- [[syntax highlighting]] — Code block highlighting with themes
|
||||
- [[OxHugo compatibility]] — Support for ox-hugo Markdown
|
||||
- [[Roam Research compatibility]] — Support for Roam Research syntax
|
||||
- [[Citations]] — Academic citation support
|
||||
- [[Canvas]] — Render Obsidian Canvas files as interactive pages
|
||||
- [[Bases]] — Database-like views for your notes (tables, cards, galleries, and more)
|
||||
|
||||
## Navigation & Discovery
|
||||
|
||||
- [[full-text search]] — Search across all your notes
|
||||
- [[graph view]] — Interactive graph visualization of note connections
|
||||
- [[backlinks]] — See which notes link to the current page
|
||||
- [[explorer]] — File tree sidebar for browsing notes
|
||||
- [[breadcrumbs]] — Breadcrumb navigation trail
|
||||
- [[table of contents]] — Per-page table of contents
|
||||
- [[folder and tag listings]] — Browse notes by folder or tag
|
||||
- [[recent notes]] — Display recently modified notes
|
||||
- [[popover previews]] — Hover previews for internal links
|
||||
- [[StackedPages|stacked pages]] — Andy Matuschak-style stacked sliding panes for tracing note connections
|
||||
- [[EncryptedPages|encrypted pages]] — Password-protect individual pages with client-side encryption
|
||||
|
||||
## Appearance & Reading
|
||||
|
||||
- [[darkmode]] — Light and dark mode toggle
|
||||
- [[reader mode]] — Distraction-free reading experience
|
||||
- [[comments]] — Add comments via Giscus, Utterances, or other providers
|
||||
- [[social images]] — Auto-generated Open Graph images for social sharing
|
||||
|
||||
## Publishing & Deployment
|
||||
|
||||
- [[RSS Feed]] — RSS feed generation for content syndication
|
||||
- [[private pages]] — Control which pages are published
|
||||
- [[SPA Routing]] — Single-page app navigation
|
||||
- [[Docker Support]] — Build and deploy with Docker
|
||||
- [[i18n]] — Internationalization with 30+ supported locales
|
||||
|
||||
@ -12,6 +12,6 @@ Similar to Obsidian, [[quartz-layout-desktop.png|images referenced using wikilin
|
||||
|
||||
## Configuration
|
||||
|
||||
- Remove popovers: set the `enablePopovers` field in `quartz.config.ts` to be `false`.
|
||||
- Remove popovers: set the `enablePopovers` field in `quartz.config.yaml` to be `false`.
|
||||
- Style: `quartz/components/styles/popover.scss`
|
||||
- Script: `quartz/components/scripts/popover.inline.ts`
|
||||
|
||||
@ -17,7 +17,7 @@ If you'd like to only publish a select number of notes, you can instead use [[Ex
|
||||
|
||||
## `ignorePatterns`
|
||||
|
||||
This is a field in `quartz.config.ts` under the main [[configuration]] which allows you to specify a list of patterns to effectively exclude from parsing all together. Any valid [fast-glob](https://github.com/mrmlnc/fast-glob#pattern-syntax) pattern works here.
|
||||
This is a field in `quartz.config.yaml` under the main [[configuration]] which allows you to specify a list of patterns to effectively exclude from parsing all together. Any valid [fast-glob](https://github.com/mrmlnc/fast-glob#pattern-syntax) pattern works here.
|
||||
|
||||
> [!note]
|
||||
> Bash's glob syntax is slightly different from fast-glob's and using bash's syntax may lead to unexpected results.
|
||||
|
||||
@ -6,15 +6,28 @@ tags:
|
||||
|
||||
Reader Mode is a feature that allows users to focus on the content by hiding the sidebars and other UI elements. When enabled, it provides a clean, distraction-free reading experience.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Configuration
|
||||
|
||||
Reader Mode is enabled by default. To disable it, you can remove the component from your layout configuration in `quartz.layout.ts`:
|
||||
Reader Mode is enabled by default. To disable it, set `enabled: false` in your `quartz.config.yaml`:
|
||||
|
||||
```ts
|
||||
// Remove or comment out this line
|
||||
Component.ReaderMode(),
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/reader-mode
|
||||
enabled: false
|
||||
```
|
||||
|
||||
Or remove the plugin entirely:
|
||||
|
||||
```bash
|
||||
npx quartz plugin remove github:quartz-community/reader-mode
|
||||
```
|
||||
|
||||
- Install: `npx quartz plugin add github:quartz-community/reader-mode`
|
||||
- Source: [`quartz-community/reader-mode`](https://github.com/quartz-community/reader-mode)
|
||||
|
||||
## Usage
|
||||
|
||||
The Reader Mode toggle appears as a button with a book icon. When clicked:
|
||||
|
||||
@ -3,15 +3,20 @@ title: Recent Notes
|
||||
tags: component
|
||||
---
|
||||
|
||||
Quartz can generate a list of recent notes based on some filtering and sorting criteria. Though this component isn't included in any [[layout]] by default, you can add it by using `Component.RecentNotes` in `quartz.layout.ts`.
|
||||
Quartz can generate a list of recent notes based on some filtering and sorting criteria. Though this component isn't included in any [[layout]] by default, you can add it by installing the plugin and configuring it in `quartz.config.yaml`.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Customization
|
||||
|
||||
- Changing the title from "Recent notes": pass in an additional parameter to `Component.RecentNotes({ title: "Recent writing" })`
|
||||
- Changing the number of recent notes: pass in an additional parameter to `Component.RecentNotes({ limit: 5 })`
|
||||
- Display the note's tags (defaults to true): `Component.RecentNotes({ showTags: false })`
|
||||
- Show a 'see more' link: pass in an additional parameter to `Component.RecentNotes({ linkToMore: "tags/components" })`. This field should be a full slug to a page that exists.
|
||||
- Customize filtering: pass in an additional parameter to `Component.RecentNotes({ filter: someFilterFunction })`. The filter function should be a function that has the signature `(f: QuartzPluginData) => boolean`.
|
||||
- Customize sorting: pass in an additional parameter to `Component.RecentNotes({ sort: someSortFunction })`. By default, Quartz will sort by date and then tie break lexographically. The sort function should be a function that has the signature `(f1: QuartzPluginData, f2: QuartzPluginData) => number`. See `byDateAndAlphabetical` in `quartz/components/PageList.tsx` for an example.
|
||||
- Component: `quartz/components/RecentNotes.tsx`
|
||||
- Style: `quartz/components/styles/recentNotes.scss`
|
||||
Most options are configured in the `options` section of the plugin entry in `quartz.config.yaml`:
|
||||
|
||||
- Changing the title from "Recent notes": set `title: "Recent writing"` in options
|
||||
- Changing the number of recent notes: set `limit: 5` in options
|
||||
- Display the note's tags (defaults to true): set `showTags: false` in options
|
||||
- Show a 'see more' link: set `linkToMore: "tags/components"` in options. This field should be a full slug to a page that exists.
|
||||
- Customize filtering: requires a TS override — pass `filter: someFilterFunction` to the plugin constructor in `quartz.ts`. The filter function should have the signature `(f: QuartzPluginData) => boolean`.
|
||||
- Customize sorting: requires a TS override — pass `sort: someSortFunction` to the plugin constructor in `quartz.ts`. By default, Quartz will sort by date and then tie break lexographically. The sort function should have the signature `(f1: QuartzPluginData, f2: QuartzPluginData) => number`.
|
||||
- Install: `npx quartz plugin add github:quartz-community/recent-notes`
|
||||
- Source: [`quartz-community/recent-notes`](https://github.com/quartz-community/recent-notes)
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
---
|
||||
draft: true
|
||||
---
|
||||
|
||||
## misc backlog
|
||||
|
||||
- static dead link detection
|
||||
- cursor chat extension
|
||||
- sidenotes? https://github.com/capnfabs/paperesque
|
||||
- direct match in search using double quotes
|
||||
- https://help.obsidian.md/Advanced+topics/Using+Obsidian+URI
|
||||
- Canvas
|
||||
@ -1,8 +1,10 @@
|
||||
---
|
||||
title: Authoring Content
|
||||
aliases:
|
||||
- "authoring content"
|
||||
---
|
||||
|
||||
All of the content in your Quartz should go in the `/content` folder. The content for the home page of your Quartz lives in `content/index.md`. If you've [[index#🪴 Get Started|setup Quartz]] already, this folder should already be initialized. Any Markdown in this folder will get processed by Quartz.
|
||||
All of the content in your Quartz should go in the `/content` folder. The content for the home page of your Quartz lives in `content/index.md`. If you've [[index#🪴 Get Started|setup Quartz]] already, this folder should already be initialized. Any Markdown in this folder will get processed by Quartz.
|
||||
|
||||
It is recommended that you use [Obsidian](https://obsidian.md/) as a way to edit and maintain your Quartz. It comes with a nice editor and graphical interface to preview, edit, and link your local files and attachments.
|
||||
|
||||
@ -40,7 +42,7 @@ See [[Frontmatter]] for a complete list of frontmatter.
|
||||
## Syncing your Content
|
||||
|
||||
When your Quartz is at a point you're happy with, you can save your changes to GitHub.
|
||||
First, make sure you've [[setting up your GitHub repository|already setup your GitHub repository]] and then do `npx quartz sync`.
|
||||
First, make sure you've [[getting-started/installation|already setup your GitHub repository]] and then do `npx quartz sync`.
|
||||
|
||||
## Customization
|
||||
|
||||
17
docs/getting-started/index.md
Normal file
17
docs/getting-started/index.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Getting Started
|
||||
---
|
||||
|
||||
Welcome to Quartz! This section will walk you through setting up your digital garden from scratch.
|
||||
|
||||
## Setup
|
||||
|
||||
1. **[[getting-started/installation|Installation]]** — Clone Quartz, create your repository, and push your first sync
|
||||
2. **[[getting-started/authoring-content|Authoring Content]]** — Write and organize your notes in the `content` folder
|
||||
3. **[[build|Building]]** — Preview your site locally with `npx quartz build --serve`
|
||||
4. **[[hosting|Hosting]]** — Deploy your Quartz site to the web
|
||||
|
||||
## Upgrading & Migrating
|
||||
|
||||
- **[[getting-started/upgrading|Upgrading Quartz]]** — Keep your Quartz installation up to date
|
||||
- **[[getting-started/migrating|Migrating to Quartz 5]]** — Migrate from Quartz 4 or Quartz 3
|
||||
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Setting up your GitHub repository
|
||||
title: "Installation"
|
||||
aliases:
|
||||
- "setting up your GitHub repository"
|
||||
---
|
||||
|
||||
First, make sure you have Quartz [[index#🪴 Get Started|cloned and setup locally]].
|
||||
@ -8,7 +10,7 @@ Then, create a new repository on GitHub.com. Do **not** initialize the new repos
|
||||
|
||||
![[github-init-repo-options.png]]
|
||||
|
||||
At the top of your repository on GitHub.com's Quick Setup page, click the clipboard to copy the remote repository URL.
|
||||
At the top of your repository on GitHub.com's Quick Setup page, click the clipboard to copy the remote repository URL.
|
||||
|
||||
![[github-quick-setup.png]]
|
||||
|
||||
359
docs/getting-started/migrating.md
Normal file
359
docs/getting-started/migrating.md
Normal file
@ -0,0 +1,359 @@
|
||||
---
|
||||
title: "Migrating to Quartz 5"
|
||||
aliases:
|
||||
- "migrating from Quartz 3"
|
||||
- "migrating from Quartz 4"
|
||||
---
|
||||
|
||||
This guide covers migrating to Quartz 5 from previous versions. If you're already on Quartz 5 and want to update to the latest version, see [[getting-started/upgrading|Upgrading Quartz]] instead.
|
||||
|
||||
## Migrating from Quartz 4
|
||||
|
||||
### Overview
|
||||
|
||||
Quartz 5 introduces a community plugin system that fundamentally changes how plugins and components are managed. Most plugins that were built into Quartz 4 are now standalone community plugins maintained under the [quartz-community](https://github.com/quartz-community) organization. This guide walks through the changes needed to migrate your configuration.
|
||||
|
||||
### What Changed
|
||||
|
||||
- **Plugin system**: Plugins are now standalone Git repositories, installed via `npx quartz plugin add`
|
||||
- **Import pattern**: Community plugins use `ExternalPlugin.X()` (from `.quartz/plugins`) instead of `Plugin.X()` (from `./quartz/plugins`)
|
||||
- **Layout structure**: `quartz.layout.ts` is gone — layout position is now a per-plugin property in `quartz.config.yaml`, with `layout.groups` for flex containers (e.g. toolbar) and `layout.byPageType` for per-page-type overrides
|
||||
- **Page Types**: A new plugin category for page rendering (content, folder, tag pages)
|
||||
- **Component references**: In layout files, community components use `Plugin.X()` (from `.quartz/plugins`) instead of `Component.X()` (from `./quartz/components`)
|
||||
|
||||
### Step-by-Step Migration
|
||||
|
||||
#### 1. Set Up Quartz 5 with a Template
|
||||
|
||||
The easiest way to migrate is to use `npx quartz create`, which generates a complete `quartz.config.yaml` from a template with all default plugins pre-configured:
|
||||
|
||||
```shell
|
||||
npx quartz create --template default --strategy copy --source /path/to/your/content
|
||||
```
|
||||
|
||||
Available templates: `default`, `obsidian`, `ttrpg`, `blog`. Pick the one closest to your setup — `obsidian` is recommended if you use an Obsidian vault.
|
||||
|
||||
> [!tip] Choosing a template
|
||||
> Each template comes with all 30+ default plugins pre-configured. The main differences are content strategy (OFM support, link resolution) and optional plugins (comments, maps). You can customize everything in `quartz.config.yaml` afterward.
|
||||
|
||||
After running `create`, install all the plugins referenced in the generated config:
|
||||
|
||||
```shell
|
||||
npx quartz plugin resolve
|
||||
```
|
||||
|
||||
This reads your `quartz.config.yaml` and installs every plugin listed in it. No need to run 30 individual `npx quartz plugin add` commands.
|
||||
|
||||
> [!note] Custom or optional plugins
|
||||
> If you used optional plugins in v4 (comments, reader-mode, breadcrumbs, recent-notes, citations, etc.), add them after the initial setup:
|
||||
>
|
||||
> ```shell
|
||||
> npx quartz plugin add github:quartz-community/comments
|
||||
> npx quartz plugin add github:quartz-community/reader-mode
|
||||
> npx quartz plugin add github:quartz-community/breadcrumbs
|
||||
> npx quartz plugin add github:quartz-community/recent-notes
|
||||
> ```
|
||||
>
|
||||
> See [[plugins/index|Plugins]] for the full list of available community plugins.
|
||||
|
||||
> [!info] Alternative: Use `npx quartz migrate`
|
||||
> If you have an existing `quartz.config.ts` and `quartz.layout.ts` from v4, you can run `npx quartz migrate` instead. This reads your old config files and generates `quartz.config.yaml` with your existing settings. You'll still need to run `npx quartz plugin resolve` afterward to install the plugins. See [[cli/migrate|quartz migrate]] for details.
|
||||
|
||||
#### 2. Update quartz.config.yaml
|
||||
|
||||
**Before (v4):**
|
||||
|
||||
```ts title="quartz.config.ts"
|
||||
import * as Plugin from "./quartz/plugins"
|
||||
|
||||
plugins: {
|
||||
transformers: [
|
||||
Plugin.FrontMatter(),
|
||||
Plugin.CreatedModifiedDate({ priority: ["frontmatter", "git", "filesystem"] }),
|
||||
Plugin.Latex({ renderEngine: "katex" }),
|
||||
],
|
||||
filters: [Plugin.RemoveDrafts()],
|
||||
emitters: [
|
||||
Plugin.AliasRedirects(),
|
||||
Plugin.ComponentResources(),
|
||||
Plugin.ContentPage(),
|
||||
Plugin.FolderPage(),
|
||||
Plugin.TagPage(),
|
||||
Plugin.ContentIndex({ enableSiteMap: true, enableRSS: true }),
|
||||
Plugin.Assets(),
|
||||
Plugin.Static(),
|
||||
Plugin.NotFoundPage(),
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
**After (v5):**
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/note-properties
|
||||
enabled: true
|
||||
options:
|
||||
delimiters: "---"
|
||||
language: yaml
|
||||
order: 5
|
||||
- source: github:quartz-community/created-modified-date
|
||||
enabled: true
|
||||
options:
|
||||
priority:
|
||||
- frontmatter
|
||||
- git
|
||||
- filesystem
|
||||
order: 10
|
||||
- source: github:quartz-community/latex
|
||||
enabled: true
|
||||
options:
|
||||
renderEngine: katex
|
||||
order: 80
|
||||
- source: github:quartz-community/remove-draft
|
||||
enabled: true
|
||||
- source: github:quartz-community/alias-redirects
|
||||
enabled: true
|
||||
- source: github:quartz-community/content-index
|
||||
enabled: true
|
||||
options:
|
||||
enableSiteMap: true
|
||||
enableRSS: true
|
||||
- source: github:quartz-community/favicon
|
||||
enabled: true
|
||||
- source: github:quartz-community/og-image
|
||||
enabled: true
|
||||
- source: github:quartz-community/cname
|
||||
enabled: true
|
||||
- source: github:quartz-community/content-page
|
||||
enabled: true
|
||||
- source: github:quartz-community/folder-page
|
||||
enabled: true
|
||||
- source: github:quartz-community/tag-page
|
||||
enabled: true
|
||||
# ... more plugins
|
||||
```
|
||||
|
||||
Key changes:
|
||||
|
||||
- Plugins are now referenced by their GitHub source (`github:org/repo`)
|
||||
- Plugin type (transformer, filter, emitter, pageType) is determined by the plugin's manifest, not by which array you place it in
|
||||
- Execution order is controlled by the `order` field (lower numbers run first)
|
||||
- Each plugin entry has `enabled`, `options`, `order`, and optionally `layout` fields
|
||||
- Install community plugins with `npx quartz plugin add github:quartz-community/<name>`
|
||||
|
||||
#### 3. Update layout configuration
|
||||
|
||||
**Before (v4):**
|
||||
|
||||
```ts title="quartz.layout.ts"
|
||||
import * as Component from "./quartz/components"
|
||||
|
||||
export const sharedPageComponents: SharedLayout = {
|
||||
head: Component.Head(),
|
||||
header: [],
|
||||
afterBody: [],
|
||||
footer: Component.Footer({ links: { ... } }),
|
||||
}
|
||||
|
||||
export const defaultContentPageLayout: PageLayout = {
|
||||
beforeBody: [Component.Breadcrumbs(), Component.ArticleTitle(), Component.ContentMeta(), Component.TagList()],
|
||||
left: [Component.PageTitle(), Component.Search(), Component.Darkmode(), Component.Explorer()],
|
||||
right: [Component.Graph(), Component.TableOfContents(), Component.Backlinks()],
|
||||
}
|
||||
```
|
||||
|
||||
**After (v5):**
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/breadcrumbs
|
||||
enabled: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 5
|
||||
- source: github:quartz-community/article-title
|
||||
enabled: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 10
|
||||
- source: github:quartz-community/content-meta
|
||||
enabled: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 20
|
||||
- source: github:quartz-community/tag-list
|
||||
enabled: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 30
|
||||
- source: github:quartz-community/page-title
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 10
|
||||
- source: github:quartz-community/search
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 20
|
||||
- source: github:quartz-community/darkmode
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 30
|
||||
- source: github:quartz-community/explorer
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 50
|
||||
- source: github:quartz-community/graph
|
||||
enabled: true
|
||||
layout:
|
||||
position: right
|
||||
priority: 10
|
||||
- source: github:quartz-community/backlinks
|
||||
enabled: true
|
||||
layout:
|
||||
position: right
|
||||
priority: 30
|
||||
- source: github:quartz-community/footer
|
||||
enabled: true
|
||||
options:
|
||||
links:
|
||||
GitHub: https://github.com/jackyzha0/quartz
|
||||
Discord Community: https://discord.gg/cRFFHYye7t
|
||||
|
||||
layout:
|
||||
byPageType:
|
||||
content: {}
|
||||
folder:
|
||||
exclude:
|
||||
- reader-mode
|
||||
positions:
|
||||
right: []
|
||||
tag:
|
||||
exclude:
|
||||
- reader-mode
|
||||
positions:
|
||||
right: []
|
||||
"404":
|
||||
positions:
|
||||
beforeBody: []
|
||||
left: []
|
||||
right: []
|
||||
```
|
||||
|
||||
Key changes:
|
||||
|
||||
- Layout position is now a property on each plugin entry (`layout.position`, `layout.priority`)
|
||||
- `sharedPageComponents` is gone — all layout is plugin-driven
|
||||
- Per-page-type overrides live in the `layout.byPageType` section
|
||||
- Empty arrays (`[]`) clear a position for that page type
|
||||
- The `exclude` field removes specific plugins from a page type
|
||||
|
||||
#### 4. Update CI/CD
|
||||
|
||||
Add `npx quartz plugin restore` to your build pipeline, before `npx quartz build`. This installs plugins from the lockfile at their pinned versions.
|
||||
|
||||
If your CI uses `quartz.config.default.yaml` (or contributors may add plugins to config without updating the lockfile), also run `npx quartz plugin resolve` to install any config-referenced plugins that are missing from the lockfile:
|
||||
|
||||
```shell
|
||||
npx quartz plugin restore # install pinned plugins from lockfile
|
||||
npx quartz plugin resolve # install any config-referenced plugins not yet in lockfile
|
||||
npx quartz build
|
||||
```
|
||||
|
||||
See [[hosting]] for detailed CI/CD examples and [[ci-cd]] for advanced configuration.
|
||||
|
||||
#### 5. Commit and Deploy
|
||||
|
||||
```shell
|
||||
git add quartz.config.yaml quartz.lock.json
|
||||
git commit -m "chore: migrate to Quartz 5 plugin system"
|
||||
```
|
||||
|
||||
> [!tip] Cleaning up leftover plugins
|
||||
> After migrating, you may have plugins installed from v4 that are no longer in your v5 config. Run `npx quartz plugin prune` to remove them. Use `--dry-run` first to preview what would be removed.
|
||||
|
||||
### Plugin Reference Table
|
||||
|
||||
Mapping v4 plugin names to v5 equivalents:
|
||||
|
||||
| v4 | v5 | Type |
|
||||
| ----------------------------------- | ------------------------------------------- | --------------------- |
|
||||
| `Plugin.FrontMatter()` | `Plugin.FrontMatter()` (unchanged) | Internal |
|
||||
| `Plugin.CreatedModifiedDate()` | `ExternalPlugin.CreatedModifiedDate()` | Community |
|
||||
| `Plugin.SyntaxHighlighting()` | `ExternalPlugin.SyntaxHighlighting()` | Community |
|
||||
| `Plugin.ObsidianFlavoredMarkdown()` | `ExternalPlugin.ObsidianFlavoredMarkdown()` | Community |
|
||||
| `Plugin.GitHubFlavoredMarkdown()` | `ExternalPlugin.GitHubFlavoredMarkdown()` | Community |
|
||||
| `Plugin.CrawlLinks()` | `ExternalPlugin.CrawlLinks()` | Community |
|
||||
| `Plugin.Description()` | `ExternalPlugin.Description()` | Community |
|
||||
| `Plugin.Latex()` | `ExternalPlugin.Latex()` | Community |
|
||||
| `Plugin.RemoveDrafts()` | `ExternalPlugin.RemoveDrafts()` | Community |
|
||||
| `Plugin.ContentPage()` | `ExternalPlugin.ContentPage()` | Community (pageTypes) |
|
||||
| `Plugin.FolderPage()` | `ExternalPlugin.FolderPage()` | Community (pageTypes) |
|
||||
| `Plugin.TagPage()` | `ExternalPlugin.TagPage()` | Community (pageTypes) |
|
||||
| `Plugin.NotFoundPage()` | `Plugin.PageTypes.NotFoundPageType()` | Internal (pageTypes) |
|
||||
| `Plugin.ComponentResources()` | `Plugin.ComponentResources()` (unchanged) | Internal |
|
||||
| `Plugin.Assets()` | `Plugin.Assets()` (unchanged) | Internal |
|
||||
| `Plugin.Static()` | `Plugin.Static()` (unchanged) | Internal |
|
||||
| `Plugin.AliasRedirects()` | `ExternalPlugin.AliasRedirects()` | Community |
|
||||
| `Plugin.ContentIndex()` | `ExternalPlugin.ContentIndex()` | Community |
|
||||
|
||||
Component layout mapping:
|
||||
|
||||
| v4 Layout | v5 Layout |
|
||||
| ----------------------------- | ------------------------------------------ |
|
||||
| `Component.Explorer()` | `Plugin.Explorer()` |
|
||||
| `Component.Graph()` | `Plugin.Graph()` |
|
||||
| `Component.Search()` | `Plugin.Search()` |
|
||||
| `Component.Backlinks()` | `Plugin.Backlinks()` |
|
||||
| `Component.Darkmode()` | `Plugin.Darkmode()` |
|
||||
| `Component.Footer()` | `Plugin.Footer()` |
|
||||
| `Component.TableOfContents()` | `Plugin.TableOfContents()` |
|
||||
| `Component.Head()` | `Component.Head()` (unchanged, internal) |
|
||||
| `Component.Spacer()` | `Component.Spacer()` (unchanged, internal) |
|
||||
|
||||
---
|
||||
|
||||
## Migrating from Quartz 3
|
||||
|
||||
As you already have Quartz locally, you don't need to fork or clone it again. Simply just checkout the v4 branch, install the dependencies, restore plugins, and import your old vault. Then follow the [Quartz 4 migration steps above](#migrating-from-quartz-4) to get to v5.
|
||||
|
||||
```bash
|
||||
git fetch
|
||||
git checkout v4
|
||||
git pull upstream v4
|
||||
npm i
|
||||
npx quartz plugin restore
|
||||
npx quartz create
|
||||
```
|
||||
|
||||
If you get an error like `fatal: 'upstream' does not appear to be a git repository`, make sure you add `upstream` as a remote origin:
|
||||
|
||||
```shell
|
||||
git remote add upstream https://github.com/jackyzha0/quartz.git
|
||||
```
|
||||
|
||||
When running `npx quartz create`, you will be prompted as to how to initialize your content folder. Here, you can choose to import or link your previous content folder and Quartz should work just as you expect it to.
|
||||
|
||||
> [!note]
|
||||
> If the existing content folder you'd like to use is at the _same_ path on a different branch, clone the repo again somewhere at a _different_ path in order to use it.
|
||||
|
||||
### Key changes from Quartz 3
|
||||
|
||||
1. **Removing Hugo and `hugo-obsidian`**: Hugo worked well for earlier versions of Quartz but it also made it hard for people outside of the Golang and Hugo communities to fully understand what Quartz was doing under the hood and be able to properly customize it to their needs. Quartz now uses a Node-based static-site generation process which should lead to much more helpful error messages and an overall smoother user experience.
|
||||
2. **Full-hot reload**: The many rough edges of how `hugo-obsidian` integrated with Hugo meant that watch mode didn't re-trigger `hugo-obsidian` to update the content index. This lead to a lot of weird cases where the watch mode output wasn't accurate. Quartz now uses a cohesive parse, filter, and emit pipeline which gets run on every change so hot-reloads are always accurate.
|
||||
3. **Replacing Go template syntax with JSX**: Quartz 3 used [Go templates](https://pkg.go.dev/text/template) to create layouts for pages. However, the syntax isn't great for doing any sort of complex rendering (like [text processing](https://github.com/jackyzha0/quartz/blob/hugo/layouts/partials/textprocessing.html)) and it got very difficult to make any meaningful layout changes to Quartz 3. Quartz now uses an extension of JavaScript syntax called JSX which allows you to write layout code that looks like HTML in JavaScript which is significantly easier to understand and maintain.
|
||||
4. **A new extensible [[configuration]] and [[configuration#Plugins|plugin]] system**: Quartz 3 was hard to configure without technical knowledge of how Hugo's partials worked. Extensions were even hard to make. Quartz 5's configuration and plugin system is designed to be extended by users while making updating to new versions of Quartz easy.
|
||||
|
||||
### Things to update
|
||||
|
||||
- You will need to update your deploy scripts. See the [[hosting]] guide for more details.
|
||||
- Ensure that your default branch on GitHub is updated from `hugo` to `v5`.
|
||||
- [[folder and tag listings|Folder and tag listings]] have also changed.
|
||||
- Folder descriptions should go under `content/<folder-name>/index.md` where `<folder-name>` is the name of the folder.
|
||||
- Tag descriptions should go under `content/tags/<tag-name>.md` where `<tag-name>` is the name of the tag.
|
||||
- Some HTML layout may not be the same between Quartz 3 and Quartz 5. If you depended on a particular HTML hierarchy or class names, you may need to update your custom CSS to reflect these changes.
|
||||
- If you customized the layout of Quartz 3, you may need to translate these changes from Go templates back to JSX as Quartz 5 no longer uses Hugo. For components, check out the guide on [[creating components]] for more details on this.
|
||||
40
docs/getting-started/upgrading.md
Normal file
40
docs/getting-started/upgrading.md
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
title: "Upgrading Quartz"
|
||||
aliases:
|
||||
- upgrading
|
||||
---
|
||||
|
||||
> [!note]
|
||||
> This is specifically a guide for upgrading your Quartz to a more recent update. If you are coming from Quartz 4 or Quartz 3, check out the [[getting-started/migrating|migration guide]] for more info.
|
||||
|
||||
To fetch the latest Quartz updates, simply run
|
||||
|
||||
```bash
|
||||
npx quartz upgrade
|
||||
```
|
||||
|
||||
As Quartz uses [git](https://git-scm.com/) under the hood for versioning, upgrading effectively 'pulls' in the updates from the official Quartz GitHub repository. If you have local changes that might conflict with the updates, you may need to resolve these manually yourself (or, pull manually using `git pull origin upstream`).
|
||||
|
||||
> [!hint]
|
||||
> Quartz will try to cache your content before upgrading to try and prevent merge conflicts. If you get a conflict mid-merge, you can stop the merge and then run `npx quartz restore` to restore your content from the cache.
|
||||
|
||||
If you have the [GitHub desktop app](https://desktop.github.com/), this will automatically open to help you resolve the conflicts. Otherwise, you will need to resolve this in a text editor like VSCode. For more help on resolving conflicts manually, check out the [GitHub guide on resolving merge conflicts](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line#competing-line-change-merge-conflicts).
|
||||
|
||||
To update your installed plugins separately, use:
|
||||
|
||||
```bash
|
||||
npx quartz update
|
||||
```
|
||||
|
||||
See the [[cli/update|CLI reference for update]] and [[cli/upgrade|CLI reference for upgrade]] for more details on available flags.
|
||||
|
||||
### Cleaning Up Unused Plugins
|
||||
|
||||
If you've removed plugins from your configuration during an upgrade, you can clean up the leftover files:
|
||||
|
||||
```bash
|
||||
npx quartz plugin prune --dry-run # preview what would be removed
|
||||
npx quartz plugin prune # remove orphaned plugins
|
||||
```
|
||||
|
||||
See the [[cli/plugin#prune|plugin prune reference]] for more details.
|
||||
@ -12,25 +12,31 @@ However, if you'd like to publish your site to the world, you need a way to host
|
||||
> [!hint]
|
||||
> Some Quartz features (like [[RSS Feed]] and sitemap generation) require `baseUrl` to be configured properly in your [[configuration]] to work properly. Make sure you set this before deploying!
|
||||
|
||||
> [!tip] Keeping plugins in sync
|
||||
> All hosting examples below use `npx quartz plugin restore` to install plugins from the lockfile. If contributors may add plugins to `quartz.config.yaml` without updating the lockfile, add `npx quartz plugin resolve` after `restore` in your build command to install any missing plugins. See [[cli/plugin#resolve|plugin resolve]] for details.
|
||||
|
||||
## Cloudflare Pages
|
||||
|
||||
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/) and select your account.
|
||||
2. In Account Home, select **Compute (Workers)** > **Workers & Pages** > **Create application** > **Pages** > **Connect to Git**.
|
||||
3. Select the new GitHub repository that you created and, in the **Set up builds and deployments** section, provide the following information:
|
||||
|
||||
| Configuration option | Value |
|
||||
| ---------------------- | ------------------ |
|
||||
| Production branch | `v4` |
|
||||
| Framework preset | `None` |
|
||||
| Build command | `npx quartz build` |
|
||||
| Build output directory | `public` |
|
||||
| Configuration option | Value |
|
||||
| ---------------------- | ----------------------------------------------- |
|
||||
| Production branch | `v5` |
|
||||
| Framework preset | `None` |
|
||||
| Build command | `npx quartz plugin restore && npx quartz build` |
|
||||
| Build output directory | `public` |
|
||||
|
||||
Press "Save and deploy" and Cloudflare should have a deployed version of your site in about a minute. Then, every time you sync your Quartz changes to GitHub, your site should be updated.
|
||||
|
||||
To add a custom domain, check out [Cloudflare's documentation](https://developers.cloudflare.com/pages/platform/custom-domains/).
|
||||
|
||||
> [!warning]
|
||||
> Cloudflare Pages performs a shallow clone by default, so if you rely on `git` for timestamps, it is recommended that you add `git fetch --unshallow &&` to the beginning of the build command (e.g., `git fetch --unshallow && npx quartz build`).
|
||||
> Cloudflare Pages performs a shallow clone by default, so if you rely on `git` for timestamps, it is recommended that you add `git fetch --unshallow &&` to the beginning of the build command (e.g., `git fetch --unshallow && npx quartz plugin restore && npx quartz build`).
|
||||
|
||||
> [!note]
|
||||
> For more detailed CI/CD configuration including caching and plugin management, see [[ci-cd]].
|
||||
|
||||
## GitHub Pages
|
||||
|
||||
@ -42,7 +48,7 @@ name: Deploy Quartz site to GitHub Pages
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v4
|
||||
- v5
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@ -65,6 +71,8 @@ jobs:
|
||||
node-version: 22
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Restore Quartz plugins
|
||||
run: npx quartz plugin restore
|
||||
- name: Build Quartz
|
||||
run: npx quartz build
|
||||
- name: Upload artifact
|
||||
@ -140,11 +148,11 @@ Before deploying to Vercel, a `vercel.json` file is required at the root of the
|
||||
3. Give the project a name (lowercase characters and hyphens only)
|
||||
4. Check that these configuration options are set:
|
||||
|
||||
| Configuration option | Value |
|
||||
| ----------------------------------------- | ------------------ |
|
||||
| Framework Preset | `Other` |
|
||||
| Root Directory | `./` |
|
||||
| Build and Output Settings > Build Command | `npx quartz build` |
|
||||
| Configuration option | Value |
|
||||
| ----------------------------------------- | ----------------------------------------------- |
|
||||
| Framework Preset | `Other` |
|
||||
| Root Directory | `./` |
|
||||
| Build and Output Settings > Build Command | `npx quartz plugin restore && npx quartz build` |
|
||||
|
||||
5. Press Deploy. Once it's live, you'll have 2 `*.vercel.app` URLs to view the page.
|
||||
|
||||
@ -153,7 +161,7 @@ Before deploying to Vercel, a `vercel.json` file is required at the root of the
|
||||
> [!note]
|
||||
> If there is something already hosted on the domain, these steps will not work without replacing the previous content. As a workaround, you could use Next.js rewrites or use the next section to create a subdomain.
|
||||
|
||||
1. Update the `baseUrl` in `quartz.config.js` if necessary.
|
||||
1. Update the `baseUrl` in `quartz.config.yaml` if necessary.
|
||||
2. Go to the [Domains - Dashboard](https://vercel.com/dashboard/domains) page in Vercel.
|
||||
3. Connect the domain to Vercel
|
||||
4. Press "Add" to connect a custom domain to Vercel.
|
||||
@ -165,7 +173,7 @@ Before deploying to Vercel, a `vercel.json` file is required at the root of the
|
||||
|
||||
Using `docs.example.com` is an example of a subdomain. They're a simple way of connecting multiple deployments to one domain.
|
||||
|
||||
1. Update the `baseUrl` in `quartz.config.js` if necessary.
|
||||
1. Update the `baseUrl` in `quartz.config.yaml` if necessary.
|
||||
2. Ensure your domain has been added to the [Domains - Dashboard](https://vercel.com/dashboard/domains) page in Vercel.
|
||||
3. Go to the [Vercel Dashboard](https://vercel.com/dashboard) and select your Quartz project.
|
||||
4. Go to the Settings tab and then click Domains in the sidebar
|
||||
@ -175,7 +183,7 @@ Using `docs.example.com` is an example of a subdomain. They're a simple way of c
|
||||
|
||||
1. Log in to the [Netlify dashboard](https://app.netlify.com/) and click "Add new site".
|
||||
2. Select your Git provider and repository containing your Quartz project.
|
||||
3. Under "Build command", enter `npx quartz build`.
|
||||
3. Under "Build command", enter `npx quartz plugin restore && npx quartz build`.
|
||||
4. Under "Publish directory", enter `public`.
|
||||
5. Press Deploy. Once it's live, you'll have a `*.netlify.app` URL to view the page.
|
||||
6. To add a custom domain, check "Domain management" in the left sidebar, just like with Vercel.
|
||||
@ -198,11 +206,12 @@ cache: # Cache modules in between jobs
|
||||
build:
|
||||
stage: build
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME == "v4"'
|
||||
- if: '$CI_COMMIT_REF_NAME == "v5"'
|
||||
before_script:
|
||||
- hash -r
|
||||
- npm ci --cache .npm --prefer-offline
|
||||
script:
|
||||
- npx quartz plugin restore
|
||||
- npx quartz build
|
||||
artifacts:
|
||||
paths:
|
||||
@ -213,7 +222,7 @@ build:
|
||||
pages:
|
||||
stage: deploy
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME == "v4"'
|
||||
- if: '$CI_COMMIT_REF_NAME == "v5"'
|
||||
script:
|
||||
- echo "Deploying to GitLab Pages..."
|
||||
artifacts:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Welcome to Quartz 4
|
||||
title: Welcome to Quartz 5
|
||||
---
|
||||
|
||||
Quartz is a fast, batteries-included static-site generator that transforms Markdown content into fully functional websites. Thousands of students, developers, and teachers are [[showcase|already using Quartz]] to publish personal notes, websites, and [digital gardens](https://jzhao.xyz/posts/networked-thought) to the web.
|
||||
@ -11,13 +11,14 @@ Quartz requires **at least [Node](https://nodejs.org/) v22** and `npm` v10.9.2 t
|
||||
Then, in your terminal of choice, enter the following commands line by line:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/jackyzha0/quartz.git
|
||||
git clone -b v5 https://github.com/jackyzha0/quartz.git
|
||||
cd quartz
|
||||
npm i
|
||||
npx quartz plugin restore
|
||||
npx quartz create
|
||||
```
|
||||
|
||||
This will guide you through initializing your Quartz with content. Once you've done so, see how to:
|
||||
This will guide you through initializing your Quartz with content, including choosing a [[cli/create#templates|project template]] and configuring your site's base URL. Once you've done so, see how to:
|
||||
|
||||
1. [[authoring content|Writing content]] in Quartz
|
||||
2. [[configuration|Configure]] Quartz's behaviour
|
||||
@ -26,9 +27,6 @@ This will guide you through initializing your Quartz with content. Once you've d
|
||||
5. Sync your changes with [[setting up your GitHub repository|GitHub]]
|
||||
6. [[hosting|Host]] Quartz online
|
||||
|
||||
If you prefer instructions in a video format you can try following Nicole van der Hoeven's
|
||||
[video guide on how to set up Quartz!](https://www.youtube.com/watch?v=6s6DT1yN4dw&t=227s)
|
||||
|
||||
## 🔧 Features
|
||||
|
||||
- [[Obsidian compatibility]], [[full-text search]], [[graph view]], [[wikilinks|wikilinks, transclusions]], [[backlinks]], [[features/Latex|Latex]], [[syntax highlighting]], [[popover previews]], [[Docker Support]], [[i18n|internationalization]], [[comments]] and [many more](./features/) right out of the box
|
||||
@ -41,6 +39,6 @@ For a comprehensive list of features, visit the [features page](./features/). Yo
|
||||
|
||||
### 🚧 Troubleshooting + Updating
|
||||
|
||||
Having trouble with Quartz? Try searching for your issue using the search feature. If you haven't already, [[upgrading|upgrade]] to the newest version of Quartz to see if this fixes your issue.
|
||||
Having trouble with Quartz? Try searching for your issue using the search feature or check the [[troubleshooting]] page. If you haven't already, [[upgrading|upgrade]] to the newest version of Quartz to see if this fixes your issue.
|
||||
|
||||
If you're still having trouble, feel free to [submit an issue](https://github.com/jackyzha0/quartz/issues) if you feel you found a bug or ask for help in our [Discord Community](https://discord.gg/cRFFHYye7t).
|
||||
If you're still having trouble, feel free to [submit an issue](https://github.com/jackyzha0/quartz/issues) if you feel you found a bug or ask for help in our [Discord Community](https://discord.gg/cRFFHYye7t). You can also browse the [[community]] page for third-party plugins and resources.
|
||||
|
||||
@ -4,20 +4,93 @@ title: Higher-Order Layout Components
|
||||
|
||||
Quartz provides several higher-order components that help with layout composition and responsive design. These components wrap other components to add additional functionality or modify their behavior.
|
||||
|
||||
Most common use cases can be configured directly in `quartz.config.yaml` using layout properties. For advanced scenarios requiring custom logic, you can use the TS override approach in `quartz.ts`.
|
||||
|
||||
## `Flex` Component
|
||||
|
||||
The `Flex` component creates a [flexible box layout](https://developer.mozilla.org/en-US/docs/Web/CSS/flex) that can arrange child components in various ways. It's particularly useful for creating responsive layouts and organizing components in rows or columns.
|
||||
|
||||
### YAML Configuration
|
||||
|
||||
In YAML, flex layouts are created using **groups**. Define a group in the top-level `layout.groups` section, then assign plugins to that group via their `layout.group` property:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/search
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 20
|
||||
group: toolbar
|
||||
groupOptions:
|
||||
grow: true # Search will grow to fill available space
|
||||
- source: github:quartz-community/darkmode
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 30
|
||||
group: toolbar # Darkmode keeps its natural size
|
||||
- source: github:quartz-community/reader-mode
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 35
|
||||
group: toolbar
|
||||
|
||||
layout:
|
||||
groups:
|
||||
toolbar:
|
||||
direction: row
|
||||
gap: 0.5rem
|
||||
```
|
||||
|
||||
The `groupOptions` field on each plugin entry supports the following flex item properties:
|
||||
|
||||
| Option | Type | Description |
|
||||
| --------- | --------------------------------------------------------------- | --------------------------------------------------------- |
|
||||
| `grow` | `boolean` | Whether the component should grow to fill available space |
|
||||
| `shrink` | `boolean` | Whether the component should shrink if needed |
|
||||
| `basis` | `string` | Initial main size of the component (e.g., `"200px"`) |
|
||||
| `order` | `number` | Order in the flex container |
|
||||
| `align` | `"start"` \| `"end"` \| `"center"` \| `"stretch"` | Cross-axis alignment |
|
||||
| `justify` | `"start"` \| `"end"` \| `"center"` \| `"between"` \| `"around"` | Main-axis alignment |
|
||||
|
||||
The top-level `layout.groups` section configures the flex container itself:
|
||||
|
||||
| Option | Type | Description |
|
||||
| ----------- | -------------------------------------------------------------- | ----------------------------------------- |
|
||||
| `direction` | `"row"` \| `"row-reverse"` \| `"column"` \| `"column-reverse"` | Flex direction |
|
||||
| `wrap` | `"nowrap"` \| `"wrap"` \| `"wrap-reverse"` | Flex wrap behavior |
|
||||
| `gap` | `string` | Gap between flex items (e.g., `"0.5rem"`) |
|
||||
|
||||
### TS Override
|
||||
|
||||
For full programmatic control, use the `Component.Flex()` wrapper in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
Component.Flex({
|
||||
components: [
|
||||
{
|
||||
Component: Plugin.Search(),
|
||||
grow: true, // Search will grow to fill available space
|
||||
},
|
||||
{ Component: Plugin.Darkmode() }, // Darkmode keeps its natural size
|
||||
],
|
||||
direction: "row",
|
||||
gap: "1rem",
|
||||
})
|
||||
```
|
||||
|
||||
```typescript
|
||||
type FlexConfig = {
|
||||
components: {
|
||||
Component: QuartzComponent
|
||||
grow?: boolean // whether component should grow to fill space
|
||||
shrink?: boolean // whether component should shrink if needed
|
||||
basis?: string // initial main size of the component
|
||||
order?: number // order in flex container
|
||||
align?: "start" | "end" | "center" | "stretch" // cross-axis alignment
|
||||
justify?: "start" | "end" | "center" | "between" | "around" // main-axis alignment
|
||||
grow?: boolean
|
||||
shrink?: boolean
|
||||
basis?: string
|
||||
order?: number
|
||||
align?: "start" | "end" | "center" | "stretch"
|
||||
justify?: "start" | "end" | "center" | "between" | "around"
|
||||
}[]
|
||||
direction?: "row" | "row-reverse" | "column" | "column-reverse"
|
||||
wrap?: "nowrap" | "wrap" | "wrap-reverse"
|
||||
@ -25,24 +98,8 @@ type FlexConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Example Usage
|
||||
|
||||
```typescript
|
||||
Component.Flex({
|
||||
components: [
|
||||
{
|
||||
Component: Component.Search(),
|
||||
grow: true, // Search will grow to fill available space
|
||||
},
|
||||
{ Component: Component.Darkmode() }, // Darkmode keeps its natural size
|
||||
],
|
||||
direction: "row",
|
||||
gap: "1rem",
|
||||
})
|
||||
```
|
||||
|
||||
> [!note] Overriding behavior
|
||||
> Components inside `Flex` get an additional CSS class `flex-component` that add the `display: flex` property. If you want to override this behavior, you can add a `display` property to the component's CSS class in your custom CSS file.
|
||||
> Components inside `Flex` get an additional CSS class `flex-component` that adds the `display: flex` property. If you want to override this behavior, you can add a `display` property to the component's CSS class in your custom CSS file.
|
||||
>
|
||||
> ```scss
|
||||
> .flex-component {
|
||||
@ -50,29 +107,81 @@ Component.Flex({
|
||||
> }
|
||||
> ```
|
||||
|
||||
## `MobileOnly` Component
|
||||
## `MobileOnly` / `DesktopOnly` Components
|
||||
|
||||
The `MobileOnly` component is a wrapper that makes its child component only visible on mobile devices. This is useful for creating responsive layouts where certain components should only appear on smaller screens.
|
||||
These components control whether a plugin is visible on mobile or desktop devices. This is useful for creating responsive layouts where certain components should only appear on specific screen sizes.
|
||||
|
||||
### Example Usage
|
||||
### YAML Configuration
|
||||
|
||||
```typescript
|
||||
In YAML, use the `display` property on a plugin's layout entry:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/table-of-contents
|
||||
enabled: true
|
||||
layout:
|
||||
position: right
|
||||
priority: 20
|
||||
display: desktop-only # Only visible on desktop
|
||||
```
|
||||
|
||||
Available `display` values:
|
||||
|
||||
| Value | Description |
|
||||
| -------------- | ------------------------------------- |
|
||||
| `all` | Visible on all screen sizes (default) |
|
||||
| `mobile-only` | Only visible on mobile devices |
|
||||
| `desktop-only` | Only visible on desktop devices |
|
||||
|
||||
### TS Override
|
||||
|
||||
For the TS override approach, use `Component.MobileOnly()` or `Component.DesktopOnly()` wrappers:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
Component.MobileOnly(Component.Spacer())
|
||||
```
|
||||
|
||||
## `DesktopOnly` Component
|
||||
|
||||
The `DesktopOnly` component is the counterpart to `MobileOnly`. It makes its child component only visible on desktop devices. This helps create responsive layouts where certain components should only appear on larger screens.
|
||||
|
||||
### Example Usage
|
||||
|
||||
```typescript
|
||||
Component.DesktopOnly(Component.TableOfContents())
|
||||
```ts title="quartz.ts (override)"
|
||||
Component.DesktopOnly(Plugin.TableOfContents())
|
||||
```
|
||||
|
||||
## `ConditionalRender` Component
|
||||
|
||||
The `ConditionalRender` component is a wrapper that conditionally renders its child component based on a provided condition function. This is useful for creating dynamic layouts where components should only appear under certain conditions.
|
||||
The `ConditionalRender` component conditionally renders a plugin based on page properties. This is useful for creating dynamic layouts where components should only appear under certain conditions.
|
||||
|
||||
### YAML Configuration
|
||||
|
||||
In YAML, use the `condition` property on a plugin's layout entry. Quartz provides several built-in condition presets:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/breadcrumbs
|
||||
enabled: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 5
|
||||
condition: not-index # Hide breadcrumbs on the root index page
|
||||
```
|
||||
|
||||
Available built-in conditions:
|
||||
|
||||
| Condition | Description |
|
||||
| --------------- | ----------------------------------------------------- |
|
||||
| `not-index` | Only render when the page is not the root `index.md` |
|
||||
| `has-tags` | Only render when the page has tags in its frontmatter |
|
||||
| `has-backlinks` | Only render when the page has backlinks |
|
||||
| `has-toc` | Only render when the page has a table of contents |
|
||||
|
||||
### TS Override
|
||||
|
||||
For custom conditions that aren't covered by the built-in presets, use `Component.ConditionalRender()` in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
Component.ConditionalRender({
|
||||
component: Plugin.Search(),
|
||||
condition: (props) => props.displayClass !== "fullpage",
|
||||
})
|
||||
```
|
||||
|
||||
```typescript
|
||||
type ConditionalRenderConfig = {
|
||||
@ -81,22 +190,5 @@ type ConditionalRenderConfig = {
|
||||
}
|
||||
```
|
||||
|
||||
### Example Usage
|
||||
|
||||
```typescript
|
||||
Component.ConditionalRender({
|
||||
component: Component.Search(),
|
||||
condition: (props) => props.displayClass !== "fullpage",
|
||||
})
|
||||
```
|
||||
|
||||
The example above would only render the Search component when the page is not in fullpage mode.
|
||||
|
||||
```typescript
|
||||
Component.ConditionalRender({
|
||||
component: Component.Breadcrumbs(),
|
||||
condition: (page) => page.fileData.slug !== "index",
|
||||
})
|
||||
```
|
||||
|
||||
The example above would hide breadcrumbs on the root `index.md` page.
|
||||
> [!tip]
|
||||
> You can also register custom conditions for use in YAML by calling `registerCondition()` in a plugin's initialization code. See [[making plugins]] for more details.
|
||||
|
||||
163
docs/layout.md
163
docs/layout.md
@ -2,7 +2,12 @@
|
||||
title: Layout
|
||||
---
|
||||
|
||||
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. The default page layouts can be found in `quartz.layout.ts`.
|
||||
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.
|
||||
|
||||
In v5, the layout is defined in `quartz.config.yaml`. Each plugin controls its own layout position via `layout.position` and `layout.priority` fields. The top-level `layout` section provides two additional mechanisms:
|
||||
|
||||
- `layout.groups` defines flex containers (like `toolbar`) that group multiple components into a single row or column. See [[layout-components]] for details.
|
||||
- `layout.byPageType` contains per-page-type overrides (content, folder, tag, 404) for beforeBody, left, right sections, and optionally a `template` to control the page's [[#Page Frames|page frame]].
|
||||
|
||||
Each page is composed of multiple different sections which contain `QuartzComponents`. The following code snippet lists all of the valid sections that you can add components to:
|
||||
|
||||
@ -31,14 +36,160 @@ These correspond to following parts of the page:
|
||||
> There are two additional layout fields that are _not_ shown in the above diagram.
|
||||
>
|
||||
> 1. `head` is a single component that renders the `<head>` [tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head) in the HTML. This doesn't appear visually on the page and is only is responsible for metadata about the document like the tab title, scripts, and styles.
|
||||
> 2. `header` is a set of components that are laid out horizontally and appears _before_ the `beforeBody` section. This enables you to replicate the old Quartz 3 header bar where the title, search bar, and dark mode toggle. By default, Quartz 4 doesn't place any components in the `header`.
|
||||
> 2. `header` is a set of components that are laid out horizontally and appears _before_ the `beforeBody` section. This enables you to replicate the old Quartz 3 header bar where the title, search bar, and dark mode toggle. By default, Quartz doesn't place any components in the `header`.
|
||||
|
||||
Quartz **components**, like plugins, can take in additional properties as configuration options. If you're familiar with React terminology, you can think of them as Higher-order Components.
|
||||
Layout components are configured in the `layout` section of `quartz.config.yaml`. Plugins declare their position and priority, and the layout system arranges them automatically:
|
||||
|
||||
See [a list of all the components](component.md) for all available components along with their configuration options. Additionally, Quartz provides several built-in higher-order components for layout composition - see [[layout-components]] for more details.
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/explorer
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 50
|
||||
- source: github:quartz-community/graph
|
||||
enabled: true
|
||||
layout:
|
||||
position: right
|
||||
priority: 10
|
||||
- source: github:quartz-community/search
|
||||
enabled: true
|
||||
layout:
|
||||
position: left
|
||||
priority: 20
|
||||
- source: github:quartz-community/backlinks
|
||||
enabled: true
|
||||
layout:
|
||||
position: right
|
||||
priority: 30
|
||||
- source: github:quartz-community/article-title
|
||||
enabled: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 10
|
||||
- source: github:quartz-community/content-meta
|
||||
enabled: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 20
|
||||
- source: github:quartz-community/tag-list
|
||||
enabled: true
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 30
|
||||
- source: github:quartz-community/footer
|
||||
enabled: true
|
||||
options:
|
||||
links:
|
||||
GitHub: https://github.com/jackyzha0/quartz
|
||||
Discord Community: https://discord.gg/cRFFHYye7t
|
||||
|
||||
layout:
|
||||
groups:
|
||||
toolbar:
|
||||
direction: row
|
||||
gap: 0.5rem
|
||||
byPageType:
|
||||
content: {}
|
||||
folder:
|
||||
exclude:
|
||||
- reader-mode
|
||||
positions:
|
||||
right: []
|
||||
tag:
|
||||
exclude:
|
||||
- reader-mode
|
||||
positions:
|
||||
right: []
|
||||
"404":
|
||||
positions:
|
||||
beforeBody: []
|
||||
left: []
|
||||
right: []
|
||||
```
|
||||
|
||||
For advanced layout overrides using TypeScript (e.g. custom component wrappers or conditional logic), you can use the TS override in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.ts"
|
||||
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||
|
||||
const config = await loadQuartzConfig()
|
||||
export default config
|
||||
export const layout = await loadQuartzLayout({
|
||||
defaults: {
|
||||
// override default layout for all page types
|
||||
},
|
||||
byPageType: {
|
||||
content: {
|
||||
// override layout for content pages only
|
||||
},
|
||||
folder: {
|
||||
// override layout for folder pages only
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Fields defined in `defaults` can be overridden by specific entries in `byPageType`.
|
||||
|
||||
Community component plugins are installed via `npx quartz plugin add github:quartz-community/<name>`. See [[layout-components]] for built-in layout utilities (Flex, MobileOnly, DesktopOnly, etc.).
|
||||
|
||||
You can also checkout the guide on [[creating components]] if you're interested in further customizing the behaviour of Quartz.
|
||||
|
||||
### Page Frames
|
||||
|
||||
Page frames control the overall HTML structure of a page — specifically, how the layout slots (sidebars, header, content, footer) are arranged inside the page shell. Different page types can use different frames to produce fundamentally different layouts.
|
||||
|
||||
Quartz ships with three built-in frames:
|
||||
|
||||
| Frame | Description | Used by |
|
||||
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
|
||||
| `default` | Three-column layout with left sidebar, center content (header, beforeBody, content, afterBody), right sidebar, and footer. This is the standard Quartz layout. | ContentPage, FolderPage, TagPage, BasesPage |
|
||||
| `full-width` | No sidebars. Single center column spanning the full width with header, content, afterBody, and footer. | — |
|
||||
| `minimal` | No sidebars, no header or beforeBody chrome. Only content and footer. | NotFoundPage (404) |
|
||||
|
||||
Plugins can also provide their own frames. For example, the `canvas-page` plugin ships a `"canvas"` frame that provides a fullscreen canvas with a togglable sidebar.
|
||||
|
||||
#### How frames are resolved
|
||||
|
||||
Each page type can declare a default frame in its plugin source code via the `frame` property. The resolution order is:
|
||||
|
||||
1. **YAML config override**: `layout.byPageType.<name>.template` in `quartz.config.yaml`
|
||||
2. **Plugin-registered frame**: Frames registered by plugins via the Frame Registry (loaded from the plugin's `frames` export)
|
||||
3. **Plugin declaration**: The `frame` property set in the page type plugin's source code
|
||||
4. **Fallback**: `"default"`
|
||||
|
||||
For example, to override canvas pages to use the minimal frame:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
layout:
|
||||
byPageType:
|
||||
canvas:
|
||||
template: minimal
|
||||
```
|
||||
|
||||
#### Custom frames
|
||||
|
||||
There are two ways to provide custom frames:
|
||||
|
||||
**1. Plugin-provided frames (recommended for reusable frames):**
|
||||
|
||||
Plugins can ship their own frames by declaring them in `package.json` and exporting them from a `./frames` subpath. See [[making plugins#Providing Custom Frames|the plugin guide]] for details. When a plugin with frames is installed, its frames are automatically registered in the Frame Registry and available by name.
|
||||
|
||||
**2. Core frames (for project-specific frames):**
|
||||
|
||||
You can also create frames directly in `quartz/components/frames/` by implementing the `PageFrame` interface and registering the frame in `quartz/components/frames/index.ts`. See the [[advanced/architecture|architecture overview]] for the full `PageFrame` interface.
|
||||
|
||||
Frames are applied as a `data-frame` attribute on the `.page` element, which you can target in CSS:
|
||||
|
||||
```scss
|
||||
.page[data-frame="my-frame"] > #quartz-body {
|
||||
/* custom grid layout */
|
||||
}
|
||||
```
|
||||
|
||||
Frame CSS should be scoped with `[data-frame="name"]` selectors to avoid conflicts with other frames.
|
||||
|
||||
### Layout breakpoints
|
||||
|
||||
Quartz has different layouts depending on the width the screen viewing the website.
|
||||
@ -58,9 +209,9 @@ $breakpoints: (
|
||||
|
||||
### Style
|
||||
|
||||
Most meaningful style changes like colour scheme and font can be done simply through the [[configuration#General Configuration|general configuration]] options. However, if you'd like to make more involved style changes, you can do this by writing your own styles. Quartz 4, like Quartz 3, uses [Sass](https://sass-lang.com/guide/) for styling.
|
||||
Most meaningful style changes like colour scheme and font can be done simply through the [[configuration#General Configuration|general configuration]] options. However, if you'd like to make more involved style changes, you can do this by writing your own styles. Quartz uses [Sass](https://sass-lang.com/guide/) for styling.
|
||||
|
||||
You can see the base style sheet in `quartz/styles/base.scss` and write your own in `quartz/styles/custom.scss`.
|
||||
|
||||
> [!note]
|
||||
> Some components may provide their own styling as well! For example, `quartz/components/Darkmode.tsx` imports styles from `quartz/components/styles/darkmode.scss`. If you'd like to customize styling for a specific component, double check the component definition to see how its styles are defined.
|
||||
> Some components may provide their own styling as well! Community plugins bundle their own styles. If you'd like to customize styling for a specific component, double check the component definition to see how its styles are defined.
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
---
|
||||
title: "Migrating from Quartz 3"
|
||||
---
|
||||
|
||||
As you already have Quartz locally, you don't need to fork or clone it again. Simply just checkout the alpha branch, install the dependencies, and import your old vault.
|
||||
|
||||
```bash
|
||||
git fetch
|
||||
git checkout v4
|
||||
git pull upstream v4
|
||||
npm i
|
||||
npx quartz create
|
||||
```
|
||||
|
||||
If you get an error like `fatal: 'upstream' does not appear to be a git repository`, make sure you add `upstream` as a remote origin:
|
||||
|
||||
```shell
|
||||
git remote add upstream https://github.com/jackyzha0/quartz.git
|
||||
```
|
||||
|
||||
When running `npx quartz create`, you will be prompted as to how to initialize your content folder. Here, you can choose to import or link your previous content folder and Quartz should work just as you expect it to.
|
||||
|
||||
> [!note]
|
||||
> If the existing content folder you'd like to use is at the _same_ path on a different branch, clone the repo again somewhere at a _different_ path in order to use it.
|
||||
|
||||
## Key changes
|
||||
|
||||
1. **Removing Hugo and `hugo-obsidian`**: Hugo worked well for earlier versions of Quartz but it also made it hard for people outside of the Golang and Hugo communities to fully understand what Quartz was doing under the hood and be able to properly customize it to their needs. Quartz 4 now uses a Node-based static-site generation process which should lead to a much more helpful error messages and an overall smoother user experience.
|
||||
2. **Full-hot reload**: The many rough edges of how `hugo-obsidian` integrated with Hugo meant that watch mode didn't re-trigger `hugo-obsidian` to update the content index. This lead to a lot of weird cases where the watch mode output wasn't accurate. Quartz 4 now uses a cohesive parse, filter, and emit pipeline which gets run on every change so hot-reloads are always accurate.
|
||||
3. **Replacing Go template syntax with JSX**: Quartz 3 used [Go templates](https://pkg.go.dev/text/template) to create layouts for pages. However, the syntax isn't great for doing any sort of complex rendering (like [text processing](https://github.com/jackyzha0/quartz/blob/hugo/layouts/partials/textprocessing.html)) and it got very difficult to make any meaningful layout changes to Quartz 3. Quartz 4 uses an extension of JavaScript syntax called JSX which allows you to write layout code that looks like HTML in JavaScript which is significantly easier to understand and maintain.
|
||||
4. **A new extensible [[configuration]] and [[configuration#Plugins|plugin]] system**: Quartz 3 was hard to configure without technical knowledge of how Hugo's partials worked. Extensions were even hard to make. Quartz 4's configuration and plugin system is designed to be extended by users while making updating to new versions of Quartz easy.
|
||||
|
||||
## Things to update
|
||||
|
||||
- You will need to update your deploy scripts. See the [[hosting]] guide for more details.
|
||||
- Ensure that your default branch on GitHub is updated from `hugo` to `v4`.
|
||||
- [[folder and tag listings|Folder and tag listings]] have also changed.
|
||||
- Folder descriptions should go under `content/<folder-name>/index.md` where `<folder-name>` is the name of the folder.
|
||||
- Tag descriptions should go under `content/tags/<tag-name>.md` where `<tag-name>` is the name of the tag.
|
||||
- Some HTML layout may not be the same between Quartz 3 and Quartz 4. If you depended on a particular HTML hierarchy or class names, you may need to update your custom CSS to reflect these changes.
|
||||
- If you customized the layout of Quartz 3, you may need to translate these changes from Go templates back to JSX as Quartz 4 no longer uses Hugo. For components, check out the guide on [[creating components]] for more details on this.
|
||||
@ -36,7 +36,7 @@ Quartz is designed first and foremost as a tool for publishing [digital gardens]
|
||||
At its core, Quartz is designed to be easy to use enough for non-technical people to get going but also powerful enough that senior developers can tweak it to work how they'd like it to work.
|
||||
|
||||
1. If you like the default configuration of Quartz and just want to change the content, the only thing that you need to change is the contents of the `content` folder.
|
||||
2. If you'd like to make basic configuration tweaks but don't want to edit source code, one can tweak the plugins and components in `quartz.config.ts` and `quartz.layout.ts` in a guided manner to their liking.
|
||||
2. If you'd like to make basic configuration tweaks but don't want to edit source code, one can tweak the plugins and components in `quartz.config.yaml` in a guided manner to their liking.
|
||||
3. If you'd like to tweak the actual source code of the underlying plugins, components, or even build process, Quartz purposefully ships its full source code to the end user to allow customization at this level too.
|
||||
|
||||
Most software either confines you to either
|
||||
|
||||
@ -33,5 +33,6 @@ This plugin has no configuration options.
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.AliasRedirects()`.
|
||||
- Source: [`quartz/plugins/emitters/aliases.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/aliases.ts).
|
||||
- Function name: `ExternalPlugin.AliasRedirects()`.
|
||||
- Source: [`quartz-community/alias-redirects`](https://github.com/quartz-community/alias-redirects)
|
||||
- Install: `npx quartz plugin add github:quartz-community/alias-redirects`
|
||||
|
||||
19
docs/plugins/ArticleTitle.md
Normal file
19
docs/plugins/ArticleTitle.md
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
title: ArticleTitle
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
This plugin renders the article title from the page's frontmatter as an `<h1>` heading at the top of the page content. It reads the `title` field from frontmatter (falling back to the filename if no title is set).
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
This plugin has no configuration options.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.ArticleTitle()`.
|
||||
- Source: [`quartz-community/article-title`](https://github.com/quartz-community/article-title)
|
||||
- Install: `npx quartz plugin add github:quartz-community/article-title`
|
||||
@ -16,5 +16,5 @@ This plugin has no configuration options.
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.Assets()`.
|
||||
- Source: [`quartz/plugins/emitters/assets.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/assets.ts).
|
||||
- Function name: `Plugin.Assets()` (internal plugin).
|
||||
- Source: [`quartz/plugins/emitters/assets.ts`](https://github.com/jackyzha0/quartz/blob/v5/quartz/plugins/emitters/assets.ts).
|
||||
|
||||
34
docs/plugins/Backlinks.md
Normal file
34
docs/plugins/Backlinks.md
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
title: Backlinks
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
Shows pages that link to the current page.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[backlinks]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `hideWhenEmpty`: Hide the backlinks section if the current page has no backlinks. Defaults to `true`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/backlinks
|
||||
enabled: true
|
||||
options:
|
||||
hideWhenEmpty: true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.Backlinks()`.
|
||||
- Source: [`quartz-community/backlinks`](https://github.com/quartz-community/backlinks)
|
||||
- Install: `npx quartz plugin add github:quartz-community/backlinks`
|
||||
60
docs/plugins/BasesPage.md
Normal file
60
docs/plugins/BasesPage.md
Normal file
@ -0,0 +1,60 @@
|
||||
---
|
||||
title: BasesPage
|
||||
tags:
|
||||
- plugin/pageType
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
This plugin provides support for [Obsidian Bases](https://obsidian.md/changelog/2025-04-15-desktop-v1.8.0/) (`.base` files) in Quartz. It reads `.base` files from your vault, resolves matching notes based on the query definition, and renders them as interactive database-like views with support for tables, lists, cards, and maps. It uses the `default` [[layout#Page Frames|page frame]] (three-column layout with sidebars).
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Features
|
||||
|
||||
- **Table view**: Sortable columns with automatic type rendering (strings, numbers, booleans, arrays, links).
|
||||
- **List view**: Compact list with metadata chips for each entry.
|
||||
- **Cards view**: Card layout with optional image property support.
|
||||
- **Map view**: Placeholder for future map-based visualization.
|
||||
- **Multiple views**: A single `.base` file can define multiple views, displayed as switchable tabs.
|
||||
- **Filters**: Recursive filter trees with `and`/`or`/`not` operators.
|
||||
- **Formulas**: Computed properties via formula expressions.
|
||||
- **Summaries**: Column-level aggregations (Sum, Average, Min, Max, Median, etc.).
|
||||
- **Property configuration**: Custom display names for properties.
|
||||
- **Link rendering**: Wikilinks and Markdown links within cell values are rendered as clickable links.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `defaultViewType`: The default view type when none is specified in the `.base` file. Defaults to `"table"`.
|
||||
- `customViews`: A map of custom view renderers. Keys are view type names. These override built-in renderers for the same type, or add new view types. Requires a TS override.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/bases-page
|
||||
enabled: true
|
||||
```
|
||||
|
||||
For custom view renderers, use a TS override in `quartz.ts`:
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
import * as ExternalPlugin from "./.quartz/plugins"
|
||||
|
||||
ExternalPlugin.BasesPage({
|
||||
defaultViewType: "table",
|
||||
customViews: {
|
||||
myView: ({ entries, view, basesData, total, locale }) => {
|
||||
// return JSX
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Page Type, Component
|
||||
- Function name: `ExternalPlugin.BasesPage()`.
|
||||
- Source: [`quartz-community/bases-page`](https://github.com/quartz-community/bases-page)
|
||||
- Install: `npx quartz plugin add github:quartz-community/bases-page`
|
||||
40
docs/plugins/Breadcrumbs.md
Normal file
40
docs/plugins/Breadcrumbs.md
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
title: Breadcrumbs
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
Navigation breadcrumb trail.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[breadcrumbs]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `spacerSymbol`: The symbol to use between breadcrumb items. Defaults to `"❯"`.
|
||||
- `rootName`: The name of the root page. Defaults to `Home`.
|
||||
- `resolveFrontmatterTitle`: Whether to use the `title` frontmatter field for breadcrumb items. Defaults to `true`.
|
||||
- `showCurrentPage`: Whether to show the current page in the breadcrumb trail. Defaults to `true`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/breadcrumbs
|
||||
enabled: true
|
||||
options:
|
||||
spacerSymbol: "❯"
|
||||
rootName: Home
|
||||
resolveFrontmatterTitle: true
|
||||
showCurrentPage: true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.Breadcrumbs()`.
|
||||
- Source: [`quartz-community/breadcrumbs`](https://github.com/quartz-community/breadcrumbs)
|
||||
- Install: `npx quartz plugin add github:quartz-community/breadcrumbs`
|
||||
@ -18,5 +18,6 @@ This plugin has no configuration options.
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.CNAME()`.
|
||||
- Source: [`quartz/plugins/emitters/cname.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/cname.ts).
|
||||
- Function name: `ExternalPlugin.CNAME()`.
|
||||
- Source: [`quartz-community/cname`](https://github.com/quartz-community/cname)
|
||||
- Install: `npx quartz plugin add github:quartz-community/cname`
|
||||
|
||||
53
docs/plugins/CanvasPage.md
Normal file
53
docs/plugins/CanvasPage.md
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
title: CanvasPage
|
||||
tags:
|
||||
- plugin/pageType
|
||||
---
|
||||
|
||||
This plugin is a page type plugin that renders [JSON Canvas](https://jsoncanvas.org) (`.canvas`) files as interactive, pannable and zoomable canvas pages. It uses a custom `"canvas"` [[layout#Page Frames|page frame]] that provides a fullscreen, always-on canvas experience with a togglable left sidebar for navigation. It supports the full [JSON Canvas 1.0 spec](https://jsoncanvas.org/spec/1.0/), including text nodes with Markdown rendering, file nodes that link to other pages in your vault, link nodes for external URLs, and group nodes for visual organization. Edges between nodes are rendered as SVG paths with optional labels, arrow markers, and colors.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `enableInteraction`: Whether to enable pan and zoom interaction on the canvas. Default: `true{:ts}`.
|
||||
- `initialZoom`: The initial zoom level when the canvas is first displayed. Default: `1{:ts}`.
|
||||
- `minZoom`: The minimum zoom level allowed when zooming out. Default: `0.1{:ts}`.
|
||||
- `maxZoom`: The maximum zoom level allowed when zooming in. Default: `5{:ts}`.
|
||||
|
||||
### Canvas Frame
|
||||
|
||||
The canvas-page plugin provides its own `"canvas"` page frame via the [[layout#Page Frames|Frame Registry]]. This frame:
|
||||
|
||||
- Renders the canvas in **fullscreen mode** by default (100vw × 100vh), giving the canvas maximum screen space — leaning into the "endless canvas" concept of JSON Canvas.
|
||||
- Provides a **togglable left sidebar** that slides in from the left edge. This is the only layout slot available — it renders the same components as the `left` sidebar on content pages (e.g., Explorer, Search, Page Title).
|
||||
- The sidebar toggle button (hamburger/close icon) is positioned in the top-left corner.
|
||||
- Canvas controls (zoom in, zoom out, reset) are positioned on the right side.
|
||||
- On mobile, the sidebar overlays the canvas rather than pushing it aside.
|
||||
|
||||
Users can override this frame via `quartz.config.yaml` if needed:
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
layout:
|
||||
byPageType:
|
||||
canvas:
|
||||
template: default # Use standard three-column layout instead
|
||||
```
|
||||
|
||||
### Features
|
||||
|
||||
- **Text nodes**: Render Markdown content including headings, bold, italic, strikethrough, lists, links, and code blocks via [GFM](https://github.github.com/gfm/) support.
|
||||
- **File nodes**: Link to other pages in your vault. Supports popover previews on hover.
|
||||
- **Link nodes**: Reference external URLs.
|
||||
- **Group nodes**: Visual grouping containers with optional labels and background colors.
|
||||
- **Edges**: SVG connections between nodes with optional labels, arrow markers, and colors. Supports all four sides (top, right, bottom, left) and both preset colors (1–6) and custom hex colors.
|
||||
- **Togglable sidebar**: Hamburger button in the top-left corner toggles the left sidebar for navigation. Press `Escape` or click the close button to dismiss.
|
||||
- **Preset colors**: Six preset colors (red, orange, yellow, green, cyan, purple) plus custom hex colors (`#RRGGBB`) for nodes and edges.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Page Type
|
||||
- Function name: `ExternalPlugin.CanvasPage()`.
|
||||
- Source: [`quartz-community/canvas-page`](https://github.com/quartz-community/canvas-page)
|
||||
- Install: `npx quartz plugin add github:quartz-community/canvas-page`
|
||||
@ -20,5 +20,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.Citations()`.
|
||||
- Source: [`quartz/plugins/transformers/citations.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/citations.ts).
|
||||
- Function name: `ExternalPlugin.Citations()`.
|
||||
- Source: [`quartz-community/citations`](https://github.com/quartz-community/citations)
|
||||
- Install: `npx quartz plugin add github:quartz-community/citations`
|
||||
|
||||
53
docs/plugins/Comments.md
Normal file
53
docs/plugins/Comments.md
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
title: Comments
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
Comment system (giscus, utterances, etc.).
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[comments]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `provider`: The comment provider to use. Currently only `giscus` is supported.
|
||||
- `options`: Provider-specific options.
|
||||
- `repo`: The GitHub repository to use for comments.
|
||||
- `repoId`: The ID of the GitHub repository.
|
||||
- `category`: The discussion category to use.
|
||||
- `categoryId`: The ID of the discussion category.
|
||||
- `lang`: The language for the comment system. Defaults to `en`.
|
||||
- `themeUrl`: URL to a folder with custom themes.
|
||||
- `lightTheme`: Filename for the light theme CSS file. Defaults to `light`.
|
||||
- `darkTheme`: Filename for the dark theme CSS file. Defaults to `dark`.
|
||||
- `mapping`: How to map pages to discussions. Defaults to `url`.
|
||||
- `strict`: Use strict title matching. Defaults to `true`.
|
||||
- `reactionsEnabled`: Whether to enable reactions for the main post. Defaults to `true`.
|
||||
- `inputPosition`: Where to put the comment input box relative to the comments. Defaults to `bottom`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/comments
|
||||
enabled: true
|
||||
options:
|
||||
provider: giscus
|
||||
options:
|
||||
repo: jackyzha0/quartz
|
||||
repoId: MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg
|
||||
category: Announcements
|
||||
categoryId: DIC_kwDOFxRnmM4B-Xg6
|
||||
lang: en
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.Comments()`.
|
||||
- Source: [`quartz-community/comments`](https://github.com/quartz-community/comments)
|
||||
- Install: `npx quartz plugin add github:quartz-community/comments`
|
||||
@ -14,5 +14,5 @@ This plugin has no configuration options.
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.ComponentResources()`.
|
||||
- Source: [`quartz/plugins/emitters/componentResources.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/componentResources.ts).
|
||||
- Function name: `Plugin.ComponentResources()` (internal plugin).
|
||||
- Source: [`quartz/plugins/emitters/componentResources.ts`](https://github.com/jackyzha0/quartz/blob/v5/quartz/plugins/emitters/componentResources.ts).
|
||||
|
||||
@ -23,5 +23,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.ContentIndex()`.
|
||||
- Source: [`quartz/plugins/emitters/contentIndex.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/contentIndex.ts).
|
||||
- Function name: `ExternalPlugin.ContentIndex()`.
|
||||
- Source: [`quartz-community/content-index`](https://github.com/quartz-community/content-index)
|
||||
- Install: `npx quartz plugin add github:quartz-community/content-index`
|
||||
|
||||
34
docs/plugins/ContentMeta.md
Normal file
34
docs/plugins/ContentMeta.md
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
title: ContentMeta
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
This plugin displays content metadata below the article title, such as the creation date and estimated reading time.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `showReadingTime`: Whether to display the estimated reading time. Defaults to `true`.
|
||||
- `showComma`: Whether to display a comma between metadata items. Defaults to `true`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/content-meta
|
||||
enabled: true
|
||||
options:
|
||||
showReadingTime: true
|
||||
showComma: true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.ContentMeta()`.
|
||||
- Source: [`quartz-community/content-meta`](https://github.com/quartz-community/content-meta)
|
||||
- Install: `npx quartz plugin add github:quartz-community/content-meta`
|
||||
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: ContentPage
|
||||
tags:
|
||||
- plugin/emitter
|
||||
- plugin/pageType
|
||||
---
|
||||
|
||||
This plugin is a core component of the Quartz framework. It generates the HTML pages for each piece of Markdown content. It emits the full-page [[layout]], including headers, footers, and body content, among others.
|
||||
This plugin is a page type plugin for the Quartz framework. It generates the HTML pages for each piece of Markdown content. It emits the full-page [[layout]], including headers, footers, and body content, among others. It uses the `default` [[layout#Page Frames|page frame]] (three-column layout with sidebars). It is now configured in the `pageTypes` section of `quartz.config.yaml`.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
@ -13,6 +13,7 @@ This plugin has no configuration options.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.ContentPage()`.
|
||||
- Source: [`quartz/plugins/emitters/contentPage.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/contentPage.tsx).
|
||||
- Category: Page Type
|
||||
- Function name: `ExternalPlugin.ContentPage()`.
|
||||
- Source: [`quartz-community/content-page`](https://github.com/quartz-community/content-page)
|
||||
- Install: `npx quartz plugin add github:quartz-community/content-page`
|
||||
|
||||
@ -26,5 +26,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.CrawlLinks()`.
|
||||
- Source: [`quartz/plugins/transformers/links.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/links.ts).
|
||||
- Function name: `ExternalPlugin.CrawlLinks()`.
|
||||
- Source: [`quartz-community/crawl-links`](https://github.com/quartz-community/crawl-links)
|
||||
- Install: `npx quartz plugin add github:quartz-community/crawl-links`
|
||||
|
||||
@ -16,12 +16,13 @@ This plugin accepts the following configuration options:
|
||||
When loading the frontmatter, the value of [[Frontmatter#List]] is used.
|
||||
|
||||
> [!warning]
|
||||
> If you rely on `git` for dates, make sure `defaultDateType` is set to `modified` in `quartz.config.ts`.
|
||||
> If you rely on `git` for dates, make sure `defaultDateType` is set to `modified` in `quartz.config.yaml`.
|
||||
>
|
||||
> Depending on how you [[hosting|host]] your Quartz, the `filesystem` dates of your local files may not match the final dates. In these cases, it may be better to use `git` or `frontmatter` to guarantee correct dates.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.CreatedModifiedDate()`.
|
||||
- Source: [`quartz/plugins/transformers/lastmod.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/lastmod.ts).
|
||||
- Function name: `ExternalPlugin.CreatedModifiedDate()`.
|
||||
- Source: [`quartz-community/created-modified-date`](https://github.com/quartz-community/created-modified-date)
|
||||
- Install: `npx quartz plugin add github:quartz-community/created-modified-date`
|
||||
|
||||
@ -25,22 +25,29 @@ The Custom OG Images emitter plugin generates social media preview images for yo
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
```typescript title="quartz.config.ts"
|
||||
import { CustomOgImages } from "./quartz/plugins/emitters/ogImage"
|
||||
```yaml title="quartz.config.yaml"
|
||||
plugins:
|
||||
- source: github:quartz-community/og-image
|
||||
enabled: true
|
||||
options:
|
||||
colorScheme: lightMode # "lightMode" or "darkMode"
|
||||
width: 1200
|
||||
height: 630
|
||||
excludeRoot: false
|
||||
```
|
||||
|
||||
const config: QuartzConfig = {
|
||||
plugins: {
|
||||
emitters: [
|
||||
CustomOgImages({
|
||||
colorScheme: "lightMode", // what colors to use for generating image, same as theme colors from config, valid values are "darkMode" and "lightMode"
|
||||
width: 1200, // width to generate with (in pixels)
|
||||
height: 630, // height to generate with (in pixels)
|
||||
excludeRoot: false, // wether to exclude "/" index path to be excluded from auto generated images (false = use auto, true = use default og image)
|
||||
imageStructure: defaultImage, // custom image component to use
|
||||
}),
|
||||
],
|
||||
},
|
||||
}
|
||||
For the TS override approach (needed for custom `imageStructure`):
|
||||
|
||||
```ts title="quartz.ts (override)"
|
||||
import { defaultImage } from "./quartz/plugins/emitters/ogImage"
|
||||
|
||||
CustomOgImages({
|
||||
colorScheme: "lightMode",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
excludeRoot: false,
|
||||
imageStructure: defaultImage, // custom JSX component — requires TS
|
||||
})
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
@ -76,7 +83,7 @@ You can fully customize how the images being generated look by passing your own
|
||||
|
||||
### Fonts
|
||||
|
||||
You will also be passed an array containing a header and a body font (where the first entry is header and the second is body). The fonts matches the ones selected in `theme.typography.header` and `theme.typography.body` from `quartz.config.ts` and will be passed in the format required by [`satori`](https://github.com/vercel/satori). To use them in CSS, use the `.name` property (e.g. `fontFamily: fonts[1].name` to use the "body" font family).
|
||||
You will also be passed an array containing a header and a body font (where the first entry is header and the second is body). The fonts matches the ones selected in `theme.typography.header` and `theme.typography.body` from `quartz.config.yaml` and will be passed in the format required by [`satori`](https://github.com/vercel/satori). To use them in CSS, use the `.name` property (e.g. `fontFamily: fonts[1].name` to use the "body" font family).
|
||||
|
||||
An example of a component using the header font could look like this:
|
||||
|
||||
@ -358,3 +365,10 @@ export const og: SocialImageOptions["Component"] = (
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `ExternalPlugin.CustomOgImages()`.
|
||||
- Source: [`quartz-community/og-image`](https://github.com/quartz-community/og-image)
|
||||
- Install: `npx quartz plugin add github:quartz-community/og-image`
|
||||
|
||||
32
docs/plugins/Darkmode.md
Normal file
32
docs/plugins/Darkmode.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Darkmode
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
Dark mode toggle.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[darkmode]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `enabled`: Whether to enable the dark mode toggle. Defaults to `true`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/darkmode
|
||||
enabled: true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.Darkmode()`.
|
||||
- Source: [`quartz-community/darkmode`](https://github.com/quartz-community/darkmode)
|
||||
- Install: `npx quartz plugin add github:quartz-community/darkmode`
|
||||
@ -19,5 +19,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.Description()`.
|
||||
- Source: [`quartz/plugins/transformers/description.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/description.ts).
|
||||
- Function name: `ExternalPlugin.Description()`.
|
||||
- Source: [`quartz-community/description`](https://github.com/quartz-community/description)
|
||||
- Install: `npx quartz plugin add github:quartz-community/description`
|
||||
|
||||
25
docs/plugins/EncryptedPages Demo.md
Normal file
25
docs/plugins/EncryptedPages Demo.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Encrypted Pages Demo
|
||||
password: quartz
|
||||
tags:
|
||||
- plugin/transformer
|
||||
---
|
||||
|
||||
Congratulations! You've successfully decrypted this page. 🎉
|
||||
|
||||
This is a live demo of the [[EncryptedPages]] plugin. The content you're reading was encrypted at build time using AES-256-GCM and decrypted in your browser using the Web Crypto API.
|
||||
|
||||
## What just happened?
|
||||
|
||||
1. At build time, the plugin read the `password` field from this page's frontmatter and encrypted all content below the title.
|
||||
2. When you visited this page, you were shown a password prompt instead of the page content.
|
||||
3. After entering the correct password, the plugin derived an encryption key using PBKDF2 and decrypted the content client-side.
|
||||
4. A `render` event was dispatched so other components (graph, explorer, etc.) could re-initialize with the decrypted content.
|
||||
|
||||
## Password caching
|
||||
|
||||
Your password has been cached in session storage. If there were other encrypted pages on this site, the plugin would automatically try this password before showing the prompt — so you'd only need to enter it once per session for pages that share the same password.
|
||||
|
||||
## Try it yourself
|
||||
|
||||
To add encrypted pages to your own Quartz site, install the plugin and add a `password` field to any page's frontmatter. See [[EncryptedPages]] for full setup instructions.
|
||||
72
docs/plugins/EncryptedPages.md
Normal file
72
docs/plugins/EncryptedPages.md
Normal file
@ -0,0 +1,72 @@
|
||||
---
|
||||
title: EncryptedPages
|
||||
tags:
|
||||
- plugin/transformer
|
||||
- plugin/filter
|
||||
---
|
||||
|
||||
Password-protected encrypted pages. Encrypts page content at build time using AES-256-GCM and decrypts client-side with the Web Crypto API. Passwords are set per-page via frontmatter.
|
||||
|
||||
> [!example] Live demo
|
||||
> Try it yourself: [[EncryptedPages Demo]]. The password is `quartz`.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Usage
|
||||
|
||||
Add a `password` field to any page's frontmatter to encrypt it:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: My Secret Page
|
||||
password: mysecretpassword
|
||||
---
|
||||
```
|
||||
|
||||
The page content will be encrypted at build time. Visitors must enter the correct password to view the content.
|
||||
|
||||
Successful passwords are cached in the browser's session storage and automatically tried on other encrypted pages for convenience.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin provides a transformer, a filter, and a component.
|
||||
|
||||
### Transformer options
|
||||
|
||||
- `visibility`: How encrypted pages appear in graph, explorer, and backlinks. `"visible"` shows the page normally, `"icon"` adds a lock indicator, `"hidden"` hides the page completely. Defaults to `"icon"`.
|
||||
- `iterations`: PBKDF2 iteration count for key derivation. Higher values are more secure but slower to unlock. Defaults to `600000`.
|
||||
- `passwordField`: Frontmatter field name that holds the page password. Defaults to `"password"`.
|
||||
|
||||
### Filter options
|
||||
|
||||
- `visibility`: Controls whether encrypted pages appear in search, RSS, and sitemap. When set to `"hidden"`, encrypted pages are excluded from content indices entirely. Defaults to `"icon"`.
|
||||
|
||||
### Component options
|
||||
|
||||
- `className`: CSS class for the component wrapper. Defaults to `"encrypted-page-wrapper"`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/encrypted-pages
|
||||
enabled: true
|
||||
options:
|
||||
visibility: icon
|
||||
iterations: 600000
|
||||
passwordField: password
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
- Content is encrypted with AES-256-GCM using PBKDF2 SHA-256 key derivation.
|
||||
- Plaintext is stripped from search indices and RSS feeds regardless of visibility setting.
|
||||
- Passwords are set per-page in frontmatter. Avoid committing passwords to public repositories.
|
||||
- This is client-side encryption of a static site. It protects against casual browsing but not against determined attackers with access to the page source.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Transformer, Filter
|
||||
- Function name: `ExternalPlugin.EncryptedPages()`, `ExternalPlugin.EncryptedPageFilter()`.
|
||||
- Source: [`quartz-community/encrypted-pages`](https://github.com/quartz-community/encrypted-pages)
|
||||
- Install: `npx quartz plugin add github:quartz-community/encrypted-pages`
|
||||
@ -14,5 +14,6 @@ This plugin has no configuration options.
|
||||
## API
|
||||
|
||||
- Category: Filter
|
||||
- Function name: `Plugin.ExplicitPublish()`.
|
||||
- Source: [`quartz/plugins/filters/explicit.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/filters/explicit.ts).
|
||||
- Function name: `ExternalPlugin.ExplicitPublish()`.
|
||||
- Source: [`quartz-community/explicit-publish`](https://github.com/quartz-community/explicit-publish)
|
||||
- Install: `npx quartz plugin add github:quartz-community/explicit-publish`
|
||||
|
||||
40
docs/plugins/Explorer.md
Normal file
40
docs/plugins/Explorer.md
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
title: Explorer
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
File tree explorer sidebar.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[explorer]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `title`: The title of the explorer. Defaults to `Explorer`.
|
||||
- `folderClickBehavior`: The behavior when a folder is clicked. Can be `"link"` to navigate or `"collapse"` to toggle. Defaults to `collapse`.
|
||||
- `folderDefaultState`: The default state of folders. Can be `"collapsed"` or `"open"`. Defaults to `collapsed`.
|
||||
- `useSavedState`: Whether to use local storage to save the state of the explorer. Defaults to `true`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/explorer
|
||||
enabled: true
|
||||
options:
|
||||
title: Explorer
|
||||
folderClickBehavior: collapse
|
||||
folderDefaultState: collapsed
|
||||
useSavedState: true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.Explorer()`.
|
||||
- Source: [`quartz-community/explorer`](https://github.com/quartz-community/explorer)
|
||||
- Install: `npx quartz plugin add github:quartz-community/explorer`
|
||||
@ -15,5 +15,6 @@ This plugin has no configuration options.
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.Favicon()`.
|
||||
- Source: [`quartz/plugins/emitters/favicon.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/favicon.ts).
|
||||
- Function name: `ExternalPlugin.Favicon()`.
|
||||
- Source: [`quartz-community/favicon`](https://github.com/quartz-community/favicon)
|
||||
- Install: `npx quartz plugin add github:quartz-community/favicon`
|
||||
|
||||
@ -1,24 +1,23 @@
|
||||
---
|
||||
title: FolderPage
|
||||
tags:
|
||||
- plugin/emitter
|
||||
- plugin/pageType
|
||||
---
|
||||
|
||||
This plugin generates index pages for folders, creating a listing page for each folder that contains multiple content files. See [[folder and tag listings]] for more information.
|
||||
This plugin is a page type plugin that generates index pages for folders, creating a listing page for each folder that contains multiple content files. It uses the `default` [[layout#Page Frames|page frame]] (three-column layout with sidebars). See [[folder and tag listings]] for more information.
|
||||
|
||||
Example: [[advanced/|Advanced]]
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
The pages are displayed using the `defaultListPageLayout` in `quartz.layouts.ts`. For the content, the `FolderContent` component is used. If you want to modify the layout, you must edit it directly (`quartz/components/pages/FolderContent.tsx`).
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `sort`: A function of type `(f1: QuartzPluginData, f2: QuartzPluginData) => number{:ts}` used to sort entries. Defaults to sorting by date and tie-breaking on lexographical order.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.FolderPage()`.
|
||||
- Source: [`quartz/plugins/emitters/folderPage.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/folderPage.tsx).
|
||||
- Category: Page Type
|
||||
- Function name: `ExternalPlugin.FolderPage()`.
|
||||
- Source: [`quartz-community/folder-page`](https://github.com/quartz-community/folder-page)
|
||||
- Install: `npx quartz plugin add github:quartz-community/folder-page`
|
||||
|
||||
34
docs/plugins/Footer.md
Normal file
34
docs/plugins/Footer.md
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
title: Footer
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
This plugin renders a footer at the bottom of the page with a "Created with Quartz" message and a set of configurable links.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `links`: A map of link labels to their URLs to display in the footer. Defaults to `{}`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/footer
|
||||
enabled: true
|
||||
options:
|
||||
links:
|
||||
GitHub: https://github.com/jackyzha0/quartz
|
||||
Discord Community: https://discord.gg/cRFFHYye7t
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.Footer()`.
|
||||
- Source: [`quartz-community/footer`](https://github.com/quartz-community/footer)
|
||||
- Install: `npx quartz plugin add github:quartz-community/footer`
|
||||
@ -1,72 +1,107 @@
|
||||
---
|
||||
title: "Frontmatter"
|
||||
aliases:
|
||||
- note-properties
|
||||
- Note Properties
|
||||
description: "Parses frontmatter and displays note properties in a collapsible panel."
|
||||
tags:
|
||||
- plugin/transformer
|
||||
- plugin/component
|
||||
publish: true
|
||||
enableToc: true
|
||||
---
|
||||
|
||||
This plugin parses the frontmatter of the page using the [gray-matter](https://github.com/jonschlinkert/gray-matter) library. See [[authoring content#Syntax]], [[Obsidian compatibility]] and [[OxHugo compatibility]] for more information.
|
||||
This plugin parses the frontmatter of the page using the [gray-matter](https://github.com/jonschlinkert/gray-matter) library and optionally displays selected properties in a collapsible panel. See [[authoring content#Syntax]], [[Obsidian compatibility]] and [[OxHugo compatibility]] for more information.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
> [!warning]
|
||||
> This plugin must not be removed, otherwise Quartz will break.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `delimiters`: the delimiters to use for the frontmatter. Can have one value (e.g. `"---"`) or separate values for opening and closing delimiters (e.g. `["---", "~~~"]`). Defaults to `"---"`.
|
||||
- `language`: the language to use for parsing the frontmatter. Can be `yaml` (default) or `toml`.
|
||||
- `includeAll`: include all frontmatter properties in the properties panel. When `false`, only `includedProperties` are shown. Defaults to `false`.
|
||||
- `includedProperties`: properties to include when `includeAll` is `false`. Defaults to `["description", "tags", "aliases"]`.
|
||||
- `excludedProperties`: properties to always exclude from display, even when `includeAll` is `true`. Defaults to `[]`.
|
||||
- `hidePropertiesView`: hide the visual properties panel while still processing frontmatter. Useful if you only need frontmatter parsing without the UI. Defaults to `false`.
|
||||
|
||||
> [!warning]
|
||||
> This plugin must not be removed, otherwise Quartz will break.
|
||||
### Default options
|
||||
|
||||
## List
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/note-properties
|
||||
enabled: true
|
||||
options:
|
||||
includeAll: false
|
||||
includedProperties:
|
||||
- description
|
||||
- tags
|
||||
- aliases
|
||||
excludedProperties: []
|
||||
hidePropertiesView: false
|
||||
delimiters: "---"
|
||||
language: yaml
|
||||
```
|
||||
|
||||
Quartz supports the following frontmatter:
|
||||
## Properties panel
|
||||
|
||||
- title
|
||||
- `title`
|
||||
- description
|
||||
- `description`
|
||||
- permalink
|
||||
- `permalink`
|
||||
- comments
|
||||
- `comments`
|
||||
- lang
|
||||
- `lang`
|
||||
- publish
|
||||
- `publish`
|
||||
- draft
|
||||
- `draft`
|
||||
- enableToc
|
||||
- `enableToc`
|
||||
- tags
|
||||
- `tags`
|
||||
- `tag`
|
||||
- aliases
|
||||
- `aliases`
|
||||
- `alias`
|
||||
- cssclasses
|
||||
- `cssclasses`
|
||||
- `cssclass`
|
||||
- socialDescription
|
||||
- `socialDescription`
|
||||
- socialImage
|
||||
- `socialImage`
|
||||
- `image`
|
||||
- `cover`
|
||||
- created
|
||||
- `created`
|
||||
- `date`
|
||||
- modified
|
||||
- `modified`
|
||||
- `lastmod`
|
||||
- `updated`
|
||||
- `last-modified`
|
||||
- published
|
||||
- `published`
|
||||
- `publishDate`
|
||||
- `date`
|
||||
When enabled, this plugin renders a collapsible "Properties" panel before the page body. The panel displays selected frontmatter fields in a table with automatic type rendering:
|
||||
|
||||
- **Strings** are shown as plain text. [[Wikilinks]] and [markdown links](https://example.com) within strings are rendered as clickable links.
|
||||
- **Arrays** are rendered as comma-separated lists.
|
||||
- **Booleans** are rendered as disabled checkboxes.
|
||||
- **Numbers** are rendered in a monospace font.
|
||||
- **Objects** are rendered as JSON in a code block.
|
||||
- **Tags** get special treatment: they are rendered as highlighted links that point to the corresponding tag page.
|
||||
- **Null/undefined** values are shown as an em-dash (—).
|
||||
|
||||
### Per-note overrides
|
||||
|
||||
You can control the properties panel on a per-note basis using frontmatter keys:
|
||||
|
||||
- `quartz-properties` (or `quartzProperties`): set to `true` to force-show the panel, or `false` to force-hide it, overriding the global `hidePropertiesView` setting.
|
||||
- `quartz-properties-collapse` (or `quartzPropertiesCollapse`): set to `true` to start the panel collapsed, or `false` to start it expanded, overriding the default collapse state.
|
||||
|
||||
These keys are automatically excluded from the visible properties table.
|
||||
|
||||
```yaml title="Example frontmatter"
|
||||
---
|
||||
title: My Note
|
||||
quartz-properties: true
|
||||
quartz-properties-collapse: false
|
||||
---
|
||||
```
|
||||
|
||||
## Supported frontmatter
|
||||
|
||||
Quartz supports the following frontmatter fields. Where multiple keys are listed, they are aliases — the first matching key is used.
|
||||
|
||||
| Field | Keys | Description |
|
||||
| ------------------ | ------------------------------------------------- | ------------------------------------------------------------------ |
|
||||
| Title | `title` | Page title. Falls back to filename if empty. |
|
||||
| Description | `description` | Page description for metadata and search. |
|
||||
| Tags | `tags`, `tag` | Categorization tags. Automatically slugified. |
|
||||
| Aliases | `aliases`, `alias` | Alternative names for the page, used for link resolution. |
|
||||
| Permalink | `permalink` | Custom URL slug. Also added to aliases. |
|
||||
| CSS classes | `cssclasses`, `cssclass` | CSS classes applied to the page body. |
|
||||
| Social image | `socialImage`, `image`, `cover` | Image used for social media previews. |
|
||||
| Social description | `socialDescription` | Description used specifically for social media previews. |
|
||||
| Created date | `created`, `date` | When the note was created. |
|
||||
| Modified date | `modified`, `lastmod`, `updated`, `last-modified` | When the note was last modified. Falls back to `created` if unset. |
|
||||
| Published date | `published`, `publishDate`, `date` | When the note was published. |
|
||||
| Publish | `publish` | Whether the note should be published. |
|
||||
| Draft | `draft` | Whether the note is a draft. |
|
||||
| Comments | `comments` | Whether comments are enabled for the note. |
|
||||
| Language | `lang` | Language code for the note. |
|
||||
| Enable TOC | `enableToc` | Whether to show the table of contents. |
|
||||
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.Frontmatter()`.
|
||||
- Source: [`quartz/plugins/transformers/frontmatter.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/frontmatter.ts).
|
||||
- Category: Transformer, Component
|
||||
- Function name: `ExternalPlugin.NoteProperties()`.
|
||||
- Source: [`quartz-community/note-properties`](https://github.com/quartz-community/note-properties)
|
||||
- Install: `npx quartz plugin add github:quartz-community/note-properties`
|
||||
|
||||
@ -19,5 +19,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.GitHubFlavoredMarkdown()`.
|
||||
- Source: [`quartz/plugins/transformers/gfm.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/gfm.ts).
|
||||
- Function name: `ExternalPlugin.GitHubFlavoredMarkdown()`.
|
||||
- Source: [`quartz-community/github-flavored-markdown`](https://github.com/quartz-community/github-flavored-markdown)
|
||||
- Install: `npx quartz plugin add github:quartz-community/github-flavored-markdown`
|
||||
|
||||
77
docs/plugins/Graph.md
Normal file
77
docs/plugins/Graph.md
Normal file
@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Graph
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
Interactive graph visualization.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[graph view]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `localGraph`: Options for the local graph view.
|
||||
- `globalGraph`: Options for the global graph view.
|
||||
|
||||
Both `localGraph` and `globalGraph` accept the following options:
|
||||
|
||||
- `drag`: Enable dragging nodes. Defaults to `true`.
|
||||
- `zoom`: Enable zooming. Defaults to `true`.
|
||||
- `depth`: The depth of the graph. Defaults to `1` for local and `-1` for global.
|
||||
- `scale`: The initial scale of the graph.
|
||||
- `repelForce`: The force that pushes nodes apart.
|
||||
- `centerForce`: The force that pulls nodes to the center.
|
||||
- `linkDistance`: The distance between linked nodes.
|
||||
- `fontSize`: The font size of node labels.
|
||||
- `opacityScale`: The scale of node opacity.
|
||||
- `removeTags`: Tags to exclude from the graph.
|
||||
- `showTags`: Whether to show tags in the graph.
|
||||
- `enableRadial`: Whether to enable radial layout.
|
||||
- `focusOnHover`: Whether to focus on the hovered node (global only).
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/graph
|
||||
enabled: true
|
||||
options:
|
||||
localGraph:
|
||||
drag: true
|
||||
zoom: true
|
||||
depth: 1
|
||||
scale: 1.1
|
||||
repelForce: 0.5
|
||||
centerForce: 0.3
|
||||
linkDistance: 30
|
||||
fontSize: 0.6
|
||||
opacityScale: 1
|
||||
removeTags: []
|
||||
showTags: true
|
||||
enableRadial: false
|
||||
globalGraph:
|
||||
drag: true
|
||||
zoom: true
|
||||
depth: -1
|
||||
scale: 0.9
|
||||
repelForce: 0.5
|
||||
centerForce: 0.3
|
||||
linkDistance: 30
|
||||
fontSize: 0.6
|
||||
opacityScale: 1
|
||||
removeTags: []
|
||||
showTags: true
|
||||
focusOnHover: true
|
||||
enableRadial: true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.Graph()`.
|
||||
- Source: [`quartz-community/graph`](https://github.com/quartz-community/graph)
|
||||
- Install: `npx quartz plugin add github:quartz-community/graph`
|
||||
@ -14,5 +14,6 @@ This plugin has no configuration options.
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.HardLineBreaks()`.
|
||||
- Source: [`quartz/plugins/transformers/linebreaks.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/linebreaks.ts).
|
||||
- Function name: `ExternalPlugin.HardLineBreaks()`.
|
||||
- Source: [`quartz-community/hard-line-breaks`](https://github.com/quartz-community/hard-line-breaks)
|
||||
- Install: `npx quartz plugin add github:quartz-community/hard-line-breaks`
|
||||
|
||||
@ -17,5 +17,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.Latex()`.
|
||||
- Source: [`quartz/plugins/transformers/latex.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/latex.ts).
|
||||
- Function name: `ExternalPlugin.Latex()`.
|
||||
- Source: [`quartz-community/latex`](https://github.com/quartz-community/latex)
|
||||
- Install: `npx quartz plugin add github:quartz-community/latex`
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: NotFoundPage
|
||||
tags:
|
||||
- plugin/emitter
|
||||
- plugin/pageType
|
||||
---
|
||||
|
||||
This plugin emits a 404 (Not Found) page for broken or non-existent URLs.
|
||||
This plugin emits a 404 (Not Found) page for broken or non-existent URLs. It uses the `minimal` [[layout#Page Frames|page frame]] (no sidebars, no header or beforeBody chrome — only content and footer) to present a clean error page.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
@ -13,6 +13,6 @@ This plugin has no configuration options.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Emitter
|
||||
- Function name: `Plugin.NotFoundPage()`.
|
||||
- Source: [`quartz/plugins/emitters/404.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/404.tsx).
|
||||
- Category: Page Type
|
||||
- Function name: `Plugin.NotFoundPage()` (internal plugin).
|
||||
- Source: [`quartz/plugins/pageTypes/404.ts`](https://github.com/jackyzha0/quartz/blob/v5/quartz/plugins/pageTypes/404.ts)
|
||||
|
||||
17
docs/plugins/NoteProperties.md
Normal file
17
docs/plugins/NoteProperties.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
title: NoteProperties
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
The NoteProperties plugin is documented under [[Frontmatter]].
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.NoteProperties()`.
|
||||
- Source: [`quartz-community/note-properties`](https://github.com/quartz-community/note-properties)
|
||||
- Install: `npx quartz plugin add github:quartz-community/note-properties`
|
||||
@ -17,12 +17,13 @@ This plugin accepts the following configuration options:
|
||||
- `callouts`: If `true` (default), adds support for [[callouts|callout]] blocks for emphasizing content.
|
||||
- `mermaid`: If `true` (default), enables [[Mermaid diagrams|Mermaid diagram]] rendering within Markdown files.
|
||||
- `parseTags`: If `true` (default), parses and links tags within the content.
|
||||
- `parseArrows`: If `true` (default), transforms arrow symbols into their HTML character equivalents.
|
||||
- `parseBlockReferences`: If `true` (default), handles block references, linking to specific content blocks.
|
||||
- `enableInHtmlEmbed`: If `true`, allows embedding of content directly within HTML. Defaults to `false`.
|
||||
- `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos and playlists using external image Markdown syntax.
|
||||
- `enableTweetEmbed`: If `true` (default), enables the embedding of tweets as static blockquotes from Twitter/X URLs.
|
||||
- `enableVideoEmbed`: If `true` (default), enables the embedding of video files.
|
||||
- `enableCheckbox`: If `true`, adds support for interactive checkboxes in content. Defaults to `false`.
|
||||
- `enableCheckbox`: If `true`, adds support for interactive checkboxes in content, including custom task characters (e.g. `- [?]`, `- [!]`, `- [/]`). Defaults to `false`.
|
||||
- `enableObsidianUri`: If `true` (default), marks `obsidian://` protocol links with a CSS class and data attribute for custom styling.
|
||||
- `disableBrokenWikilinks`: If `true`, replaces links to non-existent notes with a dimmed, disabled link. Defaults to `false`.
|
||||
|
||||
> [!warning]
|
||||
@ -31,5 +32,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.ObsidianFlavoredMarkdown()`.
|
||||
- Source: [`quartz/plugins/transformers/ofm.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/ofm.ts)
|
||||
- Function name: `ExternalPlugin.ObsidianFlavoredMarkdown()`.
|
||||
- Source: [`quartz-community/obsidian-flavored-markdown`](https://github.com/quartz-community/obsidian-flavored-markdown)
|
||||
- Install: `npx quartz plugin add github:quartz-community/obsidian-flavored-markdown`
|
||||
|
||||
@ -25,5 +25,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.OxHugoFlavoredMarkdown()`.
|
||||
- Source: [`quartz/plugins/transformers/oxhugofm.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/oxhugofm.ts).
|
||||
- Function name: `ExternalPlugin.OxHugoFlavoredMarkdown()`.
|
||||
- Source: [`quartz-community/ox-hugo`](https://github.com/quartz-community/ox-hugo)
|
||||
- Install: `npx quartz plugin add github:quartz-community/ox-hugo`
|
||||
|
||||
19
docs/plugins/PageTitle.md
Normal file
19
docs/plugins/PageTitle.md
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
title: PageTitle
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
This plugin renders the site-wide page title (configured via the `pageTitle` field in [[configuration]]) as a clickable link to the home page. It typically appears in the left sidebar.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
This plugin has no configuration options. The displayed title is controlled by the `pageTitle` field in `quartz.config.yaml`.
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.PageTitle()`.
|
||||
- Source: [`quartz-community/page-title`](https://github.com/quartz-community/page-title)
|
||||
- Install: `npx quartz plugin add github:quartz-community/page-title`
|
||||
32
docs/plugins/ReaderMode.md
Normal file
32
docs/plugins/ReaderMode.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: ReaderMode
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
Distraction-free reading mode.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[reader mode]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `enabled`: Whether to enable reader mode. Defaults to `true`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/reader-mode
|
||||
enabled: true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.ReaderMode()`.
|
||||
- Source: [`quartz-community/reader-mode`](https://github.com/quartz-community/reader-mode)
|
||||
- Install: `npx quartz plugin add github:quartz-community/reader-mode`
|
||||
40
docs/plugins/RecentNotes.md
Normal file
40
docs/plugins/RecentNotes.md
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
title: RecentNotes
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
Shows recently modified notes.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[recent notes]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `title`: The title of the recent notes section. Defaults to `Recent notes`.
|
||||
- `limit`: The maximum number of recent notes to display. Defaults to `5`.
|
||||
- `showTags`: Whether to display the tags for each note. Defaults to `true`.
|
||||
- `linkToMore`: A slug to a page that shows more notes. Defaults to `""`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/recent-notes
|
||||
enabled: true
|
||||
options:
|
||||
title: Recent notes
|
||||
limit: 5
|
||||
showTags: true
|
||||
linkToMore: ""
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.RecentNotes()`.
|
||||
- Source: [`quartz-community/recent-notes`](https://github.com/quartz-community/recent-notes)
|
||||
- Install: `npx quartz plugin add github:quartz-community/recent-notes`
|
||||
@ -14,5 +14,6 @@ This plugin has no configuration options.
|
||||
## API
|
||||
|
||||
- Category: Filter
|
||||
- Function name: `Plugin.RemoveDrafts()`.
|
||||
- Source: [`quartz/plugins/filters/draft.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/filters/draft.ts).
|
||||
- Function name: `ExternalPlugin.RemoveDrafts()`.
|
||||
- Source: [`quartz-community/remove-draft`](https://github.com/quartz-community/remove-draft)
|
||||
- Install: `npx quartz plugin add github:quartz-community/remove-draft`
|
||||
|
||||
@ -22,5 +22,6 @@ This plugin accepts the following configuration options:
|
||||
## API
|
||||
|
||||
- Category: Transformer
|
||||
- Function name: `Plugin.RoamFlavoredMarkdown()`.
|
||||
- Source: [`quartz/plugins/transformers/roam.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/transformers/roam.ts).
|
||||
- Function name: `ExternalPlugin.RoamFlavoredMarkdown()`.
|
||||
- Source: [`quartz-community/roam`](https://github.com/quartz-community/roam)
|
||||
- Install: `npx quartz plugin add github:quartz-community/roam`
|
||||
|
||||
32
docs/plugins/Search.md
Normal file
32
docs/plugins/Search.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Search
|
||||
tags:
|
||||
- plugin/component
|
||||
---
|
||||
|
||||
Full-text search functionality.
|
||||
|
||||
> [!note]
|
||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||
|
||||
See [[full-text search]] for detailed usage information.
|
||||
|
||||
## Configuration
|
||||
|
||||
This plugin accepts the following configuration options:
|
||||
|
||||
- `enabled`: Whether to enable full-text search. Defaults to `true`.
|
||||
|
||||
### Default options
|
||||
|
||||
```yaml title="quartz.config.yaml"
|
||||
- source: github:quartz-community/search
|
||||
enabled: true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- Category: Component
|
||||
- Function name: `ExternalPlugin.Search()`.
|
||||
- Source: [`quartz-community/search`](https://github.com/quartz-community/search)
|
||||
- Install: `npx quartz plugin add github:quartz-community/search`
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user