Nette Documentation Preview

syntax
Format NEON
***********

.[perex]
NEON to czytelny dla człowieka format danych strukturalnych. W Nette używany jest do plików konfiguracyjnych. Używa się go też do danych strukturalnych, jak ustawienia, tłumaczenia językowe itd. [Wypróbuj go w piaskownicy |https://fiddle.nette.org/neon/].

NEON to skrót od *Nette Object Notation*. Jest mniej złożony i uciążliwy niż XML czy JSON, ale daje podobne możliwości. Jest bardzo podobny do YAML-a. Główną zaletą jest to, że NEON ma tak zwane [encje |#Encje], dzięki którym konfiguracja usług DI jest [taka sexy |https://gist.github.com/dg/26baf3ce8f29d0f751e9dddfaa06504f]. I pozwala używać tabulatorów do wcięć.

NEON od podstaw zbudowany jest tak, żeby był łatwy w użyciu.


Integracja
==========

- NetBeans (ma wbudowane wsparcie)
- PhpStorm ([plugin |https://plugins.jetbrains.com/plugin/28338-neon])
- Visual Studio Code ([Nette Latte + Neon |https://marketplace.visualstudio.com/items?itemName=Kasik96.latte] albo [Nette for VS Code |https://marketplace.visualstudio.com/items?itemName=franken-ui.nette-for-vscode])
- Sublime Text 3 ([plugin |https://github.com/FilipStryk/Nette-Latte-Neon-for-Sublime-Text-3])
- Sublime Text 2 ([plugin |https://github.com/Michal-Mikolas/Nette-package-for-Sublime-Text-2])
- VIM ([plugin |https://github.com/fpob/nette.vim])
- Emacs ([plugin |https://github.com/Fuco1/neon-mode])
- Prism.js ([zintegrowany język |https://prismjs.com/#supported-languages])


- [NEON dla PHP |@home]
- [NEON dla JavaScriptu |https://github.com/matej21/neon-js]
- [NEON dla Pythona |https://github.com/paveldedik/neon-py].


Składnia
========

Plik napisany w NEON-ie reprezentuje zwykle sekwencję albo mapowanie.


Mapowania
---------
Mapowanie to zbiór par klucz-wartość; w PHP nazywałoby się tablicą asocjacyjną. Każda para zapisywana jest jako `klucz: wartość`, spacja po `:` jest wymagana. Wartością może być cokolwiek: ciąg, liczba, wartość logiczna, null, sekwencja albo kolejne mapowanie.

```neon
street: 742 Evergreen Terrace
city: Springfield
country: USA
```

W PHP tę samą strukturę zapisalibyśmy jako:

```php
[ // PHP
	'street' => '742 Evergreen Terrace',
	'city' => 'Springfield',
	'country' => 'USA',
]
```

Zapis ten nazywa się blokowym, bo wszystkie pozycje są w osobnych liniach i mają to samo wcięcie (w tym przypadku żadne). NEON wspiera też zapis inline dla mapowania, który zamykany jest w nawiasach klamrowych, wcięcia nie odgrywają roli, a separatorem elementów jest albo przecinek, albo złamanie linii:

```neon
{street: 742 Evergreen Terrace, city: Springfield, country: USA}
```

To samo zapisane w wielu liniach (wcięcia nie mają znaczenia):

```neon
{
	street: 742 Evergreen Terrace
		city: Springfield, country: USA
}
```

Alternatywnie zamiast <code>: </code> można użyć `=`, zarówno w zapisie blokowym, jak i inline:

```neon
{street=742 Evergreen Terrace, city=Springfield, country=USA}
```


Sekwencje
---------
Sekwencje to w PHP tablice indeksowane. Zapisywane są jako linie zaczynające się myślnikiem `-`, po którym następuje spacja. Znów wartością może być cokolwiek: ciąg, liczba, wartość logiczna, null, sekwencja albo kolejne mapowanie.

```neon
- Cat
- Dog
- Goldfish
```

W PHP tę samą strukturę zapisalibyśmy jako:

```php
[ // PHP
	'Cat',
	'Dog',
	'Goldfish',
]
```

Zapis ten nazywa się blokowym, bo wszystkie pozycje są w osobnych liniach i mają to samo wcięcie (w tym przypadku żadne). NEON wspiera też zapis inline dla sekwencji, który zamykany jest w nawiasach kwadratowych, wcięcia nie odgrywają roli, a separatorem elementów jest albo przecinek, albo złamanie linii:

```neon
[Cat, Dog, Goldfish]
```

To samo zapisane w wielu liniach (wcięcia nie mają znaczenia):

```neon
[
	Cat, Dog
		Goldfish
]
```

Myślników (punktorów) nie da się używać w zapisie inline.


Kombinacje
----------
Wartościami mapowań i sekwencji mogą być inne mapowania i sekwencje. Główną rolę odgrywa poziom wcięcia. W poniższym przykładzie myślnik oznaczający pozycje sekwencji ma większe wcięcie niż klucz `pets`, więc pozycje stają się wartością pierwszej linii:

```neon
pets:
   - Cat
   - Dog
cars:
   - Volvo
   - Skoda
```

W PHP tę samą strukturę zapisalibyśmy jako:

```php
[ // PHP
	'pets' => [
		'Cat',
		'Dog',
	],
	'cars' => [
		'Volvo',
		'Skoda',
	],
]
```

Zapis blokowy i inline można łączyć:

```neon
pets: [Cat, Dog]
cars: [
	Volvo,
	Skoda,
]
```

Zapisu blokowego nie da się użyć wewnątrz zapisu inline; to nie zadziała:

```neon
item: [
	pets:
	 - Cat     # TO NIE JEST MOŻLIWE!!!
	 - Dog
]
```

W poprzednim przypadku zapisaliśmy mapowanie, którego elementami były sekwencje. Spróbujmy teraz odwrotnie i utwórzmy sekwencję zawierającą mapowania:

```neon
-
	name: John
	age: 35
-
	name: Peter
	age: 28
```

Myślniki nie muszą być w osobnych liniach, można umieścić je też tak:

```neon
- name: John
  age: 35
- name: Peter
  age: 28
```

To od Ciebie zależy, czy wyrównasz klucze w kolumnie spacjami, czy użyjesz tabulatora.

Ponieważ PHP używa dla mapowań i sekwencji tej samej struktury (czyli tablic), oba da się połączyć. Wcięcie jest tym razem takie samo:

```neon
- Cat
street: 742 Evergreen Terrace
- Goldfish
```

W PHP tę samą strukturę zapisalibyśmy jako:

```php
[ // PHP
	'Cat',
	'street' => '742 Evergreen Terrace',
	'Goldfish',
]
```


Ciągi
-----
Ciągi w NEON-ie można zamykać w apostrofach albo cudzysłowach. Ale jak widzisz, mogą też być bez nich.

```neon
- An unquoted string in NEON
- 'A single-quoted string in NEON'
- "A double-quoted string in NEON"
```

Jeśli ciąg zawiera znaki `` # " ' ` , : = - [ ] { } ( ) ``, które mogłyby zostać pomylone ze składnią NEON-a, musi być zamknięty w cudzysłowach albo apostrofach. Zalecamy używanie apostrofów, bo nie używają escapowania. Jeśli musisz umieścić w takim ciągu apostrof, zdubluj go:

```neon
'A single quote '' inside a single-quoted string'
```

Cudzysłowy pozwalają używać sekwencji escape do zapisania znaków specjalnych za pomocą odwrotnych ukośników `\`. Wspierane są wszystkie sekwencje escape wspierane przez format JSON, plus `\_`, które reprezentuje twardą spację, czyli `\u00A0`.

```neon
- "\t \n \r \f \b \" \\ \/ \_"
- "\u00A9"
```

Są jeszcze inne przypadki, w których trzeba zamknąć ciągi w cudzysłowach:
- zaczynają się albo kończą spacjami
- wyglądają jak liczby, wartości logiczne albo null
- NEON zinterpretowałby je jako [daty |#Daty]


Ciągi wieloliniowe
------------------

Ciąg wieloliniowy zaczyna się i kończy potrójnymi apostrofami w osobnych liniach. Wcięcie pierwszej linii jest ignorowane dla wszystkich linii:

```neon
'''
	first line
		second line
	third line
	'''
```

W PHP zapisalibyśmy to samo jako:

```php
"first line\n\tsecond line\nthird line" // PHP
```

Sekwencje escape działają tylko dla ciągów zamkniętych w cudzysłowach zamiast apostrofów:

```neon
"""
	Copyright \u00A9
"""
```


Liczby
------
NEON rozumie liczby zapisane w notacji naukowej, a także liczby w systemie binarnym, ósemkowym i szesnastkowym:

```neon
- 12         # liczba całkowita
- 12.3       # liczba zmiennoprzecinkowa
- +1.2e-34   # liczba wykładnicza

- 0b11010    # liczba binarna
- 0o666      # liczba ósemkowa
- 0x7A       # liczba szesnastkowa
```


Nulle
-----
Null można wyrazić w NEON-ie za pomocą `null` albo przez pominięcie wartości. Dozwolone są też warianty z wielką pierwszą literą albo wszystkimi wielkimi literami (`Null`, `NULL`).

```neon
a: null
b:
```


Wartości logiczne
-----------------
Wartości logiczne wyraża się w NEON-ie za pomocą `true` / `false` albo `yes` / `no`. Dozwolone są też warianty z wielką pierwszą literą albo wszystkimi wielkimi literami (`True`, `TRUE`, `False`, `FALSE`, `Yes`, `YES`, `No`, `NO`).

```neon
[true, TRUE, True, false, yes, no]
```


Daty
----
NEON używa do wyrażania dat poniższych formatów i automatycznie konwertuje je na obiekty `DateTimeImmutable`:

```neon
- 2016-06-03                  # data
- 2016-06-03 19:00:00         # data i czas
- 2016-06-03 19:00:00.1234    # data i mikroczas
- 2016-06-03 19:00:00 +0200   # data, czas i strefa czasowa
- 2016-06-03 19:00:00 +02:00  # data, czas i strefa czasowa
```


Encje
-----
Encja to struktura przypominająca wywołanie funkcji:

```neon
Column(type: int, nulls: yes)
```

W PHP parsowana jest jako obiekt [api:Nette\Neon\Entity]:

```php
// PHP
new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true])
```

Encje można też łączyć w łańcuch:

```neon
Column(type: int, nulls: yes) Field(id: 1)
```

Co w PHP parsowane jest tak:

```php
// 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]),
])
```

Wewnątrz nawiasów obowiązują reguły zapisu inline używanego dla mapowań i sekwencji, więc może być wieloliniowy, a przecinki nie są konieczne:

```neon
Column(
	type: int
	nulls: yes
)
```


Komentarze
----------
Komentarze zaczynają się od `#`, a wszystkie kolejne znaki na prawo są ignorowane:

```neon
# ta linia zostanie zignorowana przez interpreter
street: 742 Evergreen Terrace
city: Springfield  # to też jest ignorowane
country: USA
```


NEON kontra JSON
================
JSON to podzbiór NEON-a. Każdy JSON da się więc sparsować jako NEON:

```neon
{
"php": {
	"date.timezone": "Europe\/Prague",
	"zlib.output_compression": true
},
"database": {
	"driver": "mysql",
	"username": "root",
	"password": "password123"
},
"users": [
	"Dave", "Kryten", "Rimmer"
]
}
```

A co, gdybyśmy pominęli cudzysłowy?

```neon
{
php: {
	date.timezone: Europe/Prague,
	zlib.output_compression: true
},
database: {
	driver: mysql,
	username: root,
	password: password123
},
users: [
	Dave, Kryten, Rimmer
]
}
```

A co z klamrami i przecinkami?

```neon
php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: password123

users: [
	Dave, Kryten, Rimmer
]
```

Czy listy z punktorami nie są czytelniejsze?

```neon
php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: password123

users:
	- Dave
	- Kryten
	- Rimmer
```

Dodamy komentarze?

```neon
# 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
```

Hurra, znasz już składnię NEON-a!


{{description: NEON to przyjazny człowiekowi język serializacji danych. Jest podobny do YAML-a. Główna różnica polega na tym, że NEON wspiera "encje" i pozwala używać tabulatorów do wcięć.}}

Format NEON

NEON to czytelny dla człowieka format danych strukturalnych. W Nette używany jest do plików konfiguracyjnych. Używa się go też do danych strukturalnych, jak ustawienia, tłumaczenia językowe itd. Wypróbuj go w piaskownicy.

NEON to skrót od Nette Object Notation. Jest mniej złożony i uciążliwy niż XML czy JSON, ale daje podobne możliwości. Jest bardzo podobny do YAML-a. Główną zaletą jest to, że NEON ma tak zwane encje, dzięki którym konfiguracja usług DI jest taka sexy. I pozwala używać tabulatorów do wcięć.

NEON od podstaw zbudowany jest tak, żeby był łatwy w użyciu.

Integracja

Składnia

Plik napisany w NEON-ie reprezentuje zwykle sekwencję albo mapowanie.

Mapowania

Mapowanie to zbiór par klucz-wartość; w PHP nazywałoby się tablicą asocjacyjną. Każda para zapisywana jest jako klucz: wartość, spacja po : jest wymagana. Wartością może być cokolwiek: ciąg, liczba, wartość logiczna, null, sekwencja albo kolejne mapowanie.

street: 742 Evergreen Terrace
city: Springfield
country: USA

W PHP tę samą strukturę zapisalibyśmy jako:

[ // PHP
	'street' => '742 Evergreen Terrace',
	'city' => 'Springfield',
	'country' => 'USA',
]

Zapis ten nazywa się blokowym, bo wszystkie pozycje są w osobnych liniach i mają to samo wcięcie (w tym przypadku żadne). NEON wspiera też zapis inline dla mapowania, który zamykany jest w nawiasach klamrowych, wcięcia nie odgrywają roli, a separatorem elementów jest albo przecinek, albo złamanie linii:

{street: 742 Evergreen Terrace, city: Springfield, country: USA}

To samo zapisane w wielu liniach (wcięcia nie mają znaczenia):

{
	street: 742 Evergreen Terrace
		city: Springfield, country: USA
}

Alternatywnie zamiast : można użyć =, zarówno w zapisie blokowym, jak i inline:

{street=742 Evergreen Terrace, city=Springfield, country=USA}

Sekwencje

Sekwencje to w PHP tablice indeksowane. Zapisywane są jako linie zaczynające się myślnikiem -, po którym następuje spacja. Znów wartością może być cokolwiek: ciąg, liczba, wartość logiczna, null, sekwencja albo kolejne mapowanie.

- Cat
- Dog
- Goldfish

W PHP tę samą strukturę zapisalibyśmy jako:

[ // PHP
	'Cat',
	'Dog',
	'Goldfish',
]

Zapis ten nazywa się blokowym, bo wszystkie pozycje są w osobnych liniach i mają to samo wcięcie (w tym przypadku żadne). NEON wspiera też zapis inline dla sekwencji, który zamykany jest w nawiasach kwadratowych, wcięcia nie odgrywają roli, a separatorem elementów jest albo przecinek, albo złamanie linii:

[Cat, Dog, Goldfish]

To samo zapisane w wielu liniach (wcięcia nie mają znaczenia):

[
	Cat, Dog
		Goldfish
]

Myślników (punktorów) nie da się używać w zapisie inline.

Kombinacje

Wartościami mapowań i sekwencji mogą być inne mapowania i sekwencje. Główną rolę odgrywa poziom wcięcia. W poniższym przykładzie myślnik oznaczający pozycje sekwencji ma większe wcięcie niż klucz pets, więc pozycje stają się wartością pierwszej linii:

pets:
   - Cat
   - Dog
cars:
   - Volvo
   - Skoda

W PHP tę samą strukturę zapisalibyśmy jako:

[ // PHP
	'pets' => [
		'Cat',
		'Dog',
	],
	'cars' => [
		'Volvo',
		'Skoda',
	],
]

Zapis blokowy i inline można łączyć:

pets: [Cat, Dog]
cars: [
	Volvo,
	Skoda,
]

Zapisu blokowego nie da się użyć wewnątrz zapisu inline; to nie zadziała:

item: [
	pets:
	 - Cat     # TO NIE JEST MOŻLIWE!!!
	 - Dog
]

W poprzednim przypadku zapisaliśmy mapowanie, którego elementami były sekwencje. Spróbujmy teraz odwrotnie i utwórzmy sekwencję zawierającą mapowania:

-
	name: John
	age: 35
-
	name: Peter
	age: 28

Myślniki nie muszą być w osobnych liniach, można umieścić je też tak:

- name: John
  age: 35
- name: Peter
  age: 28

To od Ciebie zależy, czy wyrównasz klucze w kolumnie spacjami, czy użyjesz tabulatora.

Ponieważ PHP używa dla mapowań i sekwencji tej samej struktury (czyli tablic), oba da się połączyć. Wcięcie jest tym razem takie samo:

- Cat
street: 742 Evergreen Terrace
- Goldfish

W PHP tę samą strukturę zapisalibyśmy jako:

[ // PHP
	'Cat',
	'street' => '742 Evergreen Terrace',
	'Goldfish',
]

Ciągi

Ciągi w NEON-ie można zamykać w apostrofach albo cudzysłowach. Ale jak widzisz, mogą też być bez nich.

- An unquoted string in NEON
- 'A single-quoted string in NEON'
- "A double-quoted string in NEON"

Jeśli ciąg zawiera znaki ` # " ' ` , : = - [ ] { } ( ) `, które mogłyby zostać pomylone ze składnią NEON-a, musi być zamknięty w cudzysłowach albo apostrofach. Zalecamy używanie apostrofów, bo nie używają escapowania. Jeśli musisz umieścić w takim ciągu apostrof, zdubluj go:

'A single quote '' inside a single-quoted string'

Cudzysłowy pozwalają używać sekwencji escape do zapisania znaków specjalnych za pomocą odwrotnych ukośników \. Wspierane są wszystkie sekwencje escape wspierane przez format JSON, plus \_, które reprezentuje twardą spację, czyli \u00A0.

- "\t \n \r \f \b \" \\ \/ \_"
- "\u00A9"

Są jeszcze inne przypadki, w których trzeba zamknąć ciągi w cudzysłowach:

  • zaczynają się albo kończą spacjami
  • wyglądają jak liczby, wartości logiczne albo null
  • NEON zinterpretowałby je jako daty

Ciągi wieloliniowe

Ciąg wieloliniowy zaczyna się i kończy potrójnymi apostrofami w osobnych liniach. Wcięcie pierwszej linii jest ignorowane dla wszystkich linii:

'''
	first line
		second line
	third line
	'''

W PHP zapisalibyśmy to samo jako:

"first line\n\tsecond line\nthird line" // PHP

Sekwencje escape działają tylko dla ciągów zamkniętych w cudzysłowach zamiast apostrofów:

"""
	Copyright \u00A9
"""

Liczby

NEON rozumie liczby zapisane w notacji naukowej, a także liczby w systemie binarnym, ósemkowym i szesnastkowym:

- 12         # liczba całkowita
- 12.3       # liczba zmiennoprzecinkowa
- +1.2e-34   # liczba wykładnicza

- 0b11010    # liczba binarna
- 0o666      # liczba ósemkowa
- 0x7A       # liczba szesnastkowa

Nulle

Null można wyrazić w NEON-ie za pomocą null albo przez pominięcie wartości. Dozwolone są też warianty z wielką pierwszą literą albo wszystkimi wielkimi literami (Null, NULL).

a: null
b:

Wartości logiczne

Wartości logiczne wyraża się w NEON-ie za pomocą true / false albo yes / no. Dozwolone są też warianty z wielką pierwszą literą albo wszystkimi wielkimi literami (True, TRUE, False, FALSE, Yes, YES, No, NO).

[true, TRUE, True, false, yes, no]

Daty

NEON używa do wyrażania dat poniższych formatów i automatycznie konwertuje je na obiekty DateTimeImmutable:

- 2016-06-03                  # data
- 2016-06-03 19:00:00         # data i czas
- 2016-06-03 19:00:00.1234    # data i mikroczas
- 2016-06-03 19:00:00 +0200   # data, czas i strefa czasowa
- 2016-06-03 19:00:00 +02:00  # data, czas i strefa czasowa

Encje

Encja to struktura przypominająca wywołanie funkcji:

Column(type: int, nulls: yes)

W PHP parsowana jest jako obiekt Nette\Neon\Entity:

// PHP
new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true])

Encje można też łączyć w łańcuch:

Column(type: int, nulls: yes) Field(id: 1)

Co w PHP parsowane jest tak:

// 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]),
])

Wewnątrz nawiasów obowiązują reguły zapisu inline używanego dla mapowań i sekwencji, więc może być wieloliniowy, a przecinki nie są konieczne:

Column(
	type: int
	nulls: yes
)

Komentarze

Komentarze zaczynają się od #, a wszystkie kolejne znaki na prawo są ignorowane:

# ta linia zostanie zignorowana przez interpreter
street: 742 Evergreen Terrace
city: Springfield  # to też jest ignorowane
country: USA

NEON kontra JSON

JSON to podzbiór NEON-a. Każdy JSON da się więc sparsować jako NEON:

{
"php": {
	"date.timezone": "Europe\/Prague",
	"zlib.output_compression": true
},
"database": {
	"driver": "mysql",
	"username": "root",
	"password": "password123"
},
"users": [
	"Dave", "Kryten", "Rimmer"
]
}

A co, gdybyśmy pominęli cudzysłowy?

{
php: {
	date.timezone: Europe/Prague,
	zlib.output_compression: true
},
database: {
	driver: mysql,
	username: root,
	password: password123
},
users: [
	Dave, Kryten, Rimmer
]
}

A co z klamrami i przecinkami?

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: password123

users: [
	Dave, Kryten, Rimmer
]

Czy listy z punktorami nie są czytelniejsze?

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: password123

users:
	- Dave
	- Kryten
	- Rimmer

Dodamy komentarze?

# 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

Hurra, znasz już składnię NEON-a!