YAML syntax
This page provides a basic overview of correct YAML syntax used for jobs and configuration files.
We use YAML because it is easier for humans to read and write than other common data formats like XML or JSON.
YAML basics
All YAML files can optionally begin with ---
and end with ...
to indicate the start and end of a document.
A list is made of lines beginning at the same indentation level starting with a "- "
(a dash and a space):
---
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
...
A dictionary is represented in a simple key: value
form (the colon must be followed by a space):
# An employee record
martin:
name: Martin D'vloper
job: Developer
skill: Elite
More complicated data structures are possible, such as lists of dictionaries, dictionaries whose values are lists, or a mix of both:
# Employee records
- martin:
name: Martin D'vloper
job: Developer
skills:
- python
- perl
- pascal
- tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- lisp
- fortran
- erlang
Dictionaries and lists can also be represented in an abbreviated form if you really want to:
---
martin: {name: Martin D'vloper, job: Developer, skill: Elite}
['Apple', 'Orange', 'Strawberry', 'Mango']
These are called “Flow collections”.
You can specify a boolean value (true/false) in several forms:
create_key: yes
needs_agent: no
knows_oop: True
likes_emacs: TRUE
uses_cvs: false
However, please use lowercase true
or false
for boolean values in dictionaries as these are the default syntax
for tools like yamllint.
Values can span multiple lines using |
or >
. Spanning multiple lines using a “Literal Block Scalar” |
will
include the newlines and any trailing spaces. Using a “Folded Block Scalar” >
will fold newlines to spaces; it’s
used to make what would otherwise be a very long line easier to read and edit. In either case the indentation will be
ignored. Examples are:
include_newlines: |
exactly as you see
will appear these three
lines of poetry
fold_newlines: >
this is really a
single line of text
despite appearances
While in the above >
example all newlines are folded into spaces, there are two ways to enforce a newline to be
kept:
fold_some_newlines: >
a
b
c
d
e
f
same_as: "a b\nc d\n e\nf\n"
Let’s combine what we learned so far in an arbitrary YAML example. This really has nothing to do with webchanges, but will give you a feel for the format:
---
# An employee record
name: Martin D'vloper
job: Developer
skill: Elite
employed: true
foods:
- Apple
- Orange
- Strawberry
- Mango
languages:
perl: Elite
python: Elite
pascal: Lame
education: |
4 GCSEs
3 A-Levels
BSc in the Internet of Things
Gotchas and common errors
While you can put just about anything into an unquoted scalar, there are some exceptions. A colon followed by a space
(or newline) ": "
is an indicator for a mapping. A space followed by the pound sign " #"
starts a comment.
Because of this, the following will work (since there’s no space immediately after the second colon):
windows_path: c:\windows
but the following will not work:
foo: somebody said I should put a colon here: so I did # This doesn't work!
windows_drive: c:
and when you run webchanges it will result in the following error:
yaml.scanner.ScannerError: mapping values are not allowed here
in [file], line 18, column 45
You will want to quote hash values using colons followed by a space or the end of the line:
foo: 'somebody said I should put a colon here: so I did' # This works!
windows_drive: 'c:'
…and then the colon will be preserved.
Alternatively, you can use double quotes:
foo: "somebody said I should put a colon here: so I did"
windows_drive: "c:"
The difference between single quotes and double quotes is that in double quotes you can use escapes:
foo: "a \t TAB and a \n NEWLINE"
The list of allowed escapes can be found in the YAML 1.1 Specification under “Escape Sequences” here.
The following is invalid YAML:
foo: "an escaped \' single quote"
Causing the error:
yaml.scanner.ScannerError: while scanning a double-quoted scalar
in [file], line 1, column 6
found unknown escape character "'"
in [file], line 1, column 19
If your value starts with a quote the entire value must be quoted, not just part of it. Here are some additional examples of how to properly quote things:
foo: "{{ variable }}/additional/string/literal"
foo2: "{{ variable }}\\backslashes\\are\\also\\special\\characters"
foo3: "even if it's just a string literal it must all be quoted"
Not valid:
foo: "E:\\path\\"rest\\of\\path
Causing this error:
yaml.parser.ParserError: while parsing a block mapping
in [file], line 1, column 1
expected <block end>, but found '<scalar>'
in [file], line 1, column 18
In addition to '
and "
there are a number of characters that are special (or reserved) and cannot be used
as the first character of an unquoted scalar: [] {} > | * & ! % # \` @ ,
.
You should also be aware of ? : -
. In YAML, they are allowed at the beginning of a string if a non-space character
follows, but YAML processor implementations differ, so it’s better to use quotes.
In Flow Collections, the rules are a bit more strict:
'a scalar in block mapping': this } is [ all , valid
'flow mapping': { key: "you { should [ use , quotes here" }
Boolean conversion is helpful, but this can be a problem when you want a literal ‘yes’ or other boolean values as a string. In these cases just use quotes:
non_boolean: "yes"
other_string: "False"
YAML converts certain strings into floating-point values, such as the string ‘1.0’. If you need to specify a version number (in a requirements.yml file, for example), you will need to quote the value if it looks like a floating-point value:
version: "1.0"
URLs are always safe and don’t need to be enclosed in quotes.
According to the YAML specification, only ASCII characters can be used, but webchanges supports Unicode, so this works just fine even though it’s technically not supported by YAML:
name: "© Megaco"
In case you care, under the standard non-ASCII characters may be represented with a \u
-style escape sequence within
double-quotes:
name: "\u00A9 Megaco" # The copyright sign ©
Note that while YAML allows for aliases (anchors/references) as a way to reuse the same content, each job is a different “document” and YAML does not allow anchors/references between documents, even if they are in the same file (reference).
See also
- YAMLLint
YAML Lint (online) helps you debug YAML syntax if you are having problems.
- Wikipedia YAML syntax reference
A good guide to YAML syntax.
- YAML 1.1 Specification
The official specification for YAML 1.1, which the Python package PyYAML used in webchanges implements.
- YAML flow scalars
A guide on when and how to use quotes in YAML (refer to YAML 1.1).