Quartz 4 custom plugins: filters en transformers

Definitie

Quartz 4 heeft een plugin-systeem met drie typen: transformers (markdown verwerken), filters (bepalen welke pagina’s worden gepubliceerd) en emitters (outputbestanden genereren). Eigen plugins schrijf je als TypeScript-bestanden in quartz/plugins/ en registreer je in quartz.config.ts.

Context

Bij het opzetten van kennisbank-web (Quartz 4 build van ~/KennisBank/02-wiki/) was een filter nodig die artikelen met status: concept uit de publieke build houdt. Quartz heeft alleen RemoveDrafts als ingebouwde filter (op draft: true frontmatter). Een eigen filter was de minimaalste oplossing: een nieuw TypeScript-bestand, een export in de index, en een regel in de config.

Kernpunten

Filterinterface

Een filter plugin heeft de vorm:

import { QuartzFilterPlugin } from "../types"
 
export const MijnFilter: QuartzFilterPlugin<{}> = () => ({
  name: "MijnFilter",
  shouldPublish(_ctx, [_tree, vfile]) {
    // return true om te publiceren, false om uit te sluiten
    const waarde = vfile.data?.frontmatter?.veldnaam ?? ""
    return waarde !== "uitgeslotenwaarde"
  },
})

vfile.data?.frontmatter geeft toegang tot alle YAML-frontmatter van het markdown-bestand. Gebruik de nullish coalescing operator (??) voor een veilige fallback.

ExcludeConcept: concreet voorbeeld

// quartz/plugins/filters/excludeConcept.ts
import { QuartzFilterPlugin } from "../types"
 
export const ExcludeConcept: QuartzFilterPlugin<{}> = () => ({
  name: "ExcludeConcept",
  shouldPublish(_ctx, [_tree, vfile]) {
    const status: string = vfile.data?.frontmatter?.status ?? ""
    return status !== "concept"
  },
})

Logica: alles met status: concept wordt gefilterd, de rest (actief, archief, leeg) wordt gepubliceerd.

Registratie in drie stappen

Stap 1: Bestand aanmaken in quartz/plugins/filters/mijnfilter.ts

Stap 2: Export toevoegen aan quartz/plugins/filters/index.ts:

export { ExcludeConcept } from "./excludeConcept"

Stap 3: Plugin registreren in quartz.config.ts onder plugins.filters:

filters: [Plugin.RemoveDrafts(), Plugin.ExcludeConcept()],

Filters zijn stapelbaar. RemoveDrafts en ExcludeConcept kunnen naast elkaar staan.

Build-verificatie

De Quartz build-output bevestigt of de filter werkt:

Filtered out 2 files in 103μs

Als het getal klopt met het aantal verwachte concept-artikelen, werkt de filter correct.

Voor een KennisBank/Quartz-combinatie is een symlink de eenvoudigste sync-methode:

ln -s ~/KennisBank/02-wiki ~/Claude/projects/kennisbank-web/content

Quartz volgt symlinks standaard. Wijzigingen in 02-wiki/ zijn direct zichtbaar in de build zonder sync-script. Dit dekt alleen markdown-content. Vault-media-assets (fotos, audio) vereisen een apart sync-script (TASK-089).

Transformer-interface (referentie)

Transformers verwerken de parsed markdown tree. Ze hebben een andere handtekening:

import { QuartzTransformerPlugin } from "../types"
 
export const MijnTransformer: QuartzTransformerPlugin = () => ({
  name: "MijnTransformer",
  markdownPlugins() { return [] },
  htmlPlugins() { return [] },
})

Voor embeds en link-transformaties (bijv. <span class="vault-embed vault-not-found" title="Asset niet gevonden: id">[vault: id]</span> syntax) gebruik je de htmlPlugins of textTransform hooks.

Verbanden

Bronnen

Sessie-herkomst