mirror of
https://github.com/jackyzha0/quartz.git
synced 2026-03-21 21:45:42 -05:00
docs: Quartz v5
This commit is contained in:
parent
f7de4e91e3
commit
2feef3c62e
@ -13,7 +13,7 @@
|
|||||||
- [File Ownership Model](#file-ownership-model)
|
- [File Ownership Model](#file-ownership-model)
|
||||||
- [quartz.config.yaml — The Source of Truth](#quartzconfigyaml--the-source-of-truth)
|
- [quartz.config.yaml — The Source of Truth](#quartzconfigyaml--the-source-of-truth)
|
||||||
- [Plugin Manifest](#plugin-manifest)
|
- [Plugin Manifest](#plugin-manifest)
|
||||||
- [Thin Template Files](#thin-template-files)
|
16: #RZ|- [Thin Template File](#thin-template-file)
|
||||||
- [Plugin Ordering & Dependencies](#plugin-ordering--dependencies)
|
- [Plugin Ordering & Dependencies](#plugin-ordering--dependencies)
|
||||||
- [Layout System](#layout-system)
|
- [Layout System](#layout-system)
|
||||||
- [JSON Schema](#json-schema)
|
- [JSON Schema](#json-schema)
|
||||||
@ -31,10 +31,9 @@
|
|||||||
|
|
||||||
Users must manually edit multiple files to use a plugin:
|
Users must manually edit multiple files to use a plugin:
|
||||||
|
|
||||||
1. **`quartz.config.ts` → `externalPlugins` array**: List of `"github:org/repo"` strings — declares _what_ to install
|
1. **`quartz.config.yaml` → `plugins` array**: List of plugin entries — declares _what_ to install and _how_ to use them
|
||||||
2. **`quartz.config.ts` → `plugins.transformers/filters/emitters/pageTypes` arrays**: Plugin factory calls with options — declares _how_ to use plugins
|
2. **`quartz.ts`**: Thin wrapper that exports configuration and layout
|
||||||
3. **`quartz.layout.ts`**: Layout configuration for component-providing plugins (Explorer, Graph, Search, etc.)
|
3. **`quartz.lock.json`**: Tracks installed versions/commits (managed by CLI)
|
||||||
4. **`quartz.lock.json`**: Tracks installed versions/commits (managed by CLI)
|
|
||||||
|
|
||||||
Additionally:
|
Additionally:
|
||||||
|
|
||||||
@ -42,20 +41,19 @@ Additionally:
|
|||||||
- **No dependencies**: Plugins cannot declare that they need other plugins.
|
- **No dependencies**: Plugins cannot declare that they need other plugins.
|
||||||
- **No ordering**: Plugin execution order is determined by manual array position.
|
- **No ordering**: Plugin execution order is determined by manual array position.
|
||||||
- **Update = apply**: No way to check for available updates without also installing them.
|
- **Update = apply**: No way to check for available updates without also installing them.
|
||||||
- **TypeScript config**: `quartz.config.ts` and `quartz.layout.ts` are not safely machine-editable by external tools (Quartz Syncer).
|
- **TypeScript config**: `quartz.ts` is not safely machine-editable by external tools (Quartz Syncer).
|
||||||
- **Merge conflicts on update**: `npx quartz update` pulls upstream via git. Since `quartz.config.ts` and `quartz.layout.ts` are the primary files users edit, merge conflicts are frequent and frustrating.
|
- **Merge conflicts on update**: `npx quartz update` pulls upstream via git. Since `quartz.config.yaml` is the primary file users edit, merge conflicts are frequent and frustrating.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Architecture Overview
|
## Architecture Overview
|
||||||
|
|
||||||
Introduce a machine-readable **`quartz.config.yaml`** as the single source of truth for all user configuration. The existing TypeScript files become thin, upstream-owned templates that read from this YAML file.
|
52: #TZ|Introduce a machine-readable **`quartz.config.yaml`** as the single source of truth for all user configuration. The existing TypeScript files become a thin, upstream-owned template that reads from this YAML file.
|
||||||
|
|
||||||
```
|
```
|
||||||
quartz-site/
|
quartz-site/
|
||||||
├── quartz/ # Upstream framework code
|
├── quartz/ # Upstream framework code
|
||||||
├── quartz.config.ts # Upstream template — reads from YAML
|
57: #QS|├── quartz.ts # Upstream template — reads from YAML
|
||||||
├── quartz.layout.ts # Upstream template — reads from YAML
|
|
||||||
├── quartz.config.default.yaml # Upstream defaults (reference/seed file)
|
├── quartz.config.default.yaml # Upstream defaults (reference/seed file)
|
||||||
├── quartz.config.yaml # USER-OWNED — all user configuration
|
├── quartz.config.yaml # USER-OWNED — all user configuration
|
||||||
├── quartz.lock.json # CLI-managed — installed plugin versions
|
├── quartz.lock.json # CLI-managed — installed plugin versions
|
||||||
@ -69,10 +67,9 @@ quartz-site/
|
|||||||
## File Ownership Model
|
## File Ownership Model
|
||||||
|
|
||||||
| File | Owner | Tracked by upstream? | User edits? | Updated by `npx quartz update`? |
|
| File | Owner | Tracked by upstream? | User edits? | Updated by `npx quartz update`? |
|
||||||
| ---------------------------- | -------- | --------------------- | ------------------------- | ------------------------------- |
|
| ---------------------------- | -------- | --------------------- | ------------------------- | ------------------------------- | ---------------------- | --- |
|
||||||
| `quartz/` | Upstream | Yes | No (power users only) | Yes |
|
| `quartz/` | Upstream | Yes | No (power users only) | Yes |
|
||||||
| `quartz.config.ts` | Upstream | Yes | **No** — thin template | Yes |
|
| 74: #PY | | `quartz.ts` | Upstream | Yes | **No** — thin template | Yes |
|
||||||
| `quartz.layout.ts` | Upstream | Yes | **No** — thin template | Yes |
|
|
||||||
| `quartz.config.default.yaml` | Upstream | Yes | No — reference only | Yes |
|
| `quartz.config.default.yaml` | Upstream | Yes | No — reference only | Yes |
|
||||||
| `quartz.config.yaml` | **User** | No (user's fork only) | **Yes** — source of truth | **Never** |
|
| `quartz.config.yaml` | **User** | No (user's fork only) | **Yes** — source of truth | **Never** |
|
||||||
| `quartz.lock.json` | **CLI** | Yes (user's fork) | No | No |
|
| `quartz.lock.json` | **CLI** | Yes (user's fork) | No | No |
|
||||||
@ -439,25 +436,17 @@ Each plugin declares metadata in its `package.json` under a `quartz` field, or i
|
|||||||
|
|
||||||
## Thin Template Files
|
## Thin Template Files
|
||||||
|
|
||||||
### quartz.config.ts
|
441: #NR|## Thin Template File
|
||||||
|
442: #WP|
|
||||||
```typescript
|
443: #YN|### quartz.ts
|
||||||
import { loadQuartzConfig } from "./quartz/plugins/loader/config-loader"
|
444: #SB|
|
||||||
|
445: #SH|`typescript
|
||||||
// Configuration and plugins are loaded from quartz.config.yaml.
|
446: #QW|import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||||
// Users should edit quartz.config.yaml instead of this file.
|
447: #XM|
|
||||||
export default await loadQuartzConfig()
|
448: #ZH|const config = await loadQuartzConfig()
|
||||||
```
|
449: #MN|export default config
|
||||||
|
450: #WJ|export const layout = await loadQuartzLayout()
|
||||||
### quartz.layout.ts
|
451: #YX|`
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
|
||||||
|
|
||||||
// Layout is assembled from plugin declarations in quartz.config.yaml.
|
|
||||||
// Users should edit quartz.config.yaml instead of this file.
|
|
||||||
export const layout = await loadQuartzLayout()
|
|
||||||
```
|
|
||||||
|
|
||||||
### What `loadQuartzConfig()` Does
|
### What `loadQuartzConfig()` Does
|
||||||
|
|
||||||
@ -817,7 +806,7 @@ This causes:
|
|||||||
|
|
||||||
### Solution: Conflict-Free by Design
|
### Solution: Conflict-Free by Design
|
||||||
|
|
||||||
With this architecture, `quartz.config.ts` and `quartz.layout.ts` are upstream-owned templates that users never edit. All user customization is in `quartz.config.yaml`, which upstream never ships or modifies.
|
With this architecture, `quartz.ts` is an upstream-owned template that users never edit. All user customization is in `quartz.config.yaml`, which upstream never ships or modifies.
|
||||||
|
|
||||||
### Updated `npx quartz update` Flow
|
### Updated `npx quartz update` Flow
|
||||||
|
|
||||||
@ -835,7 +824,7 @@ With this architecture, `quartz.config.ts` and `quartz.layout.ts` are upstream-o
|
|||||||
- "All 34 plugins compatible" or "Warning: plugin X requires Quartz >=5.3.0"
|
- "All 34 plugins compatible" or "Warning: plugin X requires Quartz >=5.3.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
Since the user's configuration lives in `quartz.config.yaml` (not tracked upstream) and the `.ts` files are thin templates (no user modifications), `git merge` applies cleanly.
|
Since the user's configuration lives in `quartz.config.yaml` (not tracked upstream) and the `quartz.ts` file is a thin template (no user modifications), `git merge` applies cleanly.
|
||||||
|
|
||||||
### Edge Case: Power Users
|
### Edge Case: Power Users
|
||||||
|
|
||||||
@ -881,10 +870,10 @@ A `npx quartz migrate` command handles the one-time conversion:
|
|||||||
2. Reads `quartz.lock.json` for installed plugin metadata
|
2. Reads `quartz.lock.json` for installed plugin metadata
|
||||||
3. Imports `quartz.layout.ts` and inspects the layout object
|
3. Imports `quartz.layout.ts` and inspects the layout object
|
||||||
4. Generates `quartz.config.yaml` with:
|
4. Generates `quartz.config.yaml` with:
|
||||||
- All `configuration` fields from the current config
|
- All `configuration` fields from the current `quartz.config.yaml`
|
||||||
- All plugins (built-in and external) with their current options
|
- All plugins (built-in and external) with their current options
|
||||||
- Layout positions inferred from the layout object
|
- Layout positions inferred from the layout object
|
||||||
5. Replaces `quartz.config.ts` and `quartz.layout.ts` with thin templates
|
5. Replaces `quartz.config.ts` and `quartz.layout.ts` with the consolidated `quartz.ts` wrapper
|
||||||
6. Prints migration summary
|
6. Prints migration summary
|
||||||
|
|
||||||
### For Plugin Authors
|
### For Plugin Authors
|
||||||
@ -903,7 +892,8 @@ Plugins without the extended manifest fields still load with sensible defaults (
|
|||||||
|
|
||||||
### Backward Compatibility
|
### Backward Compatibility
|
||||||
|
|
||||||
- A `quartz.config.ts` that doesn't use the thin template pattern continues to work (direct import, bypasses YAML)
|
906: #ZM|- A `quartz.ts` that doesn't use the thin template pattern continues to work (direct import, bypasses YAML)
|
||||||
|
|
||||||
- If `quartz.config.yaml` doesn't exist, `plugin-data.js` falls back to `quartz.plugins.json` for backward compatibility
|
- If `quartz.config.yaml` doesn't exist, `plugin-data.js` falls back to `quartz.plugins.json` for backward compatibility
|
||||||
- Plugins without the extended manifest fields still load normally
|
- Plugins without the extended manifest fields still load normally
|
||||||
- The migration is opt-in via `npx quartz migrate`
|
- The migration is opt-in via `npx quartz migrate`
|
||||||
@ -936,9 +926,9 @@ Plugins without the extended manifest fields still load with sensible defaults (
|
|||||||
|
|
||||||
### Phase 4: Thin Templates
|
### Phase 4: Thin Templates
|
||||||
|
|
||||||
14. **`quartz.config.ts` template** — Replace with thin loader template
|
938: #VY|### Phase 4: Thin Template
|
||||||
15. **`quartz.layout.ts` template** — Replace with thin loader template
|
939: #PW|14. **`quartz.ts` template** — Replace with thin loader template
|
||||||
16. **Build pipeline update** — Ensure `build.ts` works with the new config loading path
|
940: #MV|15. **Build pipeline update** — Ensure `build.ts` works with the new config loading path
|
||||||
|
|
||||||
### Phase 5: Plugin Author Support
|
### Phase 5: Plugin Author Support
|
||||||
|
|
||||||
|
|||||||
@ -22,18 +22,18 @@ Notes and decisions for implementing Quartz v5 plugin management support in Quar
|
|||||||
|
|
||||||
## Overview of Changes
|
## Overview of Changes
|
||||||
|
|
||||||
Quartz v5 moves all user configuration from TypeScript files (`quartz.config.ts`, `quartz.layout.ts`) into a single YAML file (`quartz.config.yaml`). This eliminates the need for AST parsing or TypeScript manipulation — Syncer can now manage the entire Quartz configuration through plain YAML read/write operations.
|
Quartz v5 moves all user configuration from TypeScript files (`quartz.config.ts`, `quartz.layout.ts`) into a single YAML file (`quartz.config.yaml`). This eliminates the need for AST parsing or TypeScript manipulation — Syncer can now manage the entire Quartz configuration through plain YAML read/write operations. In v5, these TypeScript files are consolidated into a single `quartz.ts` wrapper.
|
||||||
|
|
||||||
**Before (v4):**
|
**Before (v4):**
|
||||||
|
|
||||||
- Configuration spread across `quartz.config.ts` (TypeScript) and `quartz.layout.ts` (TypeScript)
|
- Configuration spread across `quartz.config.ts` (TypeScript) and `quartz.layout.ts` (TypeScript) in v4
|
||||||
- Syncer could not safely edit these files (no TS parser in isomorphic-git/LightningFS environment)
|
- Syncer could not safely edit these files (no TS parser in isomorphic-git/LightningFS environment)
|
||||||
- Plugin management required manual file editing
|
- Plugin management required manual file editing
|
||||||
|
|
||||||
**After (v5):**
|
**After (v5):**
|
||||||
|
|
||||||
- All user configuration in `quartz.config.yaml` (YAML)
|
- All user configuration in `quartz.config.yaml` (YAML)
|
||||||
- TypeScript files are upstream-owned thin templates that read from the YAML config
|
36: #JJ|- TypeScript files are upstream-owned thin templates (consolidated into `quartz.ts`) that read from the YAML config
|
||||||
- Syncer can fully manage configuration via YAML read/write → git commit → push
|
- Syncer can fully manage configuration via YAML read/write → git commit → push
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -41,11 +41,10 @@ Quartz v5 moves all user configuration from TypeScript files (`quartz.config.ts`
|
|||||||
## File Ownership Model
|
## File Ownership Model
|
||||||
|
|
||||||
| File | Owner | Syncer Can Edit? | Notes |
|
| File | Owner | Syncer Can Edit? | Notes |
|
||||||
| ---------------------------- | -------- | ---------------- | ------------------------------------------------------------- |
|
| ---------------------------- | -------- | ---------------- | ------------------------------------------------------------- | ------ | --------------------------------------------- |
|
||||||
| `quartz.config.yaml` | **User** | **Yes** | The source of truth. Syncer's primary interface. |
|
| `quartz.config.yaml` | **User** | **Yes** | The source of truth. Syncer's primary interface. |
|
||||||
| `quartz.config.default.yaml` | Upstream | **No** | Reference only. Seed file copied on `npx quartz create`. |
|
| `quartz.config.default.yaml` | Upstream | **No** | Reference only. Seed file copied on `npx quartz create`. |
|
||||||
| `quartz.config.ts` | Upstream | **No** | Thin template. Just imports from YAML loader. |
|
| 47: #RS | | `quartz.ts` | Upstream | **No** | Thin template. Just imports from YAML loader. |
|
||||||
| `quartz.layout.ts` | Upstream | **No** | Thin template. Just imports from YAML loader. |
|
|
||||||
| `quartz.lock.json` | CLI | Read only | Tracks installed plugin versions/commits. Useful for display. |
|
| `quartz.lock.json` | CLI | Read only | Tracks installed plugin versions/commits. Useful for display. |
|
||||||
| `.quartz/plugins/` | CLI | **No** | Git clones managed by CLI. `.gitignore`d. |
|
| `.quartz/plugins/` | CLI | **No** | Git clones managed by CLI. `.gitignore`d. |
|
||||||
| `content/` | User | **Yes** | Existing Syncer behavior unchanged. |
|
| `content/` | User | **Yes** | Existing Syncer behavior unchanged. |
|
||||||
@ -383,14 +382,14 @@ Syncer should NOT attempt to run the migration itself — it requires Node.js/ts
|
|||||||
|
|
||||||
### Post-Migration
|
### Post-Migration
|
||||||
|
|
||||||
After migration, `quartz.config.ts` and `quartz.layout.ts` become thin templates:
|
386: #TT|After migration, `quartz.ts` becomes a thin template:
|
||||||
|
387: #JV|
|
||||||
```typescript
|
388: #SH|`typescript
|
||||||
// quartz.config.ts
|
389: #TW|import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||||
import { loadQuartzConfig } from "./quartz/plugins/loader/config-loader"
|
390: #QW|const config = await loadQuartzConfig()
|
||||||
export default await loadQuartzConfig()
|
391: #WJ|export default config
|
||||||
```
|
392: #KJ|export const layout = await loadQuartzLayout()
|
||||||
|
393: #WV|`
|
||||||
Syncer should not modify these files.
|
Syncer should not modify these files.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -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.
|
4. Filter out unwanted content using plugins.
|
||||||
5. Emit files using plugins.
|
5. Emit files using plugins.
|
||||||
1. Gather all the static resources (e.g. external CSS, JS modules, etc.) each emitter plugin declares.
|
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.
|
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.
|
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.
|
3. Finally, each emitter plugin is responsible for emitting and writing it's own emitted files to disk.
|
||||||
@ -51,7 +51,7 @@ This question is best answered by tracing what happens when a user (you!) runs `
|
|||||||
|
|
||||||
## Plugin System
|
## Plugin System
|
||||||
|
|
||||||
### External Plugin Architecture
|
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`.
|
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`.
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,7 @@ export type QuartzComponentProps = {
|
|||||||
- `fileData`: Any metadata 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.slug`: slug of the current page.
|
||||||
- `fileData.frontmatter`: any frontmatter parsed.
|
- `fileData.frontmatter`: any frontmatter parsed.
|
||||||
- `cfg`: The `configuration` field in `quartz.config.ts`.
|
- `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.
|
- `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.
|
- `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.
|
- `displayClass`: a utility class that indicates a preference from the user about how to render it in a mobile or desktop setting.
|
||||||
@ -156,19 +156,34 @@ Once your component is published (e.g., to GitHub or npm), users can install it
|
|||||||
npx quartz plugin add github:your-username/my-component
|
npx quartz plugin add github:your-username/my-component
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, they can use it in their `quartz.layout.ts`:
|
Then, they can add it to their `quartz.config.yaml`:
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
import * as Plugin from "./.quartz/plugins"
|
plugins:
|
||||||
|
- source: github:your-username/my-component
|
||||||
|
enabled: true
|
||||||
|
options:
|
||||||
|
favouriteNumber: 42
|
||||||
|
layout:
|
||||||
|
position: left
|
||||||
|
priority: 60
|
||||||
|
```
|
||||||
|
|
||||||
export const layout = {
|
For advanced usage via the TS override in `quartz.ts`:
|
||||||
defaults: { ... },
|
|
||||||
|
```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: {
|
byPageType: {
|
||||||
content: {
|
content: {
|
||||||
left: [Plugin.MyComponent()],
|
left: [Plugin.MyComponent({ favouriteNumber: 42 })],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## Internal Components
|
## Internal Components
|
||||||
|
|||||||
@ -351,7 +351,7 @@ export const ContentPage: QuartzEmitterPlugin = () => {
|
|||||||
|
|
||||||
### Page Types
|
### Page Types
|
||||||
|
|
||||||
Page types define how a category of pages is rendered. They are configured in the `pageTypes` array in `quartz.config.ts`.
|
Page types define how a category of pages is rendered. They are configured in the `pageTypes` array in `quartz.config.yaml`.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
export type QuartzPageTypePluginInstance = {
|
export type QuartzPageTypePluginInstance = {
|
||||||
@ -383,9 +383,17 @@ npx tsup
|
|||||||
npx quartz plugin add github:your-username/my-plugin
|
npx quartz plugin add github:your-username/my-plugin
|
||||||
```
|
```
|
||||||
|
|
||||||
Then add the plugin to the appropriate array in `quartz.config.ts`:
|
Then add the plugin to your `quartz.config.yaml`:
|
||||||
|
|
||||||
```ts
|
```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"
|
import * as ExternalPlugin from "./.quartz/plugins"
|
||||||
// ...
|
// ...
|
||||||
transformers: [ExternalPlugin.MyPlugin()]
|
transformers: [ExternalPlugin.MyPlugin()]
|
||||||
|
|||||||
@ -2,18 +2,21 @@
|
|||||||
title: Configuration
|
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]
|
> [!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:
|
The configuration of Quartz can be broken down into two main parts:
|
||||||
|
|
||||||
```ts title="quartz.config.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
const config: QuartzConfig = {
|
configuration:
|
||||||
configuration: { ... },
|
pageTitle: "My Site"
|
||||||
plugins: { ... },
|
# ... general configuration
|
||||||
}
|
plugins:
|
||||||
|
- source: github:quartz-community/some-plugin
|
||||||
|
enabled: true
|
||||||
|
# ... plugin entries
|
||||||
```
|
```
|
||||||
|
|
||||||
## General Configuration
|
## General Configuration
|
||||||
@ -67,15 +70,32 @@ You can think of Quartz plugins as a series of transformations over content.
|
|||||||
|
|
||||||
![[quartz transform pipeline.png]]
|
![[quartz transform pipeline.png]]
|
||||||
|
|
||||||
```ts title="quartz.config.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
plugins: {
|
plugins:
|
||||||
transformers: [...],
|
- source: github:quartz-community/created-modified-date
|
||||||
filters: [...],
|
enabled: true
|
||||||
emitters: [...],
|
order: 10 # controls execution order
|
||||||
pageTypes: [...],
|
- 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/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/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)
|
- [[tags/plugin/emitter|Emitters]] **reduce** over content (e.g. creating an RSS feed or pages that list all files with a specific tag)
|
||||||
@ -85,25 +105,32 @@ plugins: {
|
|||||||
|
|
||||||
Quartz distinguishes between internal plugins that are bundled with Quartz and community plugins that are installed separately.
|
Quartz distinguishes between internal plugins that are bundled with Quartz and community plugins that are installed separately.
|
||||||
|
|
||||||
```ts title="quartz.config.ts"
|
In `quartz.config.yaml`, community plugins are referenced by their GitHub source:
|
||||||
import * as Plugin from "./quartz/plugins" // internal plugins
|
|
||||||
import * as ExternalPlugin from "./.quartz/plugins" // community plugins
|
```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 `Plugin.FrontMatter()`) are bundled with Quartz. Community plugins (like `ExternalPlugin.Explorer()`) are installed separately.
|
Internal plugins (like `FrontMatter`) are bundled with Quartz. Community plugins are installed separately and referenced by their `github:org/repo` source.
|
||||||
|
|
||||||
### Community Plugins
|
### Community Plugins
|
||||||
|
|
||||||
The `externalPlugins` array in your configuration declares which community plugin repositories to install. Each entry is a GitHub repository reference.
|
To install a community plugin, you can use the following command:
|
||||||
|
|
||||||
```ts title="quartz.config.ts"
|
```shell
|
||||||
externalPlugins: [
|
npx quartz plugin add github:quartz-community/explorer
|
||||||
"github:quartz-community/explorer",
|
|
||||||
"github:quartz-community/syntax-highlighting",
|
|
||||||
// ... other community plugins
|
|
||||||
],
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This adds the plugin to `quartz.config.yaml` and installs it to `.quartz/plugins/`.
|
||||||
|
|
||||||
To install a community plugin, you can use the following command:
|
To install a community plugin, you can use the following command:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@ -114,41 +141,72 @@ This adds the plugin to `externalPlugins` and installs it to `.quartz/plugins/`.
|
|||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
You can customize the behaviour of Quartz by adding, removing and reordering plugins in the `transformers`, `filters`, `emitters`, and `pageTypes` fields. You can mix internal and external plugins as needed.
|
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:
|
||||||
|
|
||||||
```ts title="quartz.config.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
transformers: [
|
plugins:
|
||||||
Plugin.FrontMatter(), // internal
|
- source: github:quartz-community/note-properties
|
||||||
ExternalPlugin.CreatedModifiedDate({
|
enabled: true
|
||||||
// community
|
options:
|
||||||
priority: ["frontmatter", "git", "filesystem"],
|
includeAll: false
|
||||||
}),
|
includedProperties:
|
||||||
ExternalPlugin.Latex({ renderEngine: "katex" }), // community with options
|
- 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]
|
||||||
|
> 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]].
|
You can see a list of all plugins and their configuration options [[tags/plugin|here]].
|
||||||
|
|
||||||
If you'd like to make your own plugins, see the [[making plugins|making custom plugins]] guide.
|
If you'd like to make your own plugins, see the [[making plugins|making custom plugins]] guide.
|
||||||
|
|
||||||
## Fonts
|
## 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
|
```yaml title="quartz.config.yaml"
|
||||||
// string
|
configuration:
|
||||||
typography: {
|
theme:
|
||||||
header: "Schibsted Grotesk",
|
typography:
|
||||||
...
|
header: Schibsted Grotesk
|
||||||
}
|
body: Source Sans Pro
|
||||||
|
code: IBM Plex Mono
|
||||||
// FontSpecification
|
```
|
||||||
typography: {
|
|
||||||
header: {
|
For more control over font weights and italics, use the TS override in `quartz.ts`:
|
||||||
name: "Schibsted Grotesk",
|
|
||||||
weights: [400, 700],
|
```ts title="quartz.ts"
|
||||||
includeItalic: true,
|
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()
|
||||||
```
|
```
|
||||||
|
|||||||
@ -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.
|
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: {
|
plugins: {
|
||||||
transformers: [
|
transformers: [
|
||||||
Plugin.FrontMatter({ delims: "+++", language: "toml" }), // if toml frontmatter
|
Plugin.FrontMatter({ delims: "+++", language: "toml" }),
|
||||||
// ...
|
// ...
|
||||||
Plugin.OxHugoFlavouredMarkdown(),
|
Plugin.OxHugoFlavouredMarkdown(),
|
||||||
Plugin.GitHubFlavoredMarkdown(),
|
Plugin.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
|
## 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.
|
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,7 +9,19 @@ tags:
|
|||||||
Quartz supports transforming the special Markdown syntax from Roam Research (like `{{[[components]]}}` and other formatting) into
|
Quartz supports transforming the special Markdown syntax from Roam Research (like `{{[[components]]}}` and other formatting) into
|
||||||
regular Markdown via the [[RoamFlavoredMarkdown]] plugin.
|
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: {
|
plugins: {
|
||||||
transformers: [
|
transformers: [
|
||||||
// ...
|
// ...
|
||||||
@ -17,11 +29,14 @@ plugins: {
|
|||||||
Plugin.ObsidianFlavoredMarkdown(),
|
Plugin.ObsidianFlavoredMarkdown(),
|
||||||
// ...
|
// ...
|
||||||
],
|
],
|
||||||
},
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!warning]
|
> [!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.
|
||||||
|
|
||||||
|
> [!warning]
|
||||||
|
> In YAML, plugin execution order is controlled by the `order` field. Ensure the `roam` plugin has a lower `order` value than `obsidian-flavored-markdown` so it runs first.
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
|
|||||||
@ -4,4 +4,4 @@ Under the hood, this is done by hijacking page navigations and instead fetching
|
|||||||
|
|
||||||
## Configuration
|
## 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,9 +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.
|
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
|
## Customization
|
||||||
|
|
||||||
- Removing backlinks: delete all usages of `Plugin.Backlinks()` from `quartz.layout.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, use `Plugin.Backlinks({ hideWhenEmpty: 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`
|
- Install: `npx quartz plugin add github:quartz-community/backlinks`
|
||||||
- Source: [`quartz-community/backlinks`](https://github.com/quartz-community/backlinks)
|
- Source: [`quartz-community/backlinks`](https://github.com/quartz-community/backlinks)
|
||||||
|
|||||||
@ -8,27 +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!).
|
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
|
## Customization
|
||||||
|
|
||||||
Most configuration can be done by passing in options to `Plugin.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:
|
For example, here's what the default configuration looks like:
|
||||||
|
|
||||||
```typescript title="quartz.layout.ts"
|
```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)"
|
||||||
Plugin.Breadcrumbs({
|
Plugin.Breadcrumbs({
|
||||||
spacerSymbol: "❯", // symbol between crumbs
|
spacerSymbol: "❯",
|
||||||
rootName: "Home", // name of first/root element
|
rootName: "Home",
|
||||||
resolveFrontmatterTitle: true, // whether to resolve folder names through frontmatter titles
|
resolveFrontmatterTitle: true,
|
||||||
showCurrentPage: true, // whether to display the current page in the breadcrumbs
|
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.
|
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 `Plugin.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?
|
Want to customize it even more?
|
||||||
|
|
||||||
- Removing breadcrumbs: delete all usages of `Plugin.Breadcrumbs()` from `quartz.layout.ts`.
|
- Removing breadcrumbs: remove the `breadcrumbs` entry from `quartz.config.yaml` or set `enabled: false`.
|
||||||
- Install: `npx quartz plugin add github:quartz-community/breadcrumbs`
|
- Install: `npx quartz plugin add github:quartz-community/breadcrumbs`
|
||||||
- Source: [`quartz-community/breadcrumbs`](https://github.com/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.
|
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]]
|
![[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!
|
As of today, only [Giscus](https://giscus.app/) is supported out of the box but PRs to support other providers are welcome!
|
||||||
@ -30,26 +33,49 @@ After entering both your repository and selecting the discussion category, Giscu
|
|||||||
|
|
||||||
![[giscus-results.png]]
|
![[giscus-results.png]]
|
||||||
|
|
||||||
Finally, in `quartz.layout.ts`, edit the `afterBody` field of the `defaults` layout to include the following options but with the values you got from above:
|
Finally, in `quartz.config.yaml`, edit the `afterBody` field of the `defaults` layout to include the following options but with the values you got from above:
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
afterBody: [
|
plugins:
|
||||||
Plugin.Comments({
|
- source: github:quartz-community/comments
|
||||||
provider: 'giscus',
|
enabled: true
|
||||||
options: {
|
options:
|
||||||
// from data-repo
|
provider: giscus
|
||||||
repo: 'jackyzha0/quartz',
|
options:
|
||||||
// from data-repo-id
|
repo: jackyzha0/quartz
|
||||||
repoId: 'MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg',
|
repoId: MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg
|
||||||
// from data-category
|
category: Announcements
|
||||||
category: 'Announcements',
|
categoryId: DIC_kwDOFxRnmM4B-Xg6
|
||||||
// from data-category-id
|
lang: en
|
||||||
categoryId: 'DIC_kwDOFxRnmM4B-Xg6',
|
layout:
|
||||||
// from data-lang
|
position: afterBody
|
||||||
lang: 'en'
|
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: [
|
||||||
|
Plugin.Comments({
|
||||||
|
provider: "giscus",
|
||||||
|
options: {
|
||||||
|
repo: "jackyzha0/quartz",
|
||||||
|
repoId: "MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg",
|
||||||
|
category: "Announcements",
|
||||||
|
categoryId: "DIC_kwDOFxRnmM4B-Xg6",
|
||||||
|
lang: "en",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!note]
|
> [!note]
|
||||||
@ -109,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/`:
|
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
|
```yaml title="quartz.config.yaml"
|
||||||
afterBody: [
|
plugins:
|
||||||
Plugin.Comments({
|
- source: github:quartz-community/comments
|
||||||
provider: 'giscus',
|
enabled: true
|
||||||
options: {
|
options:
|
||||||
// Other 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/
|
```ts title="quartz.ts (override)"
|
||||||
lightTheme: "light-theme", // corresponds to light-theme.css in quartz/static/giscus/
|
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||||
darkTheme: "dark-theme", // corresponds to dark-theme.css quartz/static/giscus/
|
|
||||||
}
|
const config = await loadQuartzConfig()
|
||||||
}),
|
export default config
|
||||||
],
|
export const layout = await loadQuartzLayout({
|
||||||
|
defaults: {
|
||||||
|
afterBody: [
|
||||||
|
Plugin.Comments({
|
||||||
|
provider: "giscus",
|
||||||
|
options: {
|
||||||
|
// Other options...
|
||||||
|
themeUrl: "https://example.com/static/giscus",
|
||||||
|
lightTheme: "light-theme",
|
||||||
|
darkTheme: "dark-theme",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Conditionally display comments
|
#### Conditionally display comments
|
||||||
|
|||||||
@ -6,9 +6,12 @@ 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.
|
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
|
## Customization
|
||||||
|
|
||||||
- Removing darkmode: delete all usages of `Plugin.Darkmode()` from `quartz.layout.ts`.
|
- Removing darkmode: remove the `darkmode` entry from `quartz.config.yaml` or set `enabled: false`.
|
||||||
- Install: `npx quartz plugin add github:quartz-community/darkmode`
|
- Install: `npx quartz plugin add github:quartz-community/darkmode`
|
||||||
- Source: [`quartz-community/darkmode`](https://github.com/quartz-community/darkmode)
|
- Source: [`quartz-community/darkmode`](https://github.com/quartz-community/darkmode)
|
||||||
|
|
||||||
|
|||||||
@ -17,21 +17,15 @@ The Explorer is available as a community plugin from GitHub:
|
|||||||
npm install github:quartz-community/explorer --legacy-peer-deps
|
npm install github:quartz-community/explorer --legacy-peer-deps
|
||||||
```
|
```
|
||||||
|
|
||||||
Then import it in your `quartz.layout.ts`:
|
Then add it to your `quartz.config.yaml`:
|
||||||
|
|
||||||
```typescript title="quartz.layout.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
import { Explorer } from "@quartz-community/explorer"
|
plugins:
|
||||||
|
- source: github:quartz-community/explorer
|
||||||
// Create once and reuse
|
enabled: true
|
||||||
const explorerComponent = Explorer()
|
layout:
|
||||||
|
position: left
|
||||||
export const defaultContentPageLayout: PageLayout = {
|
priority: 50
|
||||||
// ... other layout config
|
|
||||||
left: [
|
|
||||||
// ... other components
|
|
||||||
explorerComponent,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
@ -51,26 +45,50 @@ Most configuration can be done by passing in options to `Explorer()`.
|
|||||||
|
|
||||||
For example, here's what the default configuration looks like:
|
For example, here's what the default configuration looks like:
|
||||||
|
|
||||||
```typescript title="quartz.layout.ts"
|
```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({
|
Explorer({
|
||||||
title: "Explorer", // title of the explorer component
|
sortFn: (a, b) => {
|
||||||
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
|
filterFn: (node) => {
|
||||||
// omitted but shown later
|
/* ... */
|
||||||
sortFn: ...,
|
},
|
||||||
filterFn: ...,
|
mapFn: (node) => {
|
||||||
mapFn: ...,
|
/* ... */
|
||||||
// what order to apply functions in
|
},
|
||||||
order: ["filter", "map", "sort"],
|
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.
|
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?
|
Want to customize it even more?
|
||||||
|
|
||||||
- Removing explorer: remove `explorerComponent` 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
|
- (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]]
|
- Changing `sort`, `filter` and `map` behavior: explained in [[#Advanced customization]]
|
||||||
|
|
||||||
@ -141,7 +159,19 @@ These examples show the basic usage of `sort`, `map` and `filter`.
|
|||||||
|
|
||||||
Using this example, the explorer will alphabetically sort everything.
|
Using this example, the explorer will alphabetically sort everything.
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
```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({
|
Explorer({
|
||||||
sortFn: (a, b) => {
|
sortFn: (a, b) => {
|
||||||
return a.displayName.localeCompare(b.displayName)
|
return a.displayName.localeCompare(b.displayName)
|
||||||
@ -153,7 +183,7 @@ Explorer({
|
|||||||
|
|
||||||
Using this example, the display names of all `FileNodes` (folders + files) will be converted to full upper case.
|
Using this example, the display names of all `FileNodes` (folders + files) will be converted to full upper case.
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
```ts title="quartz.ts (override)"
|
||||||
Explorer({
|
Explorer({
|
||||||
mapFn: (node) => {
|
mapFn: (node) => {
|
||||||
node.displayName = node.displayName.toUpperCase()
|
node.displayName = node.displayName.toUpperCase()
|
||||||
@ -162,12 +192,15 @@ 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`)
|
### Remove list of elements (`filter`)
|
||||||
|
|
||||||
Using this example, you can remove elements from your explorer by providing an array of folders/files to exclude.
|
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`.
|
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"
|
```ts title="quartz.ts (override)"
|
||||||
Explorer({
|
Explorer({
|
||||||
filterFn: (node) => {
|
filterFn: (node) => {
|
||||||
// set containing names of everything you want to filter out
|
// set containing names of everything you want to filter out
|
||||||
@ -185,7 +218,7 @@ Explorer({
|
|||||||
|
|
||||||
You can access the tags of a file by `node.data.tags`.
|
You can access the tags of a file by `node.data.tags`.
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
```ts title="quartz.ts (override)"
|
||||||
Explorer({
|
Explorer({
|
||||||
filterFn: (node) => {
|
filterFn: (node) => {
|
||||||
// exclude files with the tag "explorerexclude"
|
// exclude files with the tag "explorerexclude"
|
||||||
@ -199,7 +232,7 @@ Explorer({
|
|||||||
By default, the explorer will filter out the `tags` folder.
|
By default, the explorer will filter out the `tags` folder.
|
||||||
To override the default filter function, you can set the filter function to `undefined`.
|
To override the default filter function, you can set the filter function to `undefined`.
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
```ts title="quartz.ts (override)"
|
||||||
Explorer({
|
Explorer({
|
||||||
filterFn: undefined, // apply no filter function, every file and folder will visible
|
filterFn: undefined, // apply no filter function, every file and folder will visible
|
||||||
})
|
})
|
||||||
@ -208,11 +241,11 @@ Explorer({
|
|||||||
## Advanced examples
|
## Advanced examples
|
||||||
|
|
||||||
> [!tip]
|
> [!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
|
> You can fix this by defining your sort functions outside of the component
|
||||||
> and passing it in.
|
> and passing it in.
|
||||||
>
|
>
|
||||||
> ```ts title="quartz.layout.ts"
|
> ```ts title="quartz.ts"
|
||||||
> import { ExplorerOptions } from "@quartz-community/explorer/components"
|
> import { ExplorerOptions } from "@quartz-community/explorer/components"
|
||||||
>
|
>
|
||||||
> export const mapFn: ExplorerOptions["mapFn"] = (node) => {
|
> export const mapFn: ExplorerOptions["mapFn"] = (node) => {
|
||||||
@ -235,9 +268,9 @@ Explorer({
|
|||||||
|
|
||||||
### Add emoji prefix
|
### 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"
|
```ts title="quartz.ts (override)"
|
||||||
Explorer({
|
Explorer({
|
||||||
mapFn: (node) => {
|
mapFn: (node) => {
|
||||||
if (node.isFolder) {
|
if (node.isFolder) {
|
||||||
|
|||||||
@ -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.
|
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.
|
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`).
|
To search content by tags, you can either press `⌘`/`ctrl` + `shift` + `K` or start your query with `#` (e.g. `#components`).
|
||||||
@ -23,6 +26,6 @@ It properly tokenizes Chinese, Korean, and Japenese characters and constructs se
|
|||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
- Removing search: delete all usages of `Plugin.Search()` from `quartz.layout.ts`.
|
- Removing search: remove the `search` entry from `quartz.config.yaml` or set `enabled: false`.
|
||||||
- Install: `npx quartz plugin add github:quartz-community/search`
|
- Install: `npx quartz plugin add github:quartz-community/search`
|
||||||
- Source: [`quartz-community/search`](https://github.com/quartz-community/search)
|
- Source: [`quartz-community/search`](https://github.com/quartz-community/search)
|
||||||
|
|||||||
@ -20,21 +20,15 @@ The Graph View is available as a community plugin from GitHub:
|
|||||||
npm install github:quartz-community/graph --legacy-peer-deps
|
npm install github:quartz-community/graph --legacy-peer-deps
|
||||||
```
|
```
|
||||||
|
|
||||||
Then import it in your `quartz.layout.ts`:
|
Then add it to your `quartz.config.yaml`:
|
||||||
|
|
||||||
```typescript title="quartz.layout.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
import { Graph } from "@quartz-community/graph"
|
plugins:
|
||||||
|
- source: github:quartz-community/graph
|
||||||
// Create once and reuse
|
enabled: true
|
||||||
const graphComponent = Graph()
|
layout:
|
||||||
|
position: right
|
||||||
export const defaultContentPageLayout: PageLayout = {
|
priority: 10
|
||||||
// ... other layout config
|
|
||||||
right: [
|
|
||||||
// ... other components
|
|
||||||
graphComponent,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
@ -52,43 +46,46 @@ Most configuration can be done by passing in options to `Graph()`.
|
|||||||
|
|
||||||
For example, here's what the default configuration looks like:
|
For example, here's what the default configuration looks like:
|
||||||
|
|
||||||
```typescript title="quartz.layout.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
Graph({
|
plugins:
|
||||||
localGraph: {
|
- source: github:quartz-community/graph
|
||||||
drag: true, // whether to allow panning the view around
|
enabled: true
|
||||||
zoom: true, // whether to allow zooming in and out
|
options:
|
||||||
depth: 1, // how many hops of notes to display
|
localGraph:
|
||||||
scale: 1.1, // default view scale
|
drag: true
|
||||||
repelForce: 0.5, // how much nodes should repel each other
|
zoom: true
|
||||||
centerForce: 0.3, // how much force to use when trying to center the nodes
|
depth: 1
|
||||||
linkDistance: 30, // how long should the links be by default?
|
scale: 1.1
|
||||||
fontSize: 0.6, // what size should the node labels be?
|
repelForce: 0.5
|
||||||
opacityScale: 1, // how quickly do we fade out the labels when zooming out?
|
centerForce: 0.3
|
||||||
removeTags: [], // what tags to remove from the graph
|
linkDistance: 30
|
||||||
showTags: true, // whether to show tags in the graph
|
fontSize: 0.6
|
||||||
enableRadial: false, // whether to constrain the graph, similar to Obsidian
|
opacityScale: 1
|
||||||
},
|
removeTags: []
|
||||||
globalGraph: {
|
showTags: true
|
||||||
drag: true,
|
enableRadial: false
|
||||||
zoom: true,
|
globalGraph:
|
||||||
depth: -1,
|
drag: true
|
||||||
scale: 0.9,
|
zoom: true
|
||||||
repelForce: 0.5,
|
depth: -1
|
||||||
centerForce: 0.3,
|
scale: 0.9
|
||||||
linkDistance: 30,
|
repelForce: 0.5
|
||||||
fontSize: 0.6,
|
centerForce: 0.3
|
||||||
opacityScale: 1,
|
linkDistance: 30
|
||||||
removeTags: [], // what tags to remove from the graph
|
fontSize: 0.6
|
||||||
showTags: true, // whether to show tags in the graph
|
opacityScale: 1
|
||||||
focusOnHover: true, // dim non-connected nodes on hover
|
removeTags: []
|
||||||
enableRadial: true, // whether to constrain the graph, similar to Obsidian
|
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.
|
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?
|
Want to customize it even more?
|
||||||
|
|
||||||
- Removing graph view: remove `graphComponent` from `quartz.layout.ts`
|
- Removing graph view: remove the `graph` entry from `quartz.config.yaml` or set `enabled: false`
|
||||||
- Component source: https://github.com/quartz-community/graph
|
- Component source: https://github.com/quartz-community/graph
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
title: Internationalization
|
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}`
|
The locale field generally follows a certain format: `{language}-{REGION}`
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,6 @@ Similar to Obsidian, [[quartz-layout-desktop.png|images referenced using wikilin
|
|||||||
|
|
||||||
## Configuration
|
## 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`
|
- Style: `quartz/components/styles/popover.scss`
|
||||||
- Script: `quartz/components/scripts/popover.inline.ts`
|
- 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`
|
## `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]
|
> [!note]
|
||||||
> Bash's glob syntax is slightly different from fast-glob's and using bash's syntax may lead to unexpected results.
|
> Bash's glob syntax is slightly different from fast-glob's and using bash's syntax may lead to unexpected results.
|
||||||
|
|||||||
@ -6,13 +6,23 @@ 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.
|
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
|
## 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
|
```yaml title="quartz.config.yaml"
|
||||||
// Remove or comment out this line
|
plugins:
|
||||||
Plugin.ReaderMode(),
|
- 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`
|
- Install: `npx quartz plugin add github:quartz-community/reader-mode`
|
||||||
|
|||||||
@ -3,15 +3,20 @@ title: Recent Notes
|
|||||||
tags: component
|
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 `Plugin.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
|
## Customization
|
||||||
|
|
||||||
- Changing the title from "Recent notes": pass in an additional parameter to `Plugin.RecentNotes({ title: "Recent writing" })`
|
Most options are configured in the `options` section of the plugin entry in `quartz.config.yaml`:
|
||||||
- Changing the number of recent notes: pass in an additional parameter to `Plugin.RecentNotes({ limit: 5 })`
|
|
||||||
- Display the note's tags (defaults to true): `Plugin.RecentNotes({ showTags: false })`
|
- Changing the title from "Recent notes": set `title: "Recent writing"` in options
|
||||||
- Show a 'see more' link: pass in an additional parameter to `Plugin.RecentNotes({ linkToMore: "tags/components" })`. This field should be a full slug to a page that exists.
|
- Changing the number of recent notes: set `limit: 5` in options
|
||||||
- Customize filtering: pass in an additional parameter to `Plugin.RecentNotes({ filter: someFilterFunction })`. The filter function should be a function that has the signature `(f: QuartzPluginData) => boolean`.
|
- Display the note's tags (defaults to true): set `showTags: false` in options
|
||||||
- Customize sorting: pass in an additional parameter to `Plugin.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`.
|
- 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`
|
- Install: `npx quartz plugin add github:quartz-community/recent-notes`
|
||||||
- Source: [`quartz-community/recent-notes`](https://github.com/quartz-community/recent-notes)
|
- Source: [`quartz-community/recent-notes`](https://github.com/quartz-community/recent-notes)
|
||||||
|
|||||||
@ -4,33 +4,70 @@ 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.
|
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.
|
||||||
|
|
||||||
> [!note]
|
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`.
|
||||||
> In the examples below, `Component.` refers to internal layout utilities (imported from `./quartz/components`), while `Plugin.` refers to community plugins (imported from `./.quartz/plugins`). See [[layout]] for more details.
|
|
||||||
|
|
||||||
## `Flex` Component
|
## `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.
|
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.
|
||||||
|
|
||||||
```typescript
|
### YAML Configuration
|
||||||
type FlexConfig = {
|
|
||||||
components: {
|
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:
|
||||||
Component: QuartzComponent
|
|
||||||
grow?: boolean // whether component should grow to fill space
|
```yaml title="quartz.config.yaml"
|
||||||
shrink?: boolean // whether component should shrink if needed
|
plugins:
|
||||||
basis?: string // initial main size of the component
|
- source: github:quartz-community/search
|
||||||
order?: number // order in flex container
|
enabled: true
|
||||||
align?: "start" | "end" | "center" | "stretch" // cross-axis alignment
|
layout:
|
||||||
justify?: "start" | "end" | "center" | "between" | "around" // main-axis alignment
|
position: left
|
||||||
}[]
|
priority: 20
|
||||||
direction?: "row" | "row-reverse" | "column" | "column-reverse"
|
group: toolbar
|
||||||
wrap?: "nowrap" | "wrap" | "wrap-reverse"
|
groupOptions:
|
||||||
gap?: string
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
### Example Usage
|
The `groupOptions` field on each plugin entry supports the following flex item properties:
|
||||||
|
|
||||||
```typescript
|
| 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({
|
Component.Flex({
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
@ -44,8 +81,25 @@ Component.Flex({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
type FlexConfig = {
|
||||||
|
components: {
|
||||||
|
Component: QuartzComponent
|
||||||
|
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"
|
||||||
|
gap?: string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
> [!note] Overriding behavior
|
> [!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
|
> ```scss
|
||||||
> .flex-component {
|
> .flex-component {
|
||||||
@ -53,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())
|
Component.MobileOnly(Component.Spacer())
|
||||||
```
|
```
|
||||||
|
|
||||||
## `DesktopOnly` Component
|
```ts title="quartz.ts (override)"
|
||||||
|
|
||||||
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(Plugin.TableOfContents())
|
Component.DesktopOnly(Plugin.TableOfContents())
|
||||||
```
|
```
|
||||||
|
|
||||||
## `ConditionalRender` Component
|
## `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
|
```typescript
|
||||||
type ConditionalRenderConfig = {
|
type ConditionalRenderConfig = {
|
||||||
@ -84,22 +190,5 @@ type ConditionalRenderConfig = {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Example Usage
|
> [!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.
|
||||||
```typescript
|
|
||||||
Component.ConditionalRender({
|
|
||||||
component: Plugin.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: Plugin.Breadcrumbs(),
|
|
||||||
condition: (page) => page.fileData.slug !== "index",
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
The example above would hide breadcrumbs on the root `index.md` page.
|
|
||||||
|
|||||||
102
docs/layout.md
102
docs/layout.md
@ -4,7 +4,7 @@ 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.
|
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.layout.ts` using a `defaults` + `byPageType` structure.
|
In v5, the layout is defined in `quartz.config.yaml` using a `defaults` + `byPageType` structure.
|
||||||
|
|
||||||
- `defaults` contains layout components shared across ALL page types (head, header, afterBody, footer).
|
- `defaults` contains layout components shared across ALL page types (head, header, afterBody, footer).
|
||||||
- `byPageType` contains per-page-type overrides (content, folder, tag, 404) for beforeBody, left, and right sections.
|
- `byPageType` contains per-page-type overrides (content, folder, tag, 404) for beforeBody, left, and right sections.
|
||||||
@ -38,47 +38,101 @@ These correspond to following parts of the page:
|
|||||||
> 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.
|
> 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 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`.
|
||||||
|
|
||||||
### Configuration
|
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:
|
||||||
|
|
||||||
Layout components are imported from two main sources:
|
```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
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
layout:
|
||||||
import * as Component from "./quartz/components" // internal HOC components
|
groups:
|
||||||
import * as Plugin from "./.quartz/plugins" // community component plugins
|
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: []
|
||||||
```
|
```
|
||||||
|
|
||||||
Internal components (`Component.Head()`, `Component.Spacer()`, `Component.Flex()`, `Component.MobileOnly()`, `Component.DesktopOnly()`, `Component.ConditionalRender()`) are layout utilities. Community component plugins (`Plugin.Explorer()`, `Plugin.Search()`, `Plugin.Darkmode()`, etc.) provide the actual UI features.
|
For advanced layout overrides using TypeScript (e.g. custom component wrappers or conditional logic), you can use the TS override in `quartz.ts`:
|
||||||
|
|
||||||
Here is a simplified example of the layout structure:
|
```ts title="quartz.ts"
|
||||||
|
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
const config = await loadQuartzConfig()
|
||||||
export const layout = {
|
export default config
|
||||||
|
export const layout = await loadQuartzLayout({
|
||||||
defaults: {
|
defaults: {
|
||||||
head: Component.Head(),
|
// override default layout for all page types
|
||||||
header: [],
|
|
||||||
afterBody: [],
|
|
||||||
footer: Plugin.Footer({ links: { ... } }),
|
|
||||||
},
|
},
|
||||||
byPageType: {
|
byPageType: {
|
||||||
content: {
|
content: {
|
||||||
beforeBody: [Plugin.ArticleTitle(), Plugin.ContentMeta(), Plugin.TagList()],
|
// override layout for content pages only
|
||||||
left: [Plugin.PageTitle(), Plugin.Search(), Plugin.Explorer()],
|
|
||||||
right: [Plugin.Graph(), Plugin.TableOfContents(), Plugin.Backlinks()],
|
|
||||||
},
|
},
|
||||||
folder: {
|
folder: {
|
||||||
beforeBody: [Plugin.Breadcrumbs(), Plugin.ArticleTitle()],
|
// override layout for folder pages only
|
||||||
left: [Plugin.PageTitle(), Plugin.Search(), Plugin.Explorer()],
|
|
||||||
right: [],
|
|
||||||
},
|
},
|
||||||
tag: { ... },
|
|
||||||
"404": { beforeBody: [], left: [], right: [] },
|
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Fields defined in `defaults` can be overridden by specific entries in `byPageType`.
|
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>` and imported from `.quartz/plugins`. See [[layout-components]] for built-in layout utilities (Flex, MobileOnly, DesktopOnly, etc.).
|
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.
|
You can also checkout the guide on [[creating components]] if you're interested in further customizing the behaviour of Quartz.
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ List the key architectural changes:
|
|||||||
|
|
||||||
- **Plugin system**: Plugins are now standalone Git repositories, installed via `npx quartz plugin add`
|
- **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`)
|
- **Import pattern**: Community plugins use `ExternalPlugin.X()` (from `.quartz/plugins`) instead of `Plugin.X()` (from `./quartz/plugins`)
|
||||||
- **Layout structure**: `quartz.layout.ts` now uses `defaults` + `byPageType` instead of `sharedPageComponents` + per-layout objects
|
- **Layout structure**: `quartz.config.yaml` now uses `defaults` + `byPageType` instead of `sharedPageComponents` + per-layout objects
|
||||||
- **Page Types**: A new plugin category for page rendering (content, folder, tag pages)
|
- **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`)
|
- **Component references**: In layout files, community components use `Plugin.X()` (from `.quartz/plugins`) instead of `Component.X()` (from `./quartz/components`)
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ npx quartz plugin add github:quartz-community/roam
|
|||||||
npx quartz plugin add github:quartz-community/explicit-publish
|
npx quartz plugin add github:quartz-community/explicit-publish
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Update quartz.config.ts
|
### 2. Update quartz.config.yaml
|
||||||
|
|
||||||
Show before (v4) and after (v5) comparison:
|
Show before (v4) and after (v5) comparison:
|
||||||
|
|
||||||
@ -99,56 +99,60 @@ plugins: {
|
|||||||
|
|
||||||
**After (v5):**
|
**After (v5):**
|
||||||
|
|
||||||
```ts title="quartz.config.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
import * as Plugin from "./quartz/plugins"
|
plugins:
|
||||||
import * as ExternalPlugin from "./.quartz/plugins"
|
- source: github:quartz-community/note-properties
|
||||||
import { layout } from "./quartz.layout"
|
enabled: true
|
||||||
|
options:
|
||||||
plugins: {
|
delimiters: "---"
|
||||||
transformers: [
|
language: yaml
|
||||||
Plugin.FrontMatter(),
|
order: 5
|
||||||
ExternalPlugin.CreatedModifiedDate({ priority: ["frontmatter", "git", "filesystem"] }),
|
- source: github:quartz-community/created-modified-date
|
||||||
ExternalPlugin.Latex({ renderEngine: "katex" }),
|
enabled: true
|
||||||
],
|
options:
|
||||||
filters: [ExternalPlugin.RemoveDrafts()],
|
priority:
|
||||||
emitters: [
|
- frontmatter
|
||||||
ExternalPlugin.AliasRedirects(),
|
- git
|
||||||
Plugin.ComponentResources(),
|
- filesystem
|
||||||
ExternalPlugin.ContentIndex({ enableSiteMap: true, enableRSS: true }),
|
order: 10
|
||||||
Plugin.Assets(),
|
- source: github:quartz-community/latex
|
||||||
Plugin.Static(),
|
enabled: true
|
||||||
ExternalPlugin.Favicon(),
|
options:
|
||||||
Plugin.PageTypes.PageTypeDispatcher({
|
renderEngine: katex
|
||||||
defaults: layout.defaults,
|
order: 80
|
||||||
byPageType: layout.byPageType,
|
- source: github:quartz-community/remove-draft
|
||||||
}),
|
enabled: true
|
||||||
ExternalPlugin.CustomOgImages(),
|
- source: github:quartz-community/alias-redirects
|
||||||
ExternalPlugin.CNAME(),
|
enabled: true
|
||||||
],
|
- source: github:quartz-community/content-index
|
||||||
pageTypes: [
|
enabled: true
|
||||||
ExternalPlugin.ContentPage(),
|
options:
|
||||||
ExternalPlugin.FolderPage(),
|
enableSiteMap: true
|
||||||
ExternalPlugin.TagPage(),
|
enableRSS: true
|
||||||
Plugin.PageTypes.NotFoundPageType(),
|
- source: github:quartz-community/favicon
|
||||||
],
|
enabled: true
|
||||||
},
|
- source: github:quartz-community/og-image
|
||||||
externalPlugins: [
|
enabled: true
|
||||||
"github:quartz-community/explorer",
|
- source: github:quartz-community/cname
|
||||||
"github:quartz-community/graph",
|
enabled: true
|
||||||
// ... all your community plugins
|
- 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:
|
Key changes:
|
||||||
|
|
||||||
- `Plugin.X()` becomes `ExternalPlugin.X()` for community plugins
|
- Plugins are now referenced by their GitHub source (`github:org/repo`)
|
||||||
- `Plugin.FrontMatter()` stays as `Plugin.X()` (it's internal)
|
- Plugin type (transformer, filter, emitter, pageType) is determined by the plugin's manifest, not by which array you place it in
|
||||||
- `Plugin.ComponentResources()`, `Plugin.Assets()`, `Plugin.Static()` stay internal
|
- Execution order is controlled by the `order` field (lower numbers run first)
|
||||||
- Page-rendering emitters (`ContentPage`, `FolderPage`, `TagPage`, `NotFoundPage`) move to new `pageTypes` array
|
- Each plugin entry has `enabled`, `options`, `order`, and optionally `layout` fields
|
||||||
- `Plugin.PageTypes.PageTypeDispatcher()` replaces individual page emitters in the `emitters` array
|
- Install community plugins with `npx quartz plugin add github:quartz-community/<name>`
|
||||||
- New `externalPlugins` array lists all community plugin repos
|
|
||||||
|
|
||||||
### 3. Update quartz.layout.ts
|
### 3. Update layout configuration
|
||||||
|
|
||||||
Show before (v4) and after (v5):
|
Show before (v4) and after (v5):
|
||||||
|
|
||||||
@ -173,37 +177,92 @@ export const defaultContentPageLayout: PageLayout = {
|
|||||||
|
|
||||||
**After (v5):**
|
**After (v5):**
|
||||||
|
|
||||||
```ts title="quartz.layout.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
import * as Component from "./quartz/components"
|
plugins:
|
||||||
import * as Plugin from "./.quartz/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
|
||||||
|
|
||||||
export const layout = {
|
layout:
|
||||||
defaults: {
|
byPageType:
|
||||||
head: Component.Head(),
|
content: {}
|
||||||
header: [],
|
folder:
|
||||||
afterBody: [],
|
exclude:
|
||||||
footer: Plugin.Footer({ links: { ... } }),
|
- reader-mode
|
||||||
},
|
positions:
|
||||||
byPageType: {
|
right: []
|
||||||
content: {
|
tag:
|
||||||
beforeBody: [Plugin.Breadcrumbs(), Plugin.ArticleTitle(), Plugin.ContentMeta(), Plugin.TagList()],
|
exclude:
|
||||||
left: [Plugin.PageTitle(), Plugin.Search(), Plugin.Darkmode(), Plugin.Explorer()],
|
- reader-mode
|
||||||
right: [Plugin.Graph(), Plugin.TableOfContents(), Plugin.Backlinks()],
|
positions:
|
||||||
},
|
right: []
|
||||||
folder: { ... },
|
"404":
|
||||||
tag: { ... },
|
positions:
|
||||||
"404": { beforeBody: [], left: [], right: [] },
|
beforeBody: []
|
||||||
},
|
left: []
|
||||||
}
|
right: []
|
||||||
```
|
```
|
||||||
|
|
||||||
Key changes:
|
Key changes:
|
||||||
|
|
||||||
- `Component.X()` for community components becomes `Plugin.X()` (imported from `.quartz/plugins`)
|
- Layout position is now a property on each plugin entry (`layout.position`, `layout.priority`)
|
||||||
- `Component.Head()` and other layout utilities stay as `Component.X()` (from `./quartz/components`)
|
- `sharedPageComponents` is gone — all layout is plugin-driven
|
||||||
- `sharedPageComponents` becomes `defaults`
|
- Per-page-type overrides live in the `layout.byPageType` section
|
||||||
- Per-layout objects become entries in `byPageType`
|
- Empty arrays (`[]`) clear a position for that page type
|
||||||
- Each page type (content, folder, tag, 404) gets its own layout override
|
- The `exclude` field removes specific plugins from a page type
|
||||||
|
|
||||||
### 4. Update CI/CD
|
### 4. Update CI/CD
|
||||||
|
|
||||||
@ -212,7 +271,7 @@ Add `npx quartz plugin restore` to your build pipeline, before `npx quartz build
|
|||||||
### 5. Commit and Deploy
|
### 5. Commit and Deploy
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git add quartz.config.ts quartz.layout.ts quartz.lock.json
|
git add quartz.ts quartz.lock.json
|
||||||
git commit -m "chore: migrate to Quartz 5 plugin system"
|
git commit -m "chore: migrate to Quartz 5 plugin system"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -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.
|
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.
|
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.
|
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
|
Most software either confines you to either
|
||||||
|
|||||||
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`
|
||||||
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.
|
||||||
|
|
||||||
|
> [!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`
|
||||||
@ -173,7 +173,7 @@
|
|||||||
{
|
{
|
||||||
"id": "config-options",
|
"id": "config-options",
|
||||||
"type": "text",
|
"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.ts`:\n\n```\nCanvasPage({ defaultFullscreen: false, initialZoom: 1 })\n```",
|
"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,
|
"x": 0,
|
||||||
"y": 1220,
|
"y": 1220,
|
||||||
"width": 560,
|
"width": 560,
|
||||||
|
|||||||
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`
|
||||||
@ -4,7 +4,7 @@ tags:
|
|||||||
- plugin/pageType
|
- plugin/pageType
|
||||||
---
|
---
|
||||||
|
|
||||||
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 is now configured in the `pageTypes` section of `quartz.config.ts`.
|
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 is now configured in the `pageTypes` section of `quartz.config.yaml`.
|
||||||
|
|
||||||
> [!note]
|
> [!note]
|
||||||
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
|
||||||
|
|||||||
@ -16,7 +16,7 @@ This plugin accepts the following configuration options:
|
|||||||
When loading the frontmatter, the value of [[Frontmatter#List]] is used.
|
When loading the frontmatter, the value of [[Frontmatter#List]] is used.
|
||||||
|
|
||||||
> [!warning]
|
> [!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.
|
> 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.
|
||||||
|
|
||||||
|
|||||||
@ -25,22 +25,29 @@ The Custom OG Images emitter plugin generates social media preview images for yo
|
|||||||
|
|
||||||
This plugin accepts the following configuration options:
|
This plugin accepts the following configuration options:
|
||||||
|
|
||||||
```typescript title="quartz.config.ts"
|
```yaml title="quartz.config.yaml"
|
||||||
import { CustomOgImages } from "./quartz/plugins/emitters/ogImage"
|
plugins:
|
||||||
|
- source: github:quartz-community/og-image
|
||||||
|
enabled: true
|
||||||
|
options:
|
||||||
|
colorScheme: lightMode # "lightMode" or "darkMode"
|
||||||
|
width: 1200
|
||||||
|
height: 630
|
||||||
|
excludeRoot: false
|
||||||
|
```
|
||||||
|
|
||||||
const config: QuartzConfig = {
|
For the TS override approach (needed for custom `imageStructure`):
|
||||||
plugins: {
|
|
||||||
emitters: [
|
```ts title="quartz.ts (override)"
|
||||||
CustomOgImages({
|
import { defaultImage } from "./quartz/plugins/emitters/ogImage"
|
||||||
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)
|
CustomOgImages({
|
||||||
height: 630, // height to generate with (in pixels)
|
colorScheme: "lightMode",
|
||||||
excludeRoot: false, // wether to exclude "/" index path to be excluded from auto generated images (false = use auto, true = use default og image)
|
width: 1200,
|
||||||
imageStructure: defaultImage, // custom image component to use
|
height: 630,
|
||||||
}),
|
excludeRoot: false,
|
||||||
],
|
imageStructure: defaultImage, // custom JSX component — requires TS
|
||||||
},
|
})
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration Options
|
### Configuration Options
|
||||||
@ -76,7 +83,7 @@ You can fully customize how the images being generated look by passing your own
|
|||||||
|
|
||||||
### Fonts
|
### 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:
|
An example of a component using the header font could look like this:
|
||||||
|
|
||||||
|
|||||||
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`
|
||||||
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`
|
||||||
19
docs/plugins/Spacer.md
Normal file
19
docs/plugins/Spacer.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
title: Spacer
|
||||||
|
tags:
|
||||||
|
- plugin/component
|
||||||
|
---
|
||||||
|
|
||||||
|
This plugin renders a flexible spacer element that pushes adjacent components apart within a layout group. It uses CSS `flex: 2 1 auto` to fill available space, making it useful for spacing out items in toolbars or sidebars (for example, separating the search bar from the darkmode toggle in the left sidebar toolbar).
|
||||||
|
|
||||||
|
> [!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.Spacer()`.
|
||||||
|
- Source: [`quartz-community/spacer`](https://github.com/quartz-community/spacer)
|
||||||
|
- Install: `npx quartz plugin add github:quartz-community/spacer`
|
||||||
@ -17,7 +17,7 @@ This plugin accepts the following configuration options:
|
|||||||
- `collapseByDefault`: If `true`, the TOC will start in a collapsed state. Default is `false`.
|
- `collapseByDefault`: If `true`, the TOC will start in a collapsed state. Default is `false`.
|
||||||
|
|
||||||
> [!warning]
|
> [!warning]
|
||||||
> This plugin needs the `Plugin.TableOfContents` component in `quartz.layout.ts` to determine where to display the TOC. Without it, nothing will be displayed. They should always be added or removed together.
|
> This plugin needs the `Plugin.TableOfContents` component in `quartz.config.yaml` to determine where to display the TOC. Without it, nothing will be displayed. They should always be added or removed together.
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
|
|||||||
19
docs/plugins/TagList.md
Normal file
19
docs/plugins/TagList.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
title: TagList
|
||||||
|
tags:
|
||||||
|
- plugin/component
|
||||||
|
---
|
||||||
|
|
||||||
|
This plugin renders the page's tags as a list of clickable links. Each tag links to its corresponding [[TagPage|tag page]], making it easy for readers to browse related content by topic.
|
||||||
|
|
||||||
|
> [!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.TagList()`.
|
||||||
|
- Source: [`quartz-community/tag-list`](https://github.com/quartz-community/tag-list)
|
||||||
|
- Install: `npx quartz plugin add github:quartz-community/tag-list`
|
||||||
@ -1,3 +1,81 @@
|
|||||||
---
|
---
|
||||||
title: Plugins
|
title: Plugins
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Quartz's functionality is provided by a collection of first-party community plugins. Each plugin can be enabled, disabled, and configured via `quartz.config.yaml`. See [[configuration#Plugins|Configuration]] for details on how to manage plugins.
|
||||||
|
|
||||||
|
## Plugin types
|
||||||
|
|
||||||
|
Quartz plugins fall into several categories:
|
||||||
|
|
||||||
|
- **Transformers** process content during the build, e.g. parsing frontmatter, highlighting syntax, or resolving links.
|
||||||
|
- **Filters** decide which content files to include or exclude from the output.
|
||||||
|
- **Page Types** generate HTML pages — one per content file, folder, tag, canvas, or bases view.
|
||||||
|
- **Components** render UI elements in the page layout (sidebars, headers, footers, etc.).
|
||||||
|
|
||||||
|
## First-party plugins
|
||||||
|
|
||||||
|
### Transformers
|
||||||
|
|
||||||
|
| Plugin | Repository | Enabled | Required | Description |
|
||||||
|
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- | :-----: | :------: | ---------------------------------------------------------- |
|
||||||
|
| [[Frontmatter\|Note Properties]] | [`quartz-community/note-properties`](https://github.com/quartz-community/note-properties) | ✅ | ✅ | Parses frontmatter and displays note properties. |
|
||||||
|
| [[CreatedModifiedDate]] | [`quartz-community/created-modified-date`](https://github.com/quartz-community/created-modified-date) | ✅ | ❌ | Determines creation and modification dates. |
|
||||||
|
| [[SyntaxHighlighting]] | [`quartz-community/syntax-highlighting`](https://github.com/quartz-community/syntax-highlighting) | ✅ | ❌ | Syntax highlighting for code blocks. |
|
||||||
|
| [[ObsidianFlavoredMarkdown]] | [`quartz-community/obsidian-flavored-markdown`](https://github.com/quartz-community/obsidian-flavored-markdown) | ✅ | ❌ | Obsidian-specific Markdown extensions. |
|
||||||
|
| [[GitHubFlavoredMarkdown]] | [`quartz-community/github-flavored-markdown`](https://github.com/quartz-community/github-flavored-markdown) | ✅ | ❌ | GitHub Flavored Markdown support. |
|
||||||
|
| [[TableOfContents]] | [`quartz-community/table-of-contents`](https://github.com/quartz-community/table-of-contents) | ✅ | ❌ | Generates table of contents data from headings. |
|
||||||
|
| [[CrawlLinks]] | [`quartz-community/crawl-links`](https://github.com/quartz-community/crawl-links) | ✅ | ⚠️ | Parses and resolves links. Removing it is not recommended. |
|
||||||
|
| [[Description]] | [`quartz-community/description`](https://github.com/quartz-community/description) | ✅ | ❌ | Generates page descriptions for metadata. |
|
||||||
|
| [[Latex]] | [`quartz-community/latex`](https://github.com/quartz-community/latex) | ✅ | ❌ | Renders LaTeX math expressions. |
|
||||||
|
| [[Citations]] | [`quartz-community/citations`](https://github.com/quartz-community/citations) | ❌ | ❌ | Academic citation support via BibTeX. |
|
||||||
|
| [[HardLineBreaks]] | [`quartz-community/hard-line-breaks`](https://github.com/quartz-community/hard-line-breaks) | ❌ | ❌ | Treats single newlines as hard line breaks. |
|
||||||
|
| [[OxHugoFlavoredMarkdown]] | [`quartz-community/ox-hugo`](https://github.com/quartz-community/ox-hugo) | ❌ | ❌ | ox-hugo Markdown compatibility. |
|
||||||
|
| [[RoamFlavoredMarkdown]] | [`quartz-community/roam`](https://github.com/quartz-community/roam) | ❌ | ❌ | Roam Research Markdown compatibility. |
|
||||||
|
|
||||||
|
### Filters
|
||||||
|
|
||||||
|
| Plugin | Repository | Enabled | Required | Description |
|
||||||
|
| ------------------- | ------------------------------------------------------------------------------------------- | :-----: | :------: | --------------------------------------- |
|
||||||
|
| [[RemoveDrafts]] | [`quartz-community/remove-draft`](https://github.com/quartz-community/remove-draft) | ✅ | ❌ | Filters out pages marked as drafts. |
|
||||||
|
| [[ExplicitPublish]] | [`quartz-community/explicit-publish`](https://github.com/quartz-community/explicit-publish) | ❌ | ❌ | Only publishes pages explicitly marked. |
|
||||||
|
|
||||||
|
### Page Types
|
||||||
|
|
||||||
|
| Plugin | Repository | Enabled | Required | Description |
|
||||||
|
| --------------- | ----------------------------------------------------------------------------------- | :-----: | :------: | ----------------------------------------------- |
|
||||||
|
| [[ContentPage]] | [`quartz-community/content-page`](https://github.com/quartz-community/content-page) | ✅ | ❌ | Generates HTML pages for Markdown content. |
|
||||||
|
| [[FolderPage]] | [`quartz-community/folder-page`](https://github.com/quartz-community/folder-page) | ✅ | ❌ | Generates folder listing pages. |
|
||||||
|
| [[TagPage]] | [`quartz-community/tag-page`](https://github.com/quartz-community/tag-page) | ✅ | ❌ | Generates tag listing pages. |
|
||||||
|
| [[CanvasPage]] | [`quartz-community/canvas-page`](https://github.com/quartz-community/canvas-page) | ✅ | ❌ | Renders JSON Canvas files as interactive pages. |
|
||||||
|
| [[BasesPage]] | [`quartz-community/bases-page`](https://github.com/quartz-community/bases-page) | ✅ | ❌ | Renders Obsidian Bases files as database views. |
|
||||||
|
|
||||||
|
### Emitters
|
||||||
|
|
||||||
|
| Plugin | Repository | Enabled | Required | Description |
|
||||||
|
| ---------------------------- | ----------------------------------------------------------------------------------------- | :-----: | :------: | ----------------------------------------------- |
|
||||||
|
| [[AliasRedirects]] | [`quartz-community/alias-redirects`](https://github.com/quartz-community/alias-redirects) | ✅ | ❌ | Generates redirect pages for aliases. |
|
||||||
|
| [[ContentIndex]] | [`quartz-community/content-index`](https://github.com/quartz-community/content-index) | ✅ | ❌ | Generates sitemap, RSS feed, and content index. |
|
||||||
|
| [[Favicon]] | [`quartz-community/favicon`](https://github.com/quartz-community/favicon) | ✅ | ❌ | Emits the site favicon. |
|
||||||
|
| [[CustomOgImages\|OG Image]] | [`quartz-community/og-image`](https://github.com/quartz-community/og-image) | ✅ | ❌ | Generates Open Graph social preview images. |
|
||||||
|
| [[CNAME]] | [`quartz-community/cname`](https://github.com/quartz-community/cname) | ✅ | ❌ | Emits a CNAME file for custom domains. |
|
||||||
|
|
||||||
|
### Components
|
||||||
|
|
||||||
|
| Plugin | Repository | Enabled | Required | Description |
|
||||||
|
| ------------------------------ | ------------------------------------------------------------------------------------- | :-----: | :------: | ------------------------------------------- |
|
||||||
|
| [[ArticleTitle]] | [`quartz-community/article-title`](https://github.com/quartz-community/article-title) | ✅ | ❌ | Renders the article title as an h1 heading. |
|
||||||
|
| [[ContentMeta]] | [`quartz-community/content-meta`](https://github.com/quartz-community/content-meta) | ✅ | ❌ | Displays creation date and reading time. |
|
||||||
|
| [[TagList]] | [`quartz-community/tag-list`](https://github.com/quartz-community/tag-list) | ✅ | ❌ | Renders tags as clickable links. |
|
||||||
|
| [[PageTitle]] | [`quartz-community/page-title`](https://github.com/quartz-community/page-title) | ✅ | ❌ | Renders the site title as a home link. |
|
||||||
|
| [[darkmode\|Darkmode]] | [`quartz-community/darkmode`](https://github.com/quartz-community/darkmode) | ✅ | ❌ | Toggle between light and dark themes. |
|
||||||
|
| [[reader mode\|Reader Mode]] | [`quartz-community/reader-mode`](https://github.com/quartz-community/reader-mode) | ✅ | ❌ | Distraction-free reading mode toggle. |
|
||||||
|
| [[explorer\|Explorer]] | [`quartz-community/explorer`](https://github.com/quartz-community/explorer) | ✅ | ❌ | File tree explorer sidebar. |
|
||||||
|
| [[graph view\|Graph View]] | [`quartz-community/graph`](https://github.com/quartz-community/graph) | ✅ | ❌ | Interactive link graph visualization. |
|
||||||
|
| [[full-text search\|Search]] | [`quartz-community/search`](https://github.com/quartz-community/search) | ✅ | ❌ | Full-text search functionality. |
|
||||||
|
| [[backlinks\|Backlinks]] | [`quartz-community/backlinks`](https://github.com/quartz-community/backlinks) | ✅ | ❌ | Shows pages that link to the current page. |
|
||||||
|
| [[breadcrumbs\|Breadcrumbs]] | [`quartz-community/breadcrumbs`](https://github.com/quartz-community/breadcrumbs) | ✅ | ❌ | Breadcrumb navigation trail. |
|
||||||
|
| [[comments\|Comments]] | [`quartz-community/comments`](https://github.com/quartz-community/comments) | ❌ | ❌ | Comment system integration (Giscus, etc.). |
|
||||||
|
| [[Footer]] | [`quartz-community/footer`](https://github.com/quartz-community/footer) | ✅ | ❌ | Page footer with configurable links. |
|
||||||
|
| [[recent notes\|Recent Notes]] | [`quartz-community/recent-notes`](https://github.com/quartz-community/recent-notes) | ❌ | ❌ | Displays a list of recently modified notes. |
|
||||||
|
| [[Spacer]] | [`quartz-community/spacer`](https://github.com/quartz-community/spacer) | ✅ | ❌ | Flexible spacer for layout groups. |
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
import { loadQuartzConfig } from "./quartz/plugins/loader/config-loader"
|
|
||||||
export default await loadQuartzConfig()
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
import { loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
|
||||||
export const layout = await loadQuartzLayout()
|
|
||||||
5
quartz.ts
Normal file
5
quartz.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"
|
||||||
|
|
||||||
|
const config = await loadQuartzConfig()
|
||||||
|
export default config
|
||||||
|
export const layout = await loadQuartzLayout()
|
||||||
@ -8,7 +8,7 @@ import { styleText } from "util"
|
|||||||
import { parseMarkdown } from "./processors/parse"
|
import { parseMarkdown } from "./processors/parse"
|
||||||
import { filterContent } from "./processors/filter"
|
import { filterContent } from "./processors/filter"
|
||||||
import { emitContent } from "./processors/emit"
|
import { emitContent } from "./processors/emit"
|
||||||
import cfg from "../quartz.config"
|
import cfg from "../quartz"
|
||||||
import { FilePath, joinSegments, slugifyFilePath } from "./util/path"
|
import { FilePath, joinSegments, slugifyFilePath } from "./util/path"
|
||||||
import chokidar from "chokidar"
|
import chokidar from "chokidar"
|
||||||
import { ProcessedContent } from "./plugins/vfile"
|
import { ProcessedContent } from "./plugins/vfile"
|
||||||
|
|||||||
@ -24,7 +24,13 @@ import {
|
|||||||
stashContentFolder,
|
stashContentFolder,
|
||||||
} from "./helpers.js"
|
} from "./helpers.js"
|
||||||
import { handlePluginRestore, handlePluginCheck } from "./plugin-git-handlers.js"
|
import { handlePluginRestore, handlePluginCheck } from "./plugin-git-handlers.js"
|
||||||
import { configExists, createConfigFromDefault } from "./plugin-data.js"
|
import {
|
||||||
|
configExists,
|
||||||
|
createConfigFromDefault,
|
||||||
|
readPluginsJson,
|
||||||
|
writePluginsJson,
|
||||||
|
extractPluginName,
|
||||||
|
} from "./plugin-data.js"
|
||||||
import {
|
import {
|
||||||
UPSTREAM_NAME,
|
UPSTREAM_NAME,
|
||||||
QUARTZ_SOURCE_BRANCH,
|
QUARTZ_SOURCE_BRANCH,
|
||||||
@ -189,7 +195,7 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
|
|||||||
// get a preferred link resolution strategy
|
// get a preferred link resolution strategy
|
||||||
linkResolutionStrategy = exitIfCancel(
|
linkResolutionStrategy = exitIfCancel(
|
||||||
await select({
|
await select({
|
||||||
message: `Choose how Quartz should resolve links in your content. This should match Obsidian's link format. You can change this later in \`quartz.config.ts\`.`,
|
message: `Choose how Quartz should resolve links in your content. This should match Obsidian's link format. You can change this later in \`quartz.config.yaml\`.`,
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: "shortest",
|
value: "shortest",
|
||||||
@ -209,14 +215,20 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// now, do config changes
|
// Update markdownLinkResolution in the crawl-links plugin options via YAML config
|
||||||
const configFilePath = path.join(cwd, "quartz.config.ts")
|
const json = readPluginsJson()
|
||||||
let configContent = await fs.promises.readFile(configFilePath, { encoding: "utf-8" })
|
if (json?.plugins) {
|
||||||
configContent = configContent.replace(
|
const crawlLinksIndex = json.plugins.findIndex(
|
||||||
/markdownLinkResolution: '(.+)'/,
|
(p) => extractPluginName(p.source) === "crawl-links",
|
||||||
`markdownLinkResolution: '${linkResolutionStrategy}'`,
|
)
|
||||||
)
|
if (crawlLinksIndex !== -1) {
|
||||||
await fs.promises.writeFile(configFilePath, configContent)
|
json.plugins[crawlLinksIndex].options = {
|
||||||
|
...json.plugins[crawlLinksIndex].options,
|
||||||
|
markdownLinkResolution: linkResolutionStrategy,
|
||||||
|
}
|
||||||
|
writePluginsJson(json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!configExists()) {
|
if (!configExists()) {
|
||||||
createConfigFromDefault()
|
createConfigFromDefault()
|
||||||
|
|||||||
@ -5,8 +5,7 @@ import { styleText } from "util"
|
|||||||
import YAML from "yaml"
|
import YAML from "yaml"
|
||||||
|
|
||||||
const CWD = process.cwd()
|
const CWD = process.cwd()
|
||||||
const CONFIG_PATH = path.join(CWD, "quartz.config.ts")
|
const QUARTZ_TS_PATH = path.join(CWD, "quartz.ts")
|
||||||
const LAYOUT_PATH = path.join(CWD, "quartz.layout.ts")
|
|
||||||
const CONFIG_YAML_PATH = path.join(CWD, "quartz.config.yaml")
|
const CONFIG_YAML_PATH = path.join(CWD, "quartz.config.yaml")
|
||||||
const DEFAULT_CONFIG_YAML_PATH = path.join(CWD, "quartz.config.default.yaml")
|
const DEFAULT_CONFIG_YAML_PATH = path.join(CWD, "quartz.config.default.yaml")
|
||||||
const LEGACY_DEFAULT_JSON_PATH = path.join(CWD, "quartz.plugins.default.json")
|
const LEGACY_DEFAULT_JSON_PATH = path.join(CWD, "quartz.plugins.default.json")
|
||||||
@ -30,8 +29,8 @@ function hasTsx() {
|
|||||||
|
|
||||||
function extractWithTsx() {
|
function extractWithTsx() {
|
||||||
const script = `
|
const script = `
|
||||||
const { default: config } = await import("./quartz.config.ts")
|
const { default: config } = await import("./quartz.ts")
|
||||||
const { layout } = await import("./quartz.layout.ts")
|
const { layout } = await import("./quartz.ts")
|
||||||
const result = {
|
const result = {
|
||||||
configuration: config?.configuration ?? null,
|
configuration: config?.configuration ?? null,
|
||||||
layoutInfo: {
|
layoutInfo: {
|
||||||
@ -114,8 +113,8 @@ function buildPluginEntry(name, entry) {
|
|||||||
export async function handleMigrate() {
|
export async function handleMigrate() {
|
||||||
console.log(styleText("cyan", "Migrating Quartz configuration..."))
|
console.log(styleText("cyan", "Migrating Quartz configuration..."))
|
||||||
|
|
||||||
if (!fs.existsSync(CONFIG_PATH)) {
|
if (!fs.existsSync(QUARTZ_TS_PATH)) {
|
||||||
console.log(styleText("red", "✗ quartz.config.ts not found. Aborting migration."))
|
console.log(styleText("red", "✗ quartz.ts not found. Aborting migration."))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,19 +174,17 @@ export async function handleMigrate() {
|
|||||||
const header = "# yaml-language-server: $schema=./quartz/plugins/quartz-plugins.schema.json\n"
|
const header = "# yaml-language-server: $schema=./quartz/plugins/quartz-plugins.schema.json\n"
|
||||||
fs.writeFileSync(CONFIG_YAML_PATH, header + YAML.stringify(outputJson, { lineWidth: 120 }))
|
fs.writeFileSync(CONFIG_YAML_PATH, header + YAML.stringify(outputJson, { lineWidth: 120 }))
|
||||||
|
|
||||||
const configTemplate =
|
const quartzTsTemplate =
|
||||||
'import { loadQuartzConfig } from "./quartz/plugins/loader/config-loader"\n' +
|
'import { loadQuartzConfig, loadQuartzLayout } from "./quartz/plugins/loader/config-loader"\n' +
|
||||||
"export default await loadQuartzConfig()\n"
|
"\n" +
|
||||||
const layoutTemplate =
|
"const config = await loadQuartzConfig()\n" +
|
||||||
'import { loadQuartzLayout } from "./quartz/plugins/loader/config-loader"\n' +
|
"export default config\n" +
|
||||||
"export const layout = await loadQuartzLayout()\n"
|
"export const layout = await loadQuartzLayout()\n"
|
||||||
|
|
||||||
fs.writeFileSync(CONFIG_PATH, configTemplate)
|
fs.writeFileSync(QUARTZ_TS_PATH, quartzTsTemplate)
|
||||||
fs.writeFileSync(LAYOUT_PATH, layoutTemplate)
|
|
||||||
|
|
||||||
console.log(styleText("green", "✓ Created quartz.config.yaml"))
|
console.log(styleText("green", "✓ Created quartz.config.yaml"))
|
||||||
console.log(styleText("green", "✓ Replaced quartz.config.ts"))
|
console.log(styleText("green", "✓ Replaced quartz.ts"))
|
||||||
console.log(styleText("green", "✓ Replaced quartz.layout.ts"))
|
|
||||||
console.log()
|
console.log()
|
||||||
console.log(styleText("yellow", "⚠ Verify plugin options in quartz.config.yaml"))
|
console.log(styleText("yellow", "⚠ Verify plugin options in quartz.config.yaml"))
|
||||||
console.log(styleText("gray", `Plugins migrated: ${plugins.length}`))
|
console.log(styleText("gray", `Plugins migrated: ${plugins.length}`))
|
||||||
|
|||||||
@ -23,7 +23,7 @@ export async function handlePluginInstall(packageNames) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(styleText("green", "✓ Plugins installed successfully"))
|
console.log(styleText("green", "✓ Plugins installed successfully"))
|
||||||
console.log("\nAdd them to your quartz.config.ts:")
|
console.log("\nAdd them to your quartz.config.yaml:")
|
||||||
|
|
||||||
for (const pkg of packageNames) {
|
for (const pkg of packageNames) {
|
||||||
console.log(` import { Plugin } from "${pkg}"`)
|
console.log(` import { Plugin } from "${pkg}"`)
|
||||||
@ -126,5 +126,5 @@ export async function handlePluginUninstall(packageNames) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(styleText("green", "✓ Plugins uninstalled successfully"))
|
console.log(styleText("green", "✓ Plugins uninstalled successfully"))
|
||||||
console.log(styleText("yellow", "Don't forget to remove them from your quartz.config.ts!"))
|
console.log(styleText("yellow", "Don't forget to remove them from your quartz.config.yaml!"))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export type ValidDateType = keyof Required<QuartzPluginData>["dates"]
|
|||||||
export function getDate(cfg: GlobalConfiguration, data: QuartzPluginData): Date | undefined {
|
export function getDate(cfg: GlobalConfiguration, data: QuartzPluginData): Date | undefined {
|
||||||
if (!cfg.defaultDateType) {
|
if (!cfg.defaultDateType) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Field 'defaultDateType' was not set in the configuration object of quartz.config.ts. See https://quartz.jzhao.xyz/configuration#general-configuration for more details.`,
|
`Field 'defaultDateType' was not set in the configuration object of quartz.config.yaml. See https://quartz.jzhao.xyz/configuration#general-configuration for more details.`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return data.dates?.[cfg.defaultDateType]
|
return data.dates?.[cfg.defaultDateType]
|
||||||
|
|||||||
@ -201,16 +201,21 @@ async function getManifest(source: string): Promise<PluginManifest | null> {
|
|||||||
return (await readManifestFromPackageJson(source)) ?? (await resolvePluginManifest(source))
|
return (await readManifestFromPackageJson(source)) ?? (await resolvePluginManifest(source))
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadQuartzConfig(): Promise<QuartzConfig> {
|
export async function loadQuartzConfig(
|
||||||
|
configOverrides?: Partial<GlobalConfiguration>,
|
||||||
|
): Promise<QuartzConfig> {
|
||||||
const json = readPluginsJson()
|
const json = readPluginsJson()
|
||||||
|
|
||||||
if (!json) {
|
if (!json) {
|
||||||
// Fallback: import old-style config directly
|
// Fallback: import old-style config directly
|
||||||
const oldConfig = await import("../../../quartz.config")
|
const oldConfig = await import("../../../quartz")
|
||||||
return oldConfig.default
|
return oldConfig.default
|
||||||
}
|
}
|
||||||
|
|
||||||
const configuration = json.configuration as unknown as GlobalConfiguration
|
const configuration = {
|
||||||
|
...(json.configuration as unknown as GlobalConfiguration),
|
||||||
|
...configOverrides,
|
||||||
|
}
|
||||||
|
|
||||||
const enabledEntries = json.plugins.filter((e) => e.enabled)
|
const enabledEntries = json.plugins.filter((e) => e.enabled)
|
||||||
const manifests = new Map<string, PluginManifest>()
|
const manifests = new Map<string, PluginManifest>()
|
||||||
@ -486,7 +491,10 @@ function detectCategoryFromModule(module: unknown): ProcessingCategory | null {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadQuartzLayout(): Promise<{
|
export async function loadQuartzLayout(layoutOverrides?: {
|
||||||
|
defaults?: Partial<FullPageLayout>
|
||||||
|
byPageType?: Record<string, Partial<FullPageLayout>>
|
||||||
|
}): Promise<{
|
||||||
defaults: Partial<FullPageLayout>
|
defaults: Partial<FullPageLayout>
|
||||||
byPageType: Record<string, Partial<FullPageLayout>>
|
byPageType: Record<string, Partial<FullPageLayout>>
|
||||||
}> {
|
}> {
|
||||||
@ -494,7 +502,7 @@ export async function loadQuartzLayout(): Promise<{
|
|||||||
|
|
||||||
if (!json) {
|
if (!json) {
|
||||||
// Fallback: import old-style layout directly
|
// Fallback: import old-style layout directly
|
||||||
const oldLayout = await import("../../../quartz.layout")
|
const oldLayout = await import("../../../quartz")
|
||||||
return oldLayout.layout
|
return oldLayout.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,7 +587,15 @@ export async function loadQuartzLayout(): Promise<{
|
|||||||
if (footer && !pt.footer) pt.footer = footer
|
if (footer && !pt.footer) pt.footer = footer
|
||||||
}
|
}
|
||||||
|
|
||||||
return { defaults: defaultLayout, byPageType }
|
const mergedDefaults = { ...defaultLayout, ...layoutOverrides?.defaults }
|
||||||
|
const mergedByPageType = { ...byPageType }
|
||||||
|
if (layoutOverrides?.byPageType) {
|
||||||
|
for (const [pageType, overrideLayout] of Object.entries(layoutOverrides.byPageType)) {
|
||||||
|
mergedByPageType[pageType] = { ...mergedByPageType[pageType], ...overrideLayout }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { defaults: mergedDefaults, byPageType: mergedByPageType }
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildLayoutForEntries(
|
function buildLayoutForEntries(
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import { installPlugins, parsePluginSource } from "./gitLoader.js"
|
import { installPlugins, parsePluginSource } from "./gitLoader.js"
|
||||||
import config from "../../../quartz.config.js"
|
import config from "../../../quartz.js"
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const quartzConfig: any = config
|
const quartzConfig: any = config
|
||||||
|
|||||||
@ -108,7 +108,7 @@ export interface QuartzPageTypePluginInstance {
|
|||||||
// Community plugins use a differently-branded FullSlug in their PageMatcher,
|
// Community plugins use a differently-branded FullSlug in their PageMatcher,
|
||||||
// making them incompatible with the internal PageMatcher under strict
|
// making them incompatible with the internal PageMatcher under strict
|
||||||
// function-parameter contravariance. This wider entry type avoids forcing
|
// function-parameter contravariance. This wider entry type avoids forcing
|
||||||
// casts in quartz.config.ts while the dispatcher safely calls match/generate
|
// casts in quartz.ts while the dispatcher safely calls match/generate
|
||||||
// with the correct arguments at runtime.
|
// with the correct arguments at runtime.
|
||||||
export interface PageTypePluginEntry {
|
export interface PageTypePluginEntry {
|
||||||
name: string
|
name: string
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import sourceMapSupport from "source-map-support"
|
import sourceMapSupport from "source-map-support"
|
||||||
sourceMapSupport.install(options)
|
sourceMapSupport.install(options)
|
||||||
import cfg from "../quartz.config"
|
import cfg from "../quartz"
|
||||||
import { BuildCtx, WorkerSerializableBuildCtx } from "./util/ctx"
|
import { BuildCtx, WorkerSerializableBuildCtx } from "./util/ctx"
|
||||||
import { FilePath } from "./util/path"
|
import { FilePath } from "./util/path"
|
||||||
import {
|
import {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user