/
modules.texy
183 lines (133 loc) · 7.55 KB
/
modules.texy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
Modules
*******
.[perex]
Les modules apportent de la clarté aux applications Nette en facilitant la division en unités logiques.
À l'instar de l'organisation des fichiers en dossiers sur un disque dur, Nette permet de diviser les présentateurs, les modèles et les autres classes auxiliaires en modules. Comment cela fonctionne-t-il en pratique ? Simplement en incorporant de nouveaux sous-répertoires dans la structure. Voici un exemple de structure avec deux modules, Front et 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
│ │ └── ...
\--
Cette structure de répertoires se reflète dans les espaces de noms des classes. Ainsi, par exemple, `DashboardPresenter` est situé dans l'espace de noms `App\UI\Admin\Dashboard`:
```php
namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
// ...
}
```
Dans l'application, nous faisons référence au présentateur `Dashboard` dans le module `Admin` en utilisant la notation des deux points comme `Admin:Dashboard`. Pour son action `default`, nous l'appelons `Admin:Dashboard:default`.
La structure présentée n'est pas rigide ; vous pouvez [l'adapter entièrement à vos besoins |#mapping] dans la configuration. .[tip]
Les modules peuvent inclure tous les autres fichiers, tels que les composants et les classes auxiliaires, en plus des présentateurs et des modèles. Si vous vous demandez où placer ces derniers, envisagez d'utiliser un dossier `Accessory`:
/--pre
app/
├── UI/
│ ├── Admin/
│ │ ├── <b>Accessory/</b>
│ │ │ ├── FormFactory.php
│ │ │ └── AdminLayout.php
│ │ ├── Dashboard/
│ │ └── ...
\--
Modules imbriqués .[#toc-nested-modules]
----------------------------------------
Les modules peuvent avoir plusieurs niveaux d'imbrication, comme la structure d'un répertoire sur un disque :
/--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
│ │ └── ...
\--
Le module `Blog` est divisé en sous-modules `Admin` et `Front`. Cela se reflète également dans les espaces de noms, qui apparaissent alors comme `App\UI\Blog\Admin` et similaires. Pour désigner le présentateur `Dashboard` au sein du sous-module `Admin`, nous l'appelons `Blog:Admin:Dashboard`.
L'imbrication peut être aussi poussée que nécessaire, ce qui permet de créer des sous-sous-modules.
Par exemple, si dans l'administration vous avez de nombreux présentateurs liés à la gestion des commandes, tels que `OrderDetail`, `OrderEdit`, `OrderDispatch`, etc., vous pouvez créer un module `Order` dans lequel les présentateurs tels que `Detail`, `Edit`, `Dispatch`, et d'autres seront organisés.
Création de liens .[#toc-creating-links]
----------------------------------------
Les liens dans les modèles de présentateur sont relatifs au module actuel. Ainsi, le lien `Foo:default` mène au présentateur `Foo` dans le même module que le présentateur actuel. Si le module actuel est `Front`, par exemple, le lien est le suivant :
```latte
<a n:href="Product:show">link to Front:Product:show</a>
```
Un lien est relatif même s'il inclut le nom d'un module, qui est alors considéré comme un sous-module :
```latte
<a n:href="Shop:Product:show">link to Front:Shop:Product:show</a>
```
Les liens absolus sont écrits de manière analogue aux chemins absolus sur le disque, mais avec des deux-points à la place des barres obliques. Ainsi, un lien absolu commence par un deux-points :
```latte
<a n:href=":Admin:Product:show">link to Admin:Product:show</a>
```
Pour savoir si nous sommes dans un certain module ou son sous-module, nous pouvons utiliser la fonction `isModuleCurrent(moduleName)`.
```latte
<li n:class="isModuleCurrent('MyEshop:Users') ? active">
<a n:href="Product:">...</a>
</li>
```
Acheminement .[#toc-routing]
----------------------------
Voir le [chapitre sur le routage |routing#Modules].
Cartographie .[#toc-mapping]
----------------------------
Le mappage définit les règles permettant de dériver le nom de la classe à partir du nom du présentateur. Ces règles sont spécifiées dans la [configuration |configuration] sous la clé `application › mapping`.
Les structures de répertoire mentionnées plus haut sur cette page sont basées sur la correspondance suivante :
```neon
application:
mapping: App\UI\*\**Presenter
```
Comment fonctionne la cartographie ? Pour mieux comprendre, imaginons d'abord une application sans modules. Nous voulons que les classes de présentateurs relèvent de l'espace de noms `App\UI`, de sorte que le présentateur `Home` soit associé à la classe `App\UI\HomePresenter`. Cette configuration permet d'atteindre cet objectif :
```neon
application:
mapping: App\UI\*Presenter
```
Ce mappage fonctionne en remplaçant l'astérisque du masque `App\UI\*Presenter` par le nom du présentateur `Home`, ce qui donne le nom de classe final `App\UI\HomePresenter`. C'est simple !
Cependant, comme vous pouvez le voir dans les exemples de ce chapitre et d'autres chapitres, nous plaçons les classes de présentateurs dans des sous-répertoires éponymes, par exemple, le présentateur `Home` est associé à la classe `App\UI\Home\HomePresenter`. Pour ce faire, il suffit de doubler l'astérisque (Nette Application 3.2 requise) :
```neon
application:
mapping: App\UI\**Presenter
```
Passons maintenant au mappage des présentateurs dans les modules. Nous pouvons définir des correspondances spécifiques pour chaque module :
```neon
application:
mapping:
Front: App\UI\Front\**Presenter
Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
Selon cette configuration, le présentateur `Front:Home` correspond à la classe `App\UI\Front\Home\HomePresenter`, tandis que le présentateur `Api:OAuth` correspond à la classe `App\Api\OAuthPresenter`.
Étant donné que les modules `Front` et `Admin` ont une approche de mappage similaire et qu'il est probable qu'il y ait d'autres modules de ce type, il est possible de créer une règle générale qui les remplace. Un nouvel astérisque pour le module est ajouté au masque de classe :
```neon
application:
mapping:
*: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
Pour les modules imbriqués à plusieurs niveaux, tels que le présentateur `Admin:User:Edit`, le segment astérisque se répète pour chaque niveau, ce qui donne la classe `App\UI\Admin\User\Edit\EditPresenter`.
Une autre notation consiste à utiliser un tableau composé de trois segments au lieu d'une chaîne. Cette notation est équivalente à la précédente :
```neon
application:
mapping:
*: [App\UI, *, **Presenter]
Api: [App\Api, '', *Presenter]
```
Si nous n'avons qu'une seule règle dans la configuration, la règle générale, nous pouvons l'écrire brièvement :
```neon
application:
mapping: App\UI\*\**Presenter
```