Page templates

Starting a page of a known kind, such as a how-to, from a template and a guide to what goes in it, written into your project by ascribe templates eject.

For AI agents: the documentation index is at llms.txt, and this page is available as Markdown.

A page of a known kind has a shape: a how-to has what to do before you start, then numbered steps, then what to do next. A template is a page with that shape and things to fill in, and its guide says what belongs in each part. Ascribe carries a set of six, and writes them into your project with one command, where they’re your files.

Where the templates come from

The templates are The Good Docs Project’s, from their repository, gitlab.com/tgdp/templates, at their release v1.6.0. Their work is under the MIT No Attribution License, which asks for no credit; this is it anyway, with thanks.

Ascribe converts each one into an Ascribe page and changes nothing of their wording: each {placeholder} is written as \{placeholder}, so it shows as written and isn’t read as a phrase. Each guide says at its top where it came from, and ascribe templates list shows the set and its release.

A template’s instructions to the writer, such as {This section is optional}, are memos: @memo: This section is optional. A memo is never published: follow it, then delete it or keep it. A paragraph that marks where the page’s own text goes, such as the how-to’s {Optional: Explanatory text} in a step, stays a placeholder.

The set has six templates, for a how-to, a concept, a tutorial, a reference, a troubleshooting page, and release notes. Each is one of theirs, and has a type of the same name.

Take the templates

To start a project with the set, run ascribe init --templates in an empty folder: it writes the project’s first ascribe.toml and takes the six templates as eject would (command reference).

In a project that has its ascribe.toml already, take the whole set:

ascribe templates eject

It writes each template, its guide, and Ascribe’s notes on its type into templates/, beside ascribe.toml, with templates/templates.lock, which records what each was copied from, and adds the six types to ascribe.toml, below what’s there. A type is declared like this:

[types.how-to]

[types.how-to.frontmatter]
title = "string"
description = "string"

The type names no template: a type with no template and no guide takes both from the lock, which records them under the type’s name. A type that names either keeps what it names, which is how a project without the lock, or with a template written by hand, gives a type its template. In VS Code, the hover on the type’s name in ascribe.toml says where its template comes from.

A page says what type it is in its frontmatter, type: how-to, as each template does, so a page of any type can go in any folder. Commit the files, the lock with them. The rules ascribe agents sync writes say what each type is for; to say it your own way, give the type a purpose.

To take only some, name them: ascribe templates eject how-to concept. A type the project declares already is refused, and nothing is written; to keep it and take its template, add --keep-type. The command reference has the rest.

Change a template

From then on the files are your project’s, and nothing in Ascribe writes over them. Change a template as you’d change any page: take out a section your project never has, add one it always does, or write your own placeholder as \{What goes here}. Add to the guide or the notes, or add a file of your own to the type’s guide list.

The check compares a page with the template as it is now, so a placeholder you take out isn’t looked for any more, and one you add is.

See what’s changed in the set

A later ascribe carries The Good Docs Project’s newer release. Nothing changes your copies: to see what’s different, run:

ascribe templates status

For each template you took, it says whether the set has changed it since your copy, and whether you’ve changed it. To take a change, see it, then copy what you want by hand:

ascribe templates status --diff how-to

The command reference has its options, for a CI job too, and its JSON.

In a project that has pages

A project with pages written already can take the set too; Ascribe’s own docs did. Its pages name no type yet if the project declared none, and ascribe check offers a fix for each. Pages written before their template have none of its placeholders, so the check reports nothing on them, and a page that’s none of the six, such as a home page that lists the others, gets a type of your own with no template. A guide says what a kind of page is for; a page that already does its job needn’t match its template heading for heading.

Ascribe’s notes

Their guide says what belongs in a page of each kind, for any tool. Ascribe’s notes, <type>.ascribe.md, are a minute’s reading after it: only what’s particular to writing that kind of page in Ascribe, such as a how-to’s alternatives by platform as a variant group, and a step’s command taken from tested code with @snippet.

