Nette Documentation Preview

syntax
Ενότητες
********

.[perex]
Οι ενότητες φέρνουν σαφήνεια στις εφαρμογές Nette διευκολύνοντας τον εύκολο διαχωρισμό σε λογικές μονάδες.

Παρόμοια με την οργάνωση των αρχείων σε φακέλους σε ένα σκληρό δίσκο, στη Nette μπορούμε να χωρίσουμε τους παρουσιαστές, τα πρότυπα και άλλες βοηθητικές κλάσεις σε ενότητες. Πώς λειτουργεί αυτό στην πράξη; Απλά με την ενσωμάτωση νέων υποκαταλόγων στη δομή. Ακολουθεί ένα παράδειγμα δομής με δύο ενότητες, Front και Admin:

/--pre
app/
├── UI/
│   ├── <b>Admin/</b>            ← Admin module
│   │   ├── @layout.latte
│   │   ├── Dashboard/
│   │   │   ├── DashboardPresenter.php
│   │   │   └── default.latte
│   │   └── ...
│   ├── <b>Front/</b>            ← Front module
│   │   ├── @layout.latte
│   │   ├── Home/
│   │   │   ├── HomePresenter.php
│   │   │   └── default.latte
│   │   └── ...
\--

Αυτή η δομή καταλόγου αντικατοπτρίζεται στα namespaces των κλάσεων, έτσι για παράδειγμα, η `DashboardPresenter` βρίσκεται στο namespace `App\UI\Admin\Dashboard`:

```php
namespace App\UI\Admin\Dashboard;

class DashboardPresenter extends Nette\Application\UI\Presenter
{
	// ...
}
```

Στην εφαρμογή, αναφερόμαστε στον παρουσιαστή `Dashboard` μέσα στην ενότητα `Admin` χρησιμοποιώντας τον συμβολισμό της άνω και κάτω τελείας ως `Admin:Dashboard`. Για τη δράση του `default`, αναφερόμαστε σε αυτόν ως `Admin:Dashboard:default`.

