Adding a tutorial¶
Community's Learn room teaches every feature in short tutorials. They are not code: they are one data file on main, docs/learn/catalog.json, which the plugin reads from GitHub when Learn is shown. So a tutorial merged to main reaches every user on their next visit to Learn — no plugin release, no update — and the plugin's main.js does not grow with it.
The file's full shape, how the plugin reads it and how it is cached are in the Learn catalog section of the architecture page. This page is the contributor's checklist.
The rules CI checks¶
test/docs/learnCatalog.test.ts validates the whole file on every push and names the entry that is wrong (tutorials.undo.steps: 2 steps (needs 3–6)). A pull request that breaks one does not merge.
sinceis never newer thanmanifest.json'sversionat merge.sinceis the oldest ZettelFlow the tutorial describes, and a plugin older than it hides the tutorial. A tutorial for a feature that ships in the next release therefore waits for that release's version bump: it cannot land before the feature it teaches.- Every string is in two languages,
enandes—{ "en": "…", "es": "…" }— and neither may be empty. - 3–6 steps per tutorial.
- Every picture exists. An
image(or ahero) is a path underdocs/resources/ending in.svgor.png, and the file is there. - Every page exists. A
docis a page underdocs/(development/reader.md), never a URL. - Capability ids are real.
tryIt.capabilityand a reference row'scapabilityare ids inCAPABILITIES(src/architecture/components/core/surface/capabilities.ts). - Ids hold together. Tutorial ids are unique, each tutorial is in exactly one track, and every
relatedid resolves. - Settings paths name real groups. Settings → ZettelFlow → Flows is checked against the settings tab, in English; the Spanish strings must use the Spanish names.
Coverage. test/docs/learnCoverage.test.ts fails when a capability in CAPABILITIES is named by no tutorial's tryIt and no reference row. A capability that genuinely cannot be covered in the same change goes in its UNCOVERED register with the issue that will cover it ("#123 — …"). The register only shrinks: once the capability is covered, the test fails until its line is removed. Adding a capability to the plugin therefore means adding its line to Learn.
Writing one¶
- Pick an id (
kebab-case, never renamed once shipped: progress and New are kept by id) and add the tutorial undertutorials. Add the id to one track'stutorials, where it belongs in reading order. - Fill it in:
title,summary,minutes,level(easy,medium,hard),door(where the feature is, in the words the UI shows), the steps, atip, thedocpage it comes from and, if they help,relatedtutorials. - Draw the pictures. A step's
imageis an official, hand-drawn SVG in the house style ofdocs/resources/readme/— never a screenshot. A step with no image keeps the one before it on the stage. Reuse a picture a docs page already shows when it fits. - Offer Do it now, if it can run.
tryIt: { "capability": "<id>", "label": { … } }gives the lesson a button that opens the feature. It only appears when the capability has a door Learn can run (a ribbon entry, a command, a surface or a settings section). - Add a reference row in
referencewhen the feature deserves a line in Look anything up.
Everything in the file is drawn as text. It can name a page, a picture and a capability id — never a command, a URL or code.
Check it before you open the pull request¶
- Run
npx jest test/docs/learnCatalog test/docs/learnCoverageto see exactly what CI will say. - Run
mkdocs serveand open every picture and page the tutorial names.
You cannot see an unmerged tutorial inside Obsidian: Learn reads main only, by design, and there is no development override. Once merged, it is in Learn for everyone on their next visit.
Linking to a tutorial from the plugin¶
Code that wants to teach a feature opens its lesson directly:
Community pans to Learn and opens that lesson once the catalog is there (Contribute's How to contribute well does exactly this). If the catalog has no such tutorial, nothing opens, so a caller that must always land somewhere checks first and falls back to the docs page, as Contribute does.