NEON Format
NEON is a human-readable structured data format. In Nette, it is used for configuration files. It is also used for structured data such as settings, language translations, etc. Try it on the sandbox.
NEON stands for Nette Object Notation. It is less complex and cumbersome than XML or JSON, but provides similar capabilities. It is very similar to YAML. The main advantage is that NEON has so-called entities, thanks to which the configuration of DI services is so sexy. And it allows tabs for indentation.
NEON is built from the ground up to be easy to use.
Integration
- NetBeans (has built-in support)
- PhpStorm (plugin)
- Visual Studio Code (Nette Latte + Neon or Nette for VS Code)
- Sublime Text 3 (plugin)
- Sublime Text 2 (plugin)
- VIM (plugin)
- Emacs (plugin)
- Prism.js (integrated language)
Syntax
A file written in NEON usually represents a sequence or a mapping.
Mappings
A mapping is a set of key-value pairs; in PHP, it would be called an associative array. Each pair is written as
key: value
, a space after :
is required. The value can be anything: string, number, boolean, null,
sequence, or another mapping.
street: 742 Evergreen Terrace
city: Springfield
country: USA
In PHP, the same structure would be written as:
[ // PHP
'street' => '742 Evergreen Terrace',
'city' => 'Springfield',
'country' => 'USA',
]
This notation is called block notation because all items are on separate lines and have the same indentation (none in this case). NEON also supports an inline representation for mapping, which is enclosed in brackets, indentation plays no role, and the separator for elements is either a comma or a newline:
{street: 742 Evergreen Terrace, city: Springfield, country: USA}
The same written on multiple lines (indentation does not matter):
{
street: 742 Evergreen Terrace
city: Springfield, country: USA
}
Alternatively, =
can be used instead of :
, both in block and inline notation:
{street=742 Evergreen Terrace, city=Springfield, country=USA}
Sequences
Sequences are indexed arrays in PHP. They are written as lines starting with a hyphen -
followed by a space.
Again, the value can be anything: string, number, boolean, null, sequence, or another mapping.
- Cat
- Dog
- Goldfish
In PHP, the same structure would be written as:
[ // PHP
'Cat',
'Dog',
'Goldfish',
]
This notation is called block notation because all items are on separate lines and have the same indentation (none in this case). NEON also supports an inline representation for sequences, which is enclosed in brackets, indentation plays no role, and the separator for elements is either a comma or a newline:
[Cat, Dog, Goldfish]
The same written on multiple lines (indentation does not matter):
[
Cat, Dog
Goldfish
]
Hyphens (bullets) cannot be used in the inline representation.
Combinations
Values of mappings and sequences can be other mappings and sequences. The level of indentation plays a major role. In the
following example, the hyphen used to indicate sequence items has a greater indentation than the pets
key, so the
items become the value of the first line:
pets:
- Cat
- Dog
cars:
- Volvo
- Skoda
In PHP, the same structure would be written as:
[ // PHP
'pets' => [
'Cat',
'Dog',
],
'cars' => [
'Volvo',
'Skoda',
],
]
It is possible to combine block and inline notation:
pets: [Cat, Dog]
cars: [
Volvo,
Skoda,
]
Block notation cannot be used inside an inline notation; this does not work:
item: [
pets:
- Cat # THIS IS NOT POSSIBLE!!!
- Dog
]
In the previous case, we wrote a mapping whose elements were sequences. Now, let's try it the other way around and create a sequence containing mappings:
-
name: John
age: 35
-
name: Peter
age: 28
It's not necessary for the hyphens to be on separate lines; they can also be placed like this:
- name: John
age: 35
- name: Peter
age: 28
It's up to you whether you align the keys in a column using spaces or use a tab character.
Because PHP uses the same structure for mappings and sequences (i.e., arrays), both can be merged. The indentation is the same this time:
- Cat
street: 742 Evergreen Terrace
- Goldfish
In PHP, the same structure would be written as:
[ // PHP
'Cat',
'street' => '742 Evergreen Terrace',
'Goldfish',
]
Strings
Strings in NEON can be enclosed in single or double quotes. But as you can see, they can also be without quotes.
- An unquoted string in NEON
- 'A single-quoted string in NEON'
- "A double-quoted string in NEON"
If the string contains characters # " ' , : = - [ ] { } ( )
that could be confused with NEON syntax, it must be
enclosed in quotes. We recommend using single quotes because they do not use escaping. If you need to include a quote character in
such a string, double it:
'A single quote '' inside a single-quoted string'
Double quotes allow you to use escape sequences to write special characters using backslashes \
. All escape
sequences supported by the JSON format are supported, plus \_
, which represents a non-breaking space, i.e.,
\u00A0
.
- "\t \n \r \f \b \" \\ \/ \_"
- "\u00A9"
There are other cases where you need to enclose strings in quotes:
- they start or end with spaces
- they look like numbers, booleans, or null
- NEON would interpret them as dates
Multiline Strings
A multiline string begins and ends with triple quotes on separate lines. The indentation of the first line is ignored for all lines:
'''
first line
second line
third line
'''
In PHP, we would write the same as:
"first line\n\tsecond line\nthird line" // PHP
Escape sequences work only for strings enclosed in double quotes instead of apostrophes:
"""
Copyright \u00A9
"""
Numbers
NEON understands numbers written in scientific notation and also numbers in binary, octal, and hexadecimal bases:
- 12 # integer
- 12.3 # float
- +1.2e-34 # exponential number
- 0b11010 # binary number
- 0o666 # octal number
- 0x7A # hexadecimal number
Nulls
Null can be expressed in NEON using null
or by omitting the value. Variants with a capital first letter or all
uppercase letters are also allowed (Null
, NULL
).
a: null
b:
Booleans
Boolean values are expressed in NEON using true
/ false
or yes
/ no
.
Variants with a capital first letter or all uppercase letters are also allowed (True
, TRUE
,
False
, FALSE
, Yes
, YES
, No
, NO
).
[true, TRUE, True, false, yes, no]
Dates
NEON uses the following formats to express dates and automatically converts them to DateTimeImmutable
objects:
- 2016-06-03 # date
- 2016-06-03 19:00:00 # date & time
- 2016-06-03 19:00:00.1234 # date & microtime
- 2016-06-03 19:00:00 +0200 # date & time & timezone
- 2016-06-03 19:00:00 +02:00 # date & time & timezone
Entities
An entity is a structure that resembles a function call:
Column(type: int, nulls: yes)
In PHP, it is parsed as a Nette\Neon\Entity object:
// PHP
new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true])
Entities can also be chained:
Column(type: int, nulls: yes) Field(id: 1)
Which is parsed in PHP as follows:
// PHP
new Nette\Neon\Entity(Nette\Neon\Neon::Chain, [
new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true]),
new Nette\Neon\Entity('Field', ['id' => 1]),
])
Inside the parentheses, the rules for inline notation used for mappings and sequences apply, so it can be multiline, and commas are not necessary:
Column(
type: int
nulls: yes
)
Comments
Comments start with #
and all subsequent characters to the right are ignored:
# this line will be ignored by the interpreter
street: 742 Evergreen Terrace
city: Springfield # this is ignored too
country: USA
NEON versus JSON
JSON is a subset of NEON. Therefore, any JSON can be parsed as NEON:
{
"php": {
"date.timezone": "Europe\/Prague",
"zlib.output_compression": true
},
"database": {
"driver": "mysql",
"username": "root",
"password": "password123"
},
"users": [
"Dave", "Kryten", "Rimmer"
]
}
What if we omitted the quotes?
{
php: {
date.timezone: Europe/Prague,
zlib.output_compression: true
},
database: {
driver: mysql,
username: root,
password: password123
},
users: [
Dave, Kryten, Rimmer
]
}
How about braces and commas?
php:
date.timezone: Europe/Prague
zlib.output_compression: true
database:
driver: mysql
username: root
password: password123
users: [
Dave, Kryten, Rimmer
]
Aren't lists with bullets more readable?
php:
date.timezone: Europe/Prague
zlib.output_compression: true
database:
driver: mysql
username: root
password: password123
users:
- Dave
- Kryten
- Rimmer
Shall we add comments?
# my web application config
php:
date.timezone: Europe/Prague
zlib.output_compression: true # use gzip
database:
driver: mysql
username: root
password: password123
users:
- Dave
- Kryten
- Rimmer
Hooray, now you know the NEON syntax!