Start a page

In VS Code, run Ascribe: New Page. It asks for the type and the page’s title, then makes the page from the type’s template, with the first thing to fill in selected; Ascribe: Go to Next Placeholder selects the next (editor guide).

From the command line, ascribe new does the same.

ascribe new

Ascribe (in main, not yet released, 0.4.5)

Starts a page of a type from the type’s template, with its type and title set, as a draft, as New Page does, and writes it where PATH says. It never writes over a file.

ascribe new how-to docs/guides --title "Rotate keys"
  • TYPE: The page’s type, as ascribe model --section types names it.
  • PATH: Where the page goes, from the current folder, in the content root: a page’s path, ending in .md, or a folder, where the page is named for its title.
  • --title <TITLE>: The page’s title, set in its frontmatter. Without one, the page keeps the template’s, to fill in with the rest, and PATH names the page itself.
  • --dry-run: Say where the page would go, and print its text, writing nothing.
  • --force: Taken as by every command that writes. new changes no file that’s there, only adds one, so the git guard has nothing to refuse.
  • --format <FORMAT>: How to show what was written.
    • text (the default): Where the page went, and what to do next, for people and agents.
    • json: One JSON document, for tools.

PATH is from the current folder, in the content root: a page’s path, ending in .md, or a folder, where the page is named for its title as a route’s segment is, docs/guides/rotate-keys.md above. The folders it names are made. Without --title, the page keeps the template’s title, to fill in with the rest, and PATH must name the page itself. A type with no template starts with its frontmatter alone: its type, the title, and each field it requires, empty.

The page starts as a draft, with draft: true in its frontmatter, which no build publishes, so what it has left of its template is advice while you write it. Take the line out to publish it: from then on, a placeholder left in it is an error (What’s left to fill in).

It says where the page went, the type’s guide to read before writing, and how many placeholders are left, which ascribe check lists:

wrote docs/guides/rotate-keys.md, a page of type `how-to`, from templates/how-to.md
Read its guide before you write: templates/how-to.guide.md, templates/how-to.ascribe.md
It has 13 placeholders left to fill in, which `ascribe check docs/guides/rotate-keys.md` lists
It's a draft, with `draft: true`, which no build publishes: take the line out to publish it

With --dry-run, it says where the page would go and prints its text, and writes nothing. With --format json, it writes one document with the page’s path, its text, and the count.

Exit code Meaning
0 The page was written, or with --dry-run would be
2 Nothing was written: a type the content model doesn’t have, a path outside the content root, a file where the page would go, no title to name a page in a folder, or a template that can’t be read

An agent starts from the template too. Ask it for a page with the plugin’s /ascribe:new-page, or the prompt ascribe agents prompt new-page prints (agents guide), which gives it the template and sends it to the guide and the notes before it writes:

ascribe agents prompt new-page --arg type=how-to --arg title="Rotate keys"

What’s left to fill in

ascribe check compares a page with its type’s template and reports what it still has of it: a placeholder or a frontmatter field the page has word for word, and a section the template gives only memos that the page leaves empty (template-section-empty, advice).

A placeholder left is advice in a draft, a page with draft: true (template-placeholder-left), so a page you’re still writing isn’t covered in errors. In a page that publishes, it’s an error (template-placeholder-published): readers would read the template’s words, so ascribe check fails, ascribe build writes nothing, and the editor, the agents’ hook, and the MCP tools report it the same way. A page started with ascribe new or New Page is a draft until you take the line out. A memo the page keeps isn’t reported. In VS Code, the sidebar’s This page says how many are left, and Go to Next Placeholder goes to the next one.

The check finds only what was never touched, so read a page through before publishing it. To turn any of these checks off, or set another level, set its level in [checks].

See also

  • ascribe templates: list, eject, and status, their options, and their output.
  • Page types: a type’s template, guide, and purpose, and the template it takes from the lock.