Das Format NEON
NEON ist ein für Menschen lesbares Format für strukturierte Daten. In Nette wird es für Konfigurationsdateien verwendet. Es dient außerdem für strukturierte Daten wie Einstellungen, Sprachübersetzungen usw. Probieren Sie es in der Sandbox aus.
NEON steht für Nette Object Notation. Es ist weniger komplex und schwerfällig als XML oder JSON, bietet aber ähnliche Möglichkeiten. Es ähnelt YAML sehr. Der Hauptvorteil ist, dass NEON die sogenannten Entities hat, dank derer die Konfiguration der DI-Services so sexy ist. Und es erlaubt Tabs zur Einrückung.
NEON ist von Grund auf so gebaut, dass es einfach zu benutzen ist.
Integration
- NetBeans (hat eingebaute Unterstützung)
- PhpStorm (Plugin)
- Visual Studio Code (Nette Latte + Neon oder Nette for VS Code)
- Sublime Text 3 (Plugin)
- Sublime Text 2 (Plugin)
- VIM (Plugin)
- Emacs (Plugin)
- Prism.js (integrierte Sprache)
Syntax
Eine in NEON geschriebene Datei stellt üblicherweise eine Sequenz oder ein Mapping dar.
Mappings
Ein Mapping ist eine Menge von Schlüssel-Wert-Paaren; in PHP würde man es assoziatives Array nennen. Jedes Paar wird als
key: value geschrieben, ein Leerzeichen nach : ist erforderlich. Der Wert kann alles sein: String, Zahl,
Boolean, null, Sequenz oder ein weiteres Mapping.
street: 742 Evergreen Terrace
city: Springfield
country: USA
In PHP würde dieselbe Struktur so geschrieben:
[ // PHP
'street' => '742 Evergreen Terrace',
'city' => 'Springfield',
'country' => 'USA',
]
Diese Schreibweise nennt man Blockschreibweise, weil alle Elemente in eigenen Zeilen stehen und dieselbe Einrückung haben (in diesem Fall keine). NEON unterstützt für Mappings außerdem eine Inline-Darstellung, die in geschweifte Klammern eingeschlossen wird, bei der die Einrückung keine Rolle spielt und bei der die Elemente entweder durch ein Komma oder durch einen Zeilenumbruch getrennt werden:
{street: 742 Evergreen Terrace, city: Springfield, country: USA}
Dasselbe über mehrere Zeilen geschrieben (die Einrückung spielt keine Rolle):
{
street: 742 Evergreen Terrace
city: Springfield, country: USA
}
Alternativ lässt sich statt : auch = verwenden, sowohl in der Block- als auch in der
Inline-Schreibweise:
{street=742 Evergreen Terrace, city=Springfield, country=USA}
Sequenzen
Sequenzen sind in PHP indizierte Arrays. Sie werden als Zeilen geschrieben, die mit einem Bindestrich - gefolgt
von einem Leerzeichen beginnen. Auch hier kann der Wert alles sein: String, Zahl, Boolean, null, Sequenz oder ein weiteres
Mapping.
- Cat
- Dog
- Goldfish
In PHP würde dieselbe Struktur so geschrieben:
[ // PHP
'Cat',
'Dog',
'Goldfish',
]
Diese Schreibweise nennt man Blockschreibweise, weil alle Elemente in eigenen Zeilen stehen und dieselbe Einrückung haben (in diesem Fall keine). NEON unterstützt für Sequenzen außerdem eine Inline-Darstellung, die in eckige Klammern eingeschlossen wird, bei der die Einrückung keine Rolle spielt und bei der die Elemente entweder durch ein Komma oder durch einen Zeilenumbruch getrennt werden:
[Cat, Dog, Goldfish]
Dasselbe über mehrere Zeilen geschrieben (die Einrückung spielt keine Rolle):
[
Cat, Dog
Goldfish
]
Bindestriche (Aufzählungszeichen) lassen sich in der Inline-Darstellung nicht verwenden.
Kombinationen
Die Werte von Mappings und Sequenzen können weitere Mappings und Sequenzen sein. Die Ebene der Einrückung spielt dabei die
Hauptrolle. Im folgenden Beispiel hat der Bindestrich, der die Elemente der Sequenz kennzeichnet, eine größere Einrückung als
der Schlüssel pets, deshalb werden die Elemente zum Wert der ersten Zeile:
pets:
- Cat
- Dog
cars:
- Volvo
- Skoda
In PHP würde dieselbe Struktur so geschrieben:
[ // PHP
'pets' => [
'Cat',
'Dog',
],
'cars' => [
'Volvo',
'Skoda',
],
]
Block- und Inline-Schreibweise lassen sich kombinieren:
pets: [Cat, Dog]
cars: [
Volvo,
Skoda,
]
Innerhalb einer Inline-Schreibweise lässt sich die Blockschreibweise nicht verwenden; das funktioniert nicht:
item: [
pets:
- Cat # DAS IST NICHT MÖGLICH!!!
- Dog
]
Im vorigen Fall haben wir ein Mapping geschrieben, dessen Elemente Sequenzen waren. Versuchen wir es nun andersherum und erstellen eine Sequenz, die Mappings enthält:
-
name: John
age: 35
-
name: Peter
age: 28
Die Bindestriche müssen nicht in eigenen Zeilen stehen, sie lassen sich auch so setzen:
- name: John
age: 35
- name: Peter
age: 28
Es liegt an Ihnen, ob Sie die Schlüssel mit Leerzeichen in einer Spalte ausrichten oder ein Tabulatorzeichen verwenden.
Weil PHP für Mappings und Sequenzen dieselbe Struktur verwendet (also Arrays), lassen sich beide zusammenführen. Die Einrückung ist diesmal gleich:
- Cat
street: 742 Evergreen Terrace
- Goldfish
In PHP würde dieselbe Struktur so geschrieben:
[ // PHP
'Cat',
'street' => '742 Evergreen Terrace',
'Goldfish',
]
Strings
Strings können in NEON in einfache oder doppelte Anführungszeichen eingeschlossen werden. Wie Sie aber sehen, geht es auch ohne Anführungszeichen.
- Ein String in NEON ohne Anführungszeichen
- 'Ein String in NEON in einfachen Anführungszeichen'
- "Ein String in NEON in doppelten Anführungszeichen"
Enthält der String Zeichen ` # " ' ` , : = - [ ] { } ( ) `, die sich mit der Syntax von NEON verwechseln ließen,
muss er in Anführungszeichen eingeschlossen werden. Wir empfehlen einfache Anführungszeichen, weil sie kein Escaping verwenden.
Müssen Sie in einem solchen String ein Anführungszeichen unterbringen, verdoppeln Sie es:
'Ein einfaches Anführungszeichen '' in einem einfach zitierten String'
Doppelte Anführungszeichen erlauben es, mit Escape-Sequenzen besondere Zeichen über Backslashes \ zu schreiben.
Unterstützt werden alle Escape-Sequenzen, die auch das Format JSON unterstützt, dazu \_, das ein geschütztes
Leerzeichen darstellt, also \u00A0.
- "\t \n \r \f \b \" \\ \/ \_"
- "\u00A9"
Es gibt weitere Fälle, in denen Sie Strings in Anführungszeichen setzen müssen:
- sie beginnen oder enden mit Leerzeichen
- sie sehen aus wie Zahlen, Booleans oder null
- NEON würde sie als Datumsangaben interpretieren
Mehrzeilige Strings
Ein mehrzeiliger String beginnt und endet mit dreifachen Anführungszeichen in eigenen Zeilen. Die Einrückung der ersten Zeile wird für alle Zeilen ignoriert:
'''
erste Zeile
zweite Zeile
dritte Zeile
'''
In PHP würden wir dasselbe so schreiben:
"erste Zeile\n\tzweite Zeile\ndritte Zeile" // PHP
Escape-Sequenzen funktionieren nur bei Strings, die statt in Apostrophe in doppelte Anführungszeichen eingeschlossen sind:
"""
Copyright \u00A9
"""
Zahlen
NEON versteht Zahlen in wissenschaftlicher Schreibweise und außerdem Zahlen zur Basis 2, 8 und 16:
- 12 # ganze Zahl
- 12.3 # Gleitkommazahl
- +1.2e-34 # Zahl in Exponentialschreibweise
- 0b11010 # Binärzahl
- 0o666 # Oktalzahl
- 0x7A # Hexadezimalzahl
Nulls
Null lässt sich in NEON mit null ausdrücken oder indem man den Wert weglässt. Varianten mit großem
Anfangsbuchstaben oder in Großbuchstaben sind ebenfalls erlaubt (Null, NULL).
a: null
b:
Booleans
Boolesche Werte drückt man in NEON mit true / false oder yes / no aus.
Varianten mit großem Anfangsbuchstaben oder in Großbuchstaben sind ebenfalls erlaubt (True, TRUE,
False, FALSE, Yes, YES, No, NO).
[true, TRUE, True, false, yes, no]
Datumsangaben
NEON verwendet zum Ausdrücken von Datumsangaben die folgenden Formate und wandelt sie automatisch in Objekte vom Typ
DateTimeImmutable um:
- 2016-06-03 # Datum
- 2016-06-03 19:00:00 # Datum und Zeit
- 2016-06-03 19:00:00.1234 # Datum und Mikrozeit
- 2016-06-03 19:00:00 +0200 # Datum, Zeit und Zeitzone
- 2016-06-03 19:00:00 +02:00 # Datum, Zeit und Zeitzone
Entities
Eine Entity ist eine Struktur, die einem Funktionsaufruf ähnelt:
Column(type: int, nulls: yes)
In PHP wird sie als Objekt Nette\Neon\Entity geparst:
// PHP
new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true])
Entities lassen sich auch verketten:
Column(type: int, nulls: yes) Field(id: 1)
Was in PHP folgendermaßen geparst wird:
// 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]),
])
Innerhalb der Klammern gelten die Regeln der Inline-Schreibweise für Mappings und Sequenzen, sie kann also mehrzeilig sein, und Kommas sind nicht nötig:
Column(
type: int
nulls: yes
)
Kommentare
Kommentare beginnen mit #, und alle folgenden Zeichen rechts davon werden ignoriert:
# diese Zeile wird vom Interpreter ignoriert
street: 742 Evergreen Terrace
city: Springfield # das wird ebenfalls ignoriert
country: USA
NEON im Vergleich zu JSON
JSON ist eine Teilmenge von NEON. Jedes JSON lässt sich deshalb als NEON parsen:
{
"php": {
"date.timezone": "Europe\/Prague",
"zlib.output_compression": true
},
"database": {
"driver": "mysql",
"username": "root",
"password": "password123"
},
"users": [
"Dave", "Kryten", "Rimmer"
]
}
Und wenn wir die Anführungszeichen weglassen?
{
php: {
date.timezone: Europe/Prague,
zlib.output_compression: true
},
database: {
driver: mysql,
username: root,
password: password123
},
users: [
Dave, Kryten, Rimmer
]
}
Und wie steht es mit den geschweiften Klammern und den Kommas?
php:
date.timezone: Europe/Prague
zlib.output_compression: true
database:
driver: mysql
username: root
password: password123
users: [
Dave, Kryten, Rimmer
]
Sind Listen mit Aufzählungszeichen nicht lesbarer?
php:
date.timezone: Europe/Prague
zlib.output_compression: true
database:
driver: mysql
username: root
password: password123
users:
- Dave
- Kryten
- Rimmer
Sollen wir Kommentare ergänzen?
# Konfiguration meiner Webanwendung
php:
date.timezone: Europe/Prague
zlib.output_compression: true # gzip verwenden
database:
driver: mysql
username: root
password: password123
users:
- Dave
- Kryten
- Rimmer
Hurra, nun kennen Sie die Syntax von NEON!