Content format

The Markdown Pholio accepts, the component tags it understands and the meta.json tree files.

Pholio parses a fixed grammar. There is no fallback: an unknown construct stops the build with exit code 3 and a message naming the file and the line, for example pholio: content/guide/index.md:12: Unknown component <Tip>; allowed: ….

Files and URLs

Every *.md file below content_dir is a page (content.extensions changes the list). guide/installation.md is published at {docs}/guide/installation, guide/index.md at {docs}/guide. URLs have no trailing slash. Files whose name starts with _ are drafts and only built with --dev.

Frontmatter

Every file starts with frontmatter. Values are plain scalars; YAML lists, objects and anchors are errors, and so is any key outside this table (content.frontmatter_aliases maps other names onto these).

KeyRequiredMeaning
titleyesPage title, used in the tree, the breadcrumb and <title>
descriptionnoShown under the heading and indexed for search
keywordsnoSearch terms the page text does not use, such as synonyms or English words: a comma-separated string (keywords: "herunterladen, download, dark mode") or a list of strings (keywords: [herunterladen, "dark mode"], or - herunterladen lines below the key); both index the same. Anything else is an error. Only indexed for search, weighted like the title
headingnoVisible h1 when it should differ from title
iconnolucide icon name, used in the sidebar and in cards
fullnotrue renders the page without the table of contents column
updatednoText of the "Last updated" line under the page
noindexnotrue keeps the page out of llms.txt, llms-full.txt, skill.md and sitemap.xml and adds <meta name="robots" content="noindex">; the page is still built

Markdown

  • Headings ## to ####. The h1 comes from the frontmatter, so # in the body is an error. Heading ids follow github-slugger: lowercase, punctuation removed, spaces to hyphens, non-ASCII letters kept, duplicates suffixed -1, -2.
  • Paragraphs, **bold**, *italic*, ~~strikethrough~~, `code`, links, images, blockquotes, horizontal rules, hard breaks from two trailing spaces.
  • Ordered, unordered and nested lists, task lists - [x].
  • GitHub-flavored tables with column alignment.
  • Footnotes [^1] with their definitions.

A plain Markdown image renders as a single bordered image, with its width and height read from the file. Put images into the project's assets/ folder and reference them either by their published URL, /assets/images/diagram.png, or relative to the page, ../assets/images/diagram.png. Both publish as /assets/images/diagram.png. A relative path that points outside a copied directory stops the build. Sites with their own layout keep using copy and content.asset_prefix, content.asset_target and content.asset_root.

Code blocks

Fenced code is highlighted at build time with the bundled TextMate grammars and GitHub light and dark themes: css, diff, html, java, javascript (js), json, php, shellscript (bash, sh), sql, typescript (ts), xml and yaml. Any other language stops the build.

```ts title="search.ts" lineNumbers
const hits = await archive.search('invoice'); // [!code highlight]
```
MetaEffect
title="…"File name bar above the code
lineNumbers, lineNumbers=40Line numbers, optionally starting at another value
tab="…"Consecutive blocks with tab are merged into one tab group
{1,3-4}Accepted for compatibility, no effect

Notation comments at the end of a line, in the comment syntax of the language: [!code highlight], [!code focus], [!code ++], [!code --], and [!code word:term] on its own line to highlight a word in the lines below.

Component tags

Tags sit on their own line, attributes are quoted, and nesting works as in HTML. They are data: no expressions, no imports, no evaluation. Attribute values have four notations:

  • text: title="Before you start"
  • list: items="macOS|Linux|Windows", a literal | written as \|
  • boolean: persist for true, persist="false" for false
  • number: defaultIndex="1"

Icons are lucide names such as book-open; an unknown name stops the build.

TagAttributesChildren
Callouttype (info, warning, error, success, idea; aliases warn, tip), title, iconMarkdown
CardsnoneCard
Cardtitle (required), description, href, iconnone
Screenshotsrc (required), dark, altnone
ImageZoomsrc (required), alt, width, heightnone
Bannerid, variant (normal, rainbow), height, changeLayoutMarkdown
Tabsitems, groupId, persist, updateAnchor, defaultIndex, labelTab
TabvalueMarkdown
Accordionstype (single, multiple), defaultValueAccordion
Accordiontitle (required), id, valueMarkdown
StepsnoneStep
StepnoneMarkdown
FilesnoneFolder, File
Foldername (required), defaultOpen, disabledFolder, File
Filename (required), iconnone
TypeTablenoneTypeProp
TypePropname, type (both required), default, typeDescription, typeDescriptionLink, required, deprecatedMarkdown
InlineTOClabelnone
DynamicCodeBlocklang (required)verbatim code
<Callout type="warning" title="Before you start">
Back up your configuration.
</Callout>

<Screenshot src="/images/pipeline.svg" dark="/images/pipeline-dark.svg" alt="The pipeline" />

<Tabs items="macOS|Linux" groupId="os" persist>
<Tab value="macOS">
Archives live in `~/Library/Application Support`.
</Tab>
<Tab value="Linux">
Archives live in `~/.local/share`.
</Tab>
</Tabs>

Screenshot shows dark in the dark color scheme and src in the light one. Without dark the same image is shown in both.

meta.json

A folder's meta.json names the folder and orders its pages. It is optional; a folder without one lists its pages alphabetically.

KeyMeaning
title, description, iconFolder title, description and icon, used in the sidebar and by home.cards.from_tree
rootThe folder is a root area with its own sidebar, listed in the area switcher
pagesOrder of the entries, see below
defaultOpenThe folder starts expanded in the sidebar
collapsiblefalse keeps the folder permanently expanded

Entries in pages:

  • "installation": a page or subfolder by its file or folder name
  • "---Components---", "---[icon]Components---": a separator with an optional icon
  • "...": every remaining entry alphabetically, "z...a" in reverse
  • "...folder": the entries of a subfolder, inlined
  • "[Title](https://example.org)", "external:[Title](https://example.org)": a link

What stops the build

Exit code 3 with file and line: unknown frontmatter keys or YAML constructs, a # heading, unknown component tags or attributes, a tag inside a parent it doesn't belong to, unknown lucide icons, unknown code languages, invalid meta.json, duplicate slugs and a folder group name used as a file name.

Not checked yet: whether an internal link points at an existing page, and whether an image file exists. A missing image renders without width and height.

On this page