/
modules.texy
147 lines (104 loc) · 6.31 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
Módulos
*******
.[perex]
En Nette, los módulos representan las unidades lógicas que componen una aplicación. Incluyen presentadores, plantillas, posiblemente también componentes y clases modelo.
Un directorio para los presentadores y otro para las plantillas no serían suficientes para los proyectos reales. Tener docenas de archivos en una carpeta es, como mínimo, desorganizado. ¿Cómo salir de ello? Simplemente los dividimos en subdirectorios en el disco y en espacios de nombres en el código. Y eso es exactamente lo que hacen los módulos de Nette.
Así que olvidémonos de una única carpeta para presentadores y plantillas y en su lugar creemos módulos, por ejemplo `Admin` y `Front`.
/--pre
<b>app/</b>
├── <del>Presenters/</del>
├── <b>Modules/</b> ← directorio con módulos
│ ├── <b>Admin/</b> ← módulo Admin
│ │ ├── <b>Presenters/</b> ← sus presentadores
│ │ │ ├── <b>DashboardPresenter.php</b>
│ │ │ └── <b>templates/</b>
│ └── <b>Front/</b> ← módulo Front
│ └── <b>Presenters/</b> ← sus presentadores
│ └── ...
\--
Esta estructura de directorios se reflejará en los espacios de nombres de las clases, así por ejemplo `DashboardPresenter` estará en el espacio de nombres `App\Modules\Admin\Presenters`:
```php
namespace App\Modules\Admin\Presenters;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
// ...
}
```
El presentador `Dashboard` dentro del módulo `Admin` es referenciado dentro de la aplicación usando la notación de dos puntos como `Admin:Dashboard`, y su acción `default` como `Admin:Dashboard:default`.
¿Y cómo sabe Nette que `Admin:Dashboard` representa la clase `App\Modules\Admin\Presenters\DashboardPresenter`? Esto se determina mediante el [mapeo |#mapping] en la configuración.
Por lo tanto, la estructura dada no es rígida y puede modificarla según sus necesidades.
Por supuesto, los módulos pueden contener todos los demás elementos además de presentadores y plantillas, como componentes, clases modelo, etc.
Módulos anidados .[#toc-nested-modules]
---------------------------------------
Los módulos no tienen por qué formar sólo una estructura plana, también puedes crear submódulos, por ejemplo:
/--pre
<b>app/</b>
├── <b>Modules/</b> ← directorio con módulos
│ ├── <b>Blog/</b> ← módulo Blog
│ │ ├── <b>Admin/</b> ← submódulo Admin
│ │ │ ├── <b>Presenters/</b>
│ │ │ └── ...
│ │ └── <b>Front/</b> ← submódulo Front
│ │ ├── <b>Presenters/</b>
│ │ └── ...
│ ├── <b>Forum/</b> ← módulo Forum
│ │ └── ...
\--
Así, el módulo `Blog` se divide en los submódulos `Admin` y `Front`. De nuevo, esto se reflejará en los espacios de nombres, que serán `App\Modules\Blog\Admin\Presenters`, etc. El presentador `Dashboard` dentro del submódulo se denomina `Blog:Admin:Dashboard`.
El anidamiento puede ser tan profundo como se desee, por lo que pueden crearse submódulos.
Creación de enlaces .[#toc-creating-links]
------------------------------------------
Los enlaces de las plantillas de presentador son relativos al módulo actual. Así, el enlace `Foo:default` lleva al presentador `Foo` en el mismo módulo que el presentador actual. Si el módulo actual es `Front`, por ejemplo, el enlace será el siguiente:
```latte
<a n:href="Product:show">enlace a Front:Product:show</a>
```
Un enlace es relativo aunque incluya el nombre de un módulo, que se considera entonces un submódulo:
```latte
<a n:href="Shop:Product:show">enlace a Front:Shop:Product:show</a>
```
Los enlaces absolutos se escriben de forma análoga a las rutas absolutas en disco, pero con dos puntos en lugar de barras. Así, un enlace absoluto comienza con dos puntos:
```latte
<a n:href=":Admin:Product:show">enlace a Admin:Product:show</a>
```
Para saber si estamos en un módulo determinado o en su submódulo podemos utilizar la función `isModuleCurrent(moduleName)`.
```latte
<li n:class="isModuleCurrent('MyEshop:Users') ? active">
<a n:href="Product:">...</a>
</li>
```
Enrutamiento .[#toc-routing]
----------------------------
Véase el [capítulo sobre en rutamiento|routing#Modules].
Mapeo .[#toc-mapping]
---------------------
Define las reglas por las que el nombre de la clase se deriva del nombre del presentador. Las escribimos en [configuración |configuration] bajo la clave `application › mapping`.
Empecemos con un ejemplo que no utiliza módulos. Sólo querremos que las clases del presentador tengan el espacio de nombres `App\Presenters`. Eso significa que un presentador como `Home` debe mapearse a la clase `App\Presenters\HomePresenter`. Esto se puede lograr con la siguiente configuración:
```neon
application:
mapping: App\Presenters\*Presenter
```
El nombre del presentador se sustituye por el asterisco en la máscara de clase y el resultado es el nombre de la clase. Muy fácil.
Si dividimos a los presentadores en módulos, podemos tener nuestra propia asignación para cada módulo:
```neon
application:
mapping:
Front: App\Modules\Front\Presenters\*Presenter
Admin: App\Modules\Admin\Presenters\*Presenter
Api: App\Api\*Presenter
```
Ahora el presentador `Front:Home` se asigna a la clase `App\Modules\Front\Presenters\HomePresenter` y el presentador `Admin:Dashboard` a la clase `App\Modules\Admin\Presenters\DashboardPresenter`.
Es más práctico crear una regla general (estrella) para sustituir a las dos primeras. El asterisco adicional se añadirá a la máscara de clase sólo para el módulo:
```neon
application:
mapping:
*: App\Modules\*\Presenters\*Presenter
Api: App\Api\*Presenter
```
Pero, ¿y si utilizamos módulos anidados y tenemos un presentador `Admin:User:Edit`? En este caso, el segmento con un asterisco que representa el módulo para cada nivel simplemente se repite y el resultado es la clase `App\Modules\Admin\User\Presenters\EditPresenter`.
Una notación alternativa es utilizar una matriz formada por tres segmentos en lugar de una cadena. Esta notación es equivalente a la anterior:
```neon
application:
mapping:
*: [App\Modules, *, Presenters\*Presenter]
```
El valor por defecto es `*Module\*Presenter`.