Data File YAML
Blogin reads YAML in two places: data/*.yaml (or .yml, with subdirectories
becoming nested maps), which a layout reads through data, and _data.yaml (or
_data.yml) in a content directory, which is merged into data for pages in
that directory and every directory below it. See Data files for how they load.
Front matter is not YAML and is not covered here. It is a block of keys and
values read directly.
What follows is not all of YAML. It is the part data files use, written down so that everything outside it is a stated boundary. The constructs in What is refused fail with the line number and what was refused. A few others are read in a way you may not expect, and are listed after that table.
Full YAML 1.2 is a project of its own. Anchors and aliases, tags, multiple documents in one file, block scalar folding, and type resolution are the parts that make it one, and none of them appears in a data file that lists the entries of a menu.
What is read#
Block mappings#
Keys and values, nested by indentation. Indentation is spaces. A tab is not refused, and a tab-indented line is read as if it were not indented, so do not indent with tabs.
site:
name: Example
owner:
name: A Person
email: person@example.com
The split between key and value happens at the first colon outside quotes that
is followed by a space or ends the line, so a:b: c has the key a:b. A key
that must contain : is quoted.
Block sequences#
archives:
- 2026
- 2025
The dashes may also sit at the key's own indentation, which is the other common style:
archives:
- 2026
- 2025
A sequence of mappings, with the first key on the dash line:
links:
- title: Home
url: /
- title: Notes
url: /notes/
A nested sequence goes on its own line, indented:
matrix:
-
- a
- b
Writing that as - - a is refused rather than read as the string - a.
Flow sequences#
A list of scalars on one line:
tags: [cpp, web, notes]
Brackets or braces inside it are not read as structure. They become part of the strings around them, so do not nest them.
Scalars#
| Written | Read as |
|---|---|
null, ~, nothing after the colon |
null |
true, false |
boolean |
42, -7 |
integer |
3.14, -0.5 |
number |
| anything else | string |
A plain scalar needs no quotes. Single quotes make a string literal, with no
escapes inside, so 'C:\path' is those characters. Double quotes take \n,
\t, \r, \", and \\, and any other escape is an error.
title: A Title
quoted: 'true'
message: "line one\nline two"
quoted above is the string true, not the boolean.
Comments#
A # at the start of a line or after a space or tab runs to the end of the line. A #
inside quotes is a character.
# The menu, in the order it is shown.
color: "#663399" # not a comment
The document marker#
A line of --- on its own is skipped wherever it appears. A file may open with
one, and a second document after another --- is read as part of the first.
What is refused#
Each of these fails with a line number rather than being guessed at.
| Written | Message |
|---|---|
{a: 1} |
flow mappings are not supported |
&anchor, *alias |
anchors and aliases are not supported |
|, >, |-, >- |
block scalars are not supported |
- - a |
a nested sequence on the same line is not supported. Indent it on its own line |
| a line indented past its parent | unexpected indentation |
| a line with no colon where a key belongs | expected 'key: value' |
a - item where a key belongs |
a sequence item where a mapping key was expected |
"\q" |
unknown escape in a double-quoted scalar |
| nesting deeper than 64 levels | nested too deeply |
These are read rather than refused. Multiple documents are merged into one, a
tag such as !!str becomes part of the string, a repeated key keeps its last
value, and a complex key fails with expected 'key: value'. None of them
belongs in a data file.
JSON is read too#
A data file may be .json instead, and JSON is read in full, up to 64 levels of
nesting. The two produce the same values, so data<menu> reads the same whether
menu.yaml or menu.json is what sits in data/. If both exist, menu.yaml (or
.yml) wins over menu.json.