Η δομή που παρουσιάζεται δεν είναι άκαμπτη- μπορείτε να [την προσαρμόσετε πλήρως στις ανάγκες σας |#mapping] στη διαμόρφωση. .[tip]

Οι ενότητες μπορούν να περιλαμβάνουν όλα τα άλλα αρχεία, όπως συστατικά και βοηθητικές κλάσεις, εκτός από τους παρουσιαστές και τα πρότυπα. Αν σκέφτεστε πού να τα τοποθετήσετε αυτά, σκεφτείτε να χρησιμοποιήσετε έναν φάκελο `Accessory`:

/--pre
app/
├── UI/
│   ├── Admin/
│   │   ├── <b>Accessory/</b>
│   │   │   ├── FormFactory.php
│   │   │   └── AdminLayout.php
│   │   ├── Dashboard/
│   │   └── ...
\--


Ενσωματωμένες ενότητες .[#toc-nested-modules]
---------------------------------------------

Οι ενότητες μπορούν να έχουν πολλαπλά επίπεδα ένθεσης, παρόμοια με μια δομή καταλόγου σε ένα δίσκο:

/--pre
app/
├── UI/
│   ├── <b>Blog/</b>             ← Blog module
│   │   ├── <b>Admin/</b>        ← Admin submodule
│   │   │   ├── Dashboard/
│   │   │   └── ...
│   │   ├── <b>Front/</b>        ← Front submodule
│   │   │   ├── @layout.latte
│   │   │   ├── Home/
│   │   │   └── ...
│   ├── <b>Forum/</b>            ← Forum module
│   │   └── ...
\--

Η ενότητα `Blog` χωρίζεται σε υποενότητες `Admin` και `Front`. Αυτό αντικατοπτρίζεται επίσης στα namespaces, τα οποία εμφανίζονται ως `App\UI\Blog\Admin` και παρόμοια. Για να αναφερθούμε στον παρουσιαστή `Dashboard` μέσα στην υποενότητα `Admin`, αναφερόμαστε σε αυτόν ως `Blog:Admin:Dashboard`.

Η φωλεοποίηση μπορεί να είναι όσο βαθιά χρειάζεται, επιτρέποντας τη δημιουργία υπο-υπομονάδων.

Για παράδειγμα, αν στη διαχείριση έχετε πολλούς παρουσιαστές που σχετίζονται με τη διαχείριση παραγγελιών, όπως `OrderDetail`, `OrderEdit`, `OrderDispatch`, κ.λπ., μπορείτε να δημιουργήσετε μια ενότητα `Order` στην οποία θα οργανωθούν παρουσιαστές όπως `Detail`, `Edit`, `Dispatch` και άλλοι.


Δημιουργία συνδέσμων .[#toc-creating-links]
-------------------------------------------

Οι σύνδεσμοι στα πρότυπα παρουσιαστή είναι σχετικοί με την τρέχουσα ενότητα. Έτσι, ο σύνδεσμος `Foo:default` οδηγεί στον παρουσιαστή `Foo` στην ίδια ενότητα με τον τρέχοντα παρουσιαστή. Εάν η τρέχουσα ενότητα είναι `Front`, για παράδειγμα, τότε ο σύνδεσμος έχει ως εξής:

```latte
<a n:href="Product:show">link to Front:Product:show</a>
```

Ένας σύνδεσμος είναι σχετικός ακόμη και αν περιλαμβάνει το όνομα μιας ενότητας, η οποία τότε θεωρείται υποενότητα:

```latte
<a n:href="Shop:Product:show">link to Front:Shop:Product:show</a>
```

Οι απόλυτοι σύνδεσμοι γράφονται ανάλογα με τις απόλυτες διαδρομές στο δίσκο, αλλά με άνω και κάτω τελεία αντί για κάθετους. Έτσι, ένας απόλυτος σύνδεσμος αρχίζει με άνω και κάτω τελεία:

```latte
<a n:href=":Admin:Product:show">link to Admin:Product:show</a>
```

Για να μάθουμε αν βρισκόμαστε σε μια συγκεκριμένη ενότητα ή υποενότητά της μπορούμε να χρησιμοποιήσουμε τη συνάρτηση `isModuleCurrent(moduleName)`.

```latte
<li n:class="isModuleCurrent('MyEshop:Users') ? active">
	<a n:href="Product:">...</a>
</li>
```


Δρομολόγηση .[#toc-routing]
---------------------------

Βλέπε [κεφάλαιο για τη δρομολόγηση |routing#Modules].


Χαρτογράφηση .[#toc-mapping]
----------------------------

Η αντιστοίχιση ορίζει τους κανόνες για την εξαγωγή του ονόματος της κλάσης από το όνομα του παρουσιαστή. Οι κανόνες αυτοί καθορίζονται στη [διαμόρφωση |configuration] στο κλειδί `application › mapping`.

Οι δομές καταλόγων που αναφέρθηκαν νωρίτερα σε αυτή τη σελίδα βασίζονται στην ακόλουθη αντιστοίχιση:

```neon
application:
	mapping: App\UI\*\**Presenter
```

Πώς λειτουργεί η χαρτογράφηση; Για καλύτερη κατανόηση, ας φανταστούμε πρώτα μια εφαρμογή χωρίς ενότητες. Θέλουμε οι κλάσεις του παρουσιαστή να υπάγονται στο χώρο ονομάτων `App\UI`, έτσι ώστε ο παρουσιαστής `Home` να αντιστοιχίζεται στην κλάση `App\UI\HomePresenter`. Αυτό μπορεί να επιτευχθεί με αυτή τη διαμόρφωση:

```neon
application:
	mapping: App\UI\*Presenter
```

Αυτή η αντιστοίχιση λειτουργεί αντικαθιστώντας τον αστερίσκο στη μάσκα `App\UI\*Presenter` με το όνομα του παρουσιαστή `Home`, με αποτέλεσμα το τελικό όνομα της κλάσης `App\UI\HomePresenter`. Απλό!

Ωστόσο, όπως μπορείτε να δείτε στα παραδείγματα σε αυτό και σε άλλα κεφάλαια, τοποθετούμε τις κλάσεις παρουσιαστή σε επώνυμους υποκαταλόγους, π.χ. ο παρουσιαστής `Home` αντιστοιχίζεται στην κλάση `App\UI\Home\HomePresenter`. Αυτό επιτυγχάνεται με τον διπλασιασμό του αστερίσκου (απαιτεί Nette Application 3.2):

```neon
application:
	mapping: App\UI\**Presenter
```

Τώρα, ας προχωρήσουμε στην αντιστοίχιση των παρουσιαστών σε ενότητες. Μπορούμε να ορίσουμε συγκεκριμένες αντιστοιχίσεις για κάθε ενότητα:

```neon
application:
	mapping:
		Front: App\UI\Front\**Presenter
		Admin: App\UI\Admin\**Presenter
		Api: App\Api\*Presenter
```

Σύμφωνα με αυτή τη διαμόρφωση, ο παρουσιαστής `Front:Home` αντιστοιχίζεται στην κλάση `App\UI\Front\Home\HomePresenter`, ενώ ο παρουσιαστής `Api:OAuth` αντιστοιχίζεται στην κλάση `App\Api\OAuthPresenter`.

Δεδομένου ότι οι ενότητες `Front` και `Admin` έχουν παρόμοια προσέγγιση αντιστοίχισης και είναι πιθανό να υπάρχουν περισσότερες τέτοιες ενότητες, είναι δυνατόν να δημιουργηθεί ένας γενικός κανόνας που να τις αντικαθιστά. Ένας νέος αστερίσκος για την ενότητα προστίθεται στη μάσκα κλάσης:

```neon
application:
	mapping:
		*: App\UI\*\**Presenter
		Api: App\Api\*Presenter
```

Για πολυεπίπεδες φωλιασμένες ενότητες, όπως ο παρουσιαστής `Admin:User:Edit`, το τμήμα αστερίσκου επαναλαμβάνεται για κάθε επίπεδο, με αποτέλεσμα την κλάση `App\UI\Admin\User\Edit\EditPresenter`.

Ένας εναλλακτικός συμβολισμός είναι η χρήση ενός πίνακα που αποτελείται από τρία τμήματα αντί για μια συμβολοσειρά. Αυτός ο συμβολισμός είναι ισοδύναμος με τον προηγούμενο:

```neon
application:
	mapping:
		*: [App\UI, *, **Presenter]
		Api: [App\Api, '', *Presenter]
```

Αν έχουμε μόνο έναν κανόνα στη διαμόρφωση, τον γενικό, μπορούμε να γράψουμε συνοπτικά:

```neon
application:
	mapping: App\UI\*\**Presenter
```

Ενότητες

Οι ενότητες φέρνουν σαφήνεια στις εφαρμογές Nette διευκολύνοντας τον εύκολο διαχωρισμό σε λογικές μονάδες.

Παρόμοια με την οργάνωση των αρχείων σε φακέλους σε ένα σκληρό δίσκο, στη Nette μπορούμε να χωρίσουμε τους παρουσιαστές, τα πρότυπα και άλλες βοηθητικές κλάσεις σε ενότητες. Πώς λειτουργεί αυτό στην πράξη; Απλά με την ενσωμάτωση νέων υποκαταλόγων στη δομή. Ακολουθεί ένα παράδειγμα δομής με δύο ενότητες, Front και Admin:

app/
├── UI/
│   ├── Admin/            ← Admin module
│   │   ├── @layout.latte
│   │   ├── Dashboard/
│   │   │   ├── DashboardPresenter.php
│   │   │   └── default.latte
│   │   └── ...
│   ├── Front/            ← Front module
│   │   ├── @layout.latte
│   │   ├── Home/
│   │   │   ├── HomePresenter.php
│   │   │   └── default.latte
│   │   └── ...

Αυτή η δομή καταλόγου αντικατοπτρίζεται στα namespaces των κλάσεων, έτσι για παράδειγμα, η DashboardPresenter βρίσκεται στο namespace App\UI\Admin\Dashboard:

namespace App\UI\Admin\Dashboard;

class DashboardPresenter extends Nette\Application\UI\Presenter
{
	// ...
}

Στην εφαρμογή, αναφερόμαστε στον παρουσιαστή Dashboard μέσα στην ενότητα Admin χρησιμοποιώντας τον συμβολισμό της άνω και κάτω τελείας ως Admin:Dashboard. Για τη δράση του default, αναφερόμαστε σε αυτόν ως Admin:Dashboard:default.

Η δομή που παρουσιάζεται δεν είναι άκαμπτη- μπορείτε να την προσαρμόσετε πλήρως στις ανάγκες σας στη διαμόρφωση.

Οι ενότητες μπορούν να περιλαμβάνουν όλα τα άλλα αρχεία, όπως συστατικά και βοηθητικές κλάσεις, εκτός από τους παρουσιαστές και τα πρότυπα. Αν σκέφτεστε πού να τα τοποθετήσετε αυτά, σκεφτείτε να χρησιμοποιήσετε έναν φάκελο Accessory:

app/
├── UI/
│   ├── Admin/
│   │   ├── Accessory/
│   │   │   ├── FormFactory.php
│   │   │   └── AdminLayout.php
│   │   ├── Dashboard/
│   │   └── ...

Ενσωματωμένες ενότητες

Οι ενότητες μπορούν να έχουν πολλαπλά επίπεδα ένθεσης, παρόμοια με μια δομή καταλόγου σε ένα δίσκο:

app/
├── UI/
│   ├── Blog/             ← Blog module
│   │   ├── Admin/        ← Admin submodule
│   │   │   ├── Dashboard/
│   │   │   └── ...
│   │   ├── Front/        ← Front submodule
│   │   │   ├── @layout.latte
│   │   │   ├── Home/
│   │   │   └── ...
│   ├── Forum/            ← Forum module
│   │   └── ...

Η ενότητα Blog χωρίζεται σε υποενότητες Admin και Front. Αυτό αντικατοπτρίζεται επίσης στα namespaces, τα οποία εμφανίζονται ως App\UI\Blog\Admin και παρόμοια. Για να αναφερθούμε στον παρουσιαστή Dashboard μέσα στην υποενότητα Admin, αναφερόμαστε σε αυτόν ως Blog:Admin:Dashboard.

Η φωλεοποίηση μπορεί να είναι όσο βαθιά χρειάζεται, επιτρέποντας τη δημιουργία υπο-υπομονάδων.

Για παράδειγμα, αν στη διαχείριση έχετε πολλούς παρουσιαστές που σχετίζονται με τη διαχείριση παραγγελιών, όπως OrderDetail, OrderEdit, OrderDispatch, κ.λπ., μπορείτε να δημιουργήσετε μια ενότητα Order στην οποία θα οργανωθούν παρουσιαστές όπως Detail, Edit, Dispatch και άλλοι.

Οι σύνδεσμοι στα πρότυπα παρουσιαστή είναι σχετικοί με την τρέχουσα ενότητα. Έτσι, ο σύνδεσμος Foo:default οδηγεί στον παρουσιαστή Foo στην ίδια ενότητα με τον τρέχοντα παρουσιαστή. Εάν η τρέχουσα ενότητα είναι Front, για παράδειγμα, τότε ο σύνδεσμος έχει ως εξής:

<a n:href="Product:show">link to Front:Product:show</a>

Ένας σύνδεσμος είναι σχετικός ακόμη και αν περιλαμβάνει το όνομα μιας ενότητας, η οποία τότε θεωρείται υποενότητα:

<a n:href="Shop:Product:show">link to Front:Shop:Product:show</a>

Οι απόλυτοι σύνδεσμοι γράφονται ανάλογα με τις απόλυτες διαδρομές στο δίσκο, αλλά με άνω και κάτω τελεία αντί για κάθετους. Έτσι, ένας απόλυτος σύνδεσμος αρχίζει με άνω και κάτω τελεία:

<a n:href=":Admin:Product:show">link to Admin:Product:show</a>

Για να μάθουμε αν βρισκόμαστε σε μια συγκεκριμένη ενότητα ή υποενότητά της μπορούμε να χρησιμοποιήσουμε τη συνάρτηση isModuleCurrent(moduleName).

<li n:class="isModuleCurrent('MyEshop:Users') ? active">
	<a n:href="Product:">...</a>
</li>

Δρομολόγηση

Βλέπε κεφάλαιο για τη δρομολόγηση.

Χαρτογράφηση

Η αντιστοίχιση ορίζει τους κανόνες για την εξαγωγή του ονόματος της κλάσης από το όνομα του παρουσιαστή. Οι κανόνες αυτοί καθορίζονται στη διαμόρφωση στο κλειδί application › mapping.

Οι δομές καταλόγων που αναφέρθηκαν νωρίτερα σε αυτή τη σελίδα βασίζονται στην ακόλουθη αντιστοίχιση:

application:
	mapping: App\UI\*\**Presenter

Πώς λειτουργεί η χαρτογράφηση; Για καλύτερη κατανόηση, ας φανταστούμε πρώτα μια εφαρμογή χωρίς ενότητες. Θέλουμε οι κλάσεις του παρουσιαστή να υπάγονται στο χώρο ονομάτων App\UI, έτσι ώστε ο παρουσιαστής Home να αντιστοιχίζεται στην κλάση App\UI\HomePresenter. Αυτό μπορεί να επιτευχθεί με αυτή τη διαμόρφωση:

application:
	mapping: App\UI\*Presenter

Αυτή η αντιστοίχιση λειτουργεί αντικαθιστώντας τον αστερίσκο στη μάσκα App\UI\*Presenter με το όνομα του παρουσιαστή Home, με αποτέλεσμα το τελικό όνομα της κλάσης App\UI\HomePresenter. Απλό!

Ωστόσο, όπως μπορείτε να δείτε στα παραδείγματα σε αυτό και σε άλλα κεφάλαια, τοποθετούμε τις κλάσεις παρουσιαστή σε επώνυμους υποκαταλόγους, π.χ. ο παρουσιαστής Home αντιστοιχίζεται στην κλάση App\UI\Home\HomePresenter. Αυτό επιτυγχάνεται με τον διπλασιασμό του αστερίσκου (απαιτεί Nette Application 3.2):

application:
	mapping: App\UI\**Presenter

Τώρα, ας προχωρήσουμε στην αντιστοίχιση των παρουσιαστών σε ενότητες. Μπορούμε να ορίσουμε συγκεκριμένες αντιστοιχίσεις για κάθε ενότητα:

application:
	mapping:
		Front: App\UI\Front\**Presenter
		Admin: App\UI\Admin\**Presenter
		Api: App\Api\*Presenter

Σύμφωνα με αυτή τη διαμόρφωση, ο παρουσιαστής Front:Home αντιστοιχίζεται στην κλάση App\UI\Front\Home\HomePresenter, ενώ ο παρουσιαστής Api:OAuth αντιστοιχίζεται στην κλάση App\Api\OAuthPresenter.

Δεδομένου ότι οι ενότητες Front και Admin έχουν παρόμοια προσέγγιση αντιστοίχισης και είναι πιθανό να υπάρχουν περισσότερες τέτοιες ενότητες, είναι δυνατόν να δημιουργηθεί ένας γενικός κανόνας που να τις αντικαθιστά. Ένας νέος αστερίσκος για την ενότητα προστίθεται στη μάσκα κλάσης:

application:
	mapping:
		*: App\UI\*\**Presenter
		Api: App\Api\*Presenter

Για πολυεπίπεδες φωλιασμένες ενότητες, όπως ο παρουσιαστής Admin:User:Edit, το τμήμα αστερίσκου επαναλαμβάνεται για κάθε επίπεδο, με αποτέλεσμα την κλάση App\UI\Admin\User\Edit\EditPresenter.

Ένας εναλλακτικός συμβολισμός είναι η χρήση ενός πίνακα που αποτελείται από τρία τμήματα αντί για μια συμβολοσειρά. Αυτός ο συμβολισμός είναι ισοδύναμος με τον προηγούμενο:

application:
	mapping:
		*: [App\UI, *, **Presenter]
		Api: [App\Api, '', *Presenter]

Αν έχουμε μόνο έναν κανόνα στη διαμόρφωση, τον γενικό, μπορούμε να γράψουμε συνοπτικά:

application:
	mapping: App\UI\*\**Presenter