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

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!

version: 3.4