/
modules.texy
183 lines (133 loc) · 9.83 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
Модули
******
.[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
│ │ └── ...
\--
Эта структура каталогов отражается в пространствах имен классов, так, например, `DashboardPresenter` находится в пространстве имен `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`. Это также отражено в пространствах имен, которые отображаются как `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">odkaz na Front:Product:show</a>
```
Ссылка является относительной, даже если имя модуля является ее частью, тогда он считается подмодулем:
```latte
<a n:href="Shop:Product:show">odkaz na Front:Shop:Product:show</a>
```
Абсолютные ссылки записываются аналогично абсолютным путям на диске, но с двоеточиями вместо косых черт. Таким образом, абсолютная ссылка начинается с двоеточия:
```latte
<a n:href=":Admin:Product:show">odkaz na Admin:Product:show</a>
```
Чтобы узнать, находимся ли мы в определенном модуле или подмодуле, мы используем функцию `isModuleCurrent(moduleName)`.
```latte
<li n:class="isModuleCurrent('Forum:Users') ? active">
<a n:href="Product:">...</a>
</li>
```
Маршрутизация .[#toc-routing]
-----------------------------
См. [главу о маршрутизации |routing#modules].
Составление карты .[#toc-mapping]
---------------------------------
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
```