forked from jelix/jelix-manuel-fr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
zones.gtw
340 lines (242 loc) · 10.9 KB
/
zones.gtw
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
~~LANG:EN@enman:zones~~
===== Principes d'une zone =====
Les zones dans Jelix représentent des morceaux de la réponse finale. En d'autre
termes, elles sont destinées à gérer et générer le contenu d'une portion de
l'écran, de la page web. Une page web est donc composée essentiellement de
zones.
L'intérêt d'utiliser les zones est de :
* pouvoir réutiliser une zone dans des pages différentes : une zone est en
théorie indépendante du contexte : elle fait elle-même appel aux classes
métiers et possède son propre template.
* avoir une génération de contenu paramétrable : les zones acceptent des
paramètres.
* pouvoir générer plus rapidement les pages, en activant la mise en cache
des zones : seules les zones dont les paramètres changent (la zone
principale en général) sont régénérées (ou celles dont on aura effacé le
cache).
* au passage, alléger le code des contrôleurs.
===== Utilisation des zones =====
==== Création ====
Une zone est déclarée via une classe héritant de @@C@jZone@@. Le nom de cette
classe est le nom de la zone suivi du mot "Zone"
<code php>
class testZone extends jZone {
}
</code>
Elle doit être stockée dans un fichier @@F@nom_de_la_zone.zone.php@@, dans le
répertoire @@F@zones/@@ du module. Ici donc, il s'agit du fichier
@@F@zones/test.zone.php@@.
Par défaut, un objet @@C@jZone@@ instancie un moteur de template.
=== Utilisation sans template ===
Si vous ne voulez pas utiliser de template pour votre zone, vous devez
surcharger la méthode @@M@_createContent@@, qui doit renvoyer le contenu de la
zone sous forme de chaine. Vous ne devez pas faire d'echo ou de print !
<code php>
class testZone extends jZone {
protected function _createContent(){
return "<p>Ceci est le contenu d'une zone</p>";
}
}
</code>
=== Utilisation avec template ===
La plupart du temps, vous utiliserez toutefois un template. Vous devez indiquer
dans la propriété @@P@$_tplname@@ le template que vous utilisez (c'est un
sélecteur), et surcharger la méthode @@M@_prepareTpl()@@. Cette méthode est,
comme son nom l'indique, chargée d'initialiser l'objet @@C@jTpl@@ instancié
automatiquement par jZone et stocké dans la propriété @@P@_tpl@@.
<code php>
class testZone extends jZone {
protected $_tplname='template_test';
protected function _prepareTpl(){
$this->_tpl->assign('foo','bar');
}
}
</code>
Et le template (stocké dans @@F@templates/template_test.tpl@@):
<code xml>
<p>Ceci est un template. Et foo vaut {$foo}.</p>
</code>
=== Création en utilisant jelix-scripts ===
Vous pouvez utiliser [[jelix-scripts|jelix-scripts]] pour créer votre zone
accompagnée ou non d'un template.
Exécutez simplement la commande suivante :
<code>
php cmd.php createzone [MonModule] [MaZone] [MonTemplate]
</code>
où le paramètre [MonTemplate] est facultatif. Le nom du template est identique
au nom de la zone dans ce cas.
Pour ne pas créer de template précisez simplement l'option -notpl.
<code>
php cmd.php createzone -notpl [MonModule] [MaZone] [MonTemplate]
</code>
==== Appel ====
Il y a plusieurs façons de récupérer le contenu d'une zone en fonction de ce que
l'on veut faire.
Si on veut récupérer simplement son contenu (dans un contrôleur) on fait :
<code php>
$contenu = jZone::get('test'); // ou 'leModule~test'...
</code>
Cependant, il arrive très souvent qu'il s'agisse d'affecter le contenu de la
zone à une variable du template principal, lorsque la réponse possède un
template principal (ce qui est le cas des réponses HTML qui possèdent un objet
jTpl dans sa propriété @@P@$body@@). Dans le contrôleur, on pourra donc utiliser
la méthode @@M@assignZone@@ de jTpl :
<code php>
$rep = $this->getResponse('html');
$rep->title = 'page de test';
$rep->bodyTpl = 'testapp~main';
$rep->body->assignZone('MAIN', 'test');
</code>
* @@L@test@@ correspondant au nom du fichier @@F@test.zone.php@@
* @@L@MAIN@@ correspondant à la variable de template @@{$MAIN}@@
Autre solution, on peut avoir dans un template, un appel de zone direct :
<code html>
<div id="menu"> {zone 'leModule~test'} </div>
</code>
=== Appel avec des paramètres ===
Il est possible de faire passer des paramètres à une zone. Il faut les passer par un tableau associatif.
<code php>
$contenu = jZone::get('test', array('foo'=>'bar'));
</code>
Avec la méthode @@M@assignZone@@ de jTpl :
<code php>
$rep = $this->getResponse('html');
$rep->title = 'page de test';
$rep->bodyTpl = 'testapp~main';
$rep->body->assignZone('MAIN', 'test', array('foo'=>'bar'));
</code>
Pour récupérer la variable dans la zone, on utilise la méthode @@P@param()@@ :
<code php>
class testZone extends jZone {
protected $_tplname='template_test';
protected function _prepareTpl(){
$foo = $this->param('foo');
$foo = strtoupper($foo);
$this->_tpl->assign('foo', $foo);
}
}
</code>
Dans cet exemple on a fait passer la variable 'foo' avec pour valeur 'bar' en
paramètre de la zone. On a récupéré la variable 'foo' dans la zone pour
effectuer un traitement dessus (ici, mise en majuscule) et on a affecté 'foo' au
template de la zone.
À noter que Jelix affecte automatiquement les variables passées en paramètres de
la zone au template de zone s'il existe. Vous pouvez vous passer d'écrire :
<code php>
protected function _prepareTpl(){
$this->_tpl->assign('foo', $this->param('foo'));
}
</code>
Si vous utilisez le plugin de template zone, le passage des paramètres à la zone
s'effectue de cette manière :
<code html>
<div id="menu"> {zone 'leModule~test', array('foo'=>'bar')} </div>
</code>
==== Utilisation du cache ====
Il est possible de mettre le contenu généré dans un cache. Et il peut y avoir un
cache pour chaque valeur des paramètres de la zone.
=== Activation du cache ===
Par défaut, une zone ne gère pas de cache : il faut donc l'activer dans votre
classe, via la propriété @@P@$_useCache@@ en la mettant à @@L@true@@ :
<code php>
class testZone extends jZone {
protected $_useCache = true;
}
</code>
Le contenu de la zone sera ainsi mis dans un fichier de cache. Si la zone a des
paramètres, un cache sera créé pour chaque valeur différente des paramètres.
Ainsi, si vous avez un paramètre 'id_article', un cache sera créé à chaque fois
que la zone sera appelée avec une valeur de id_article différente.
**ATTENTION** : un cache se matérialise par un fichier dans le répertoire
temporaire de l'application. Si vous avez des milliers d'articles, cela peut
engendrer autant de fichiers dans votre répertoire temporaire. Il faut donc
éviter dans un cas comme celui-là, d'activer le cache si votre hébergeur vous
limite en nombre de fichiers par exemple.
Utilisez donc le cache à bon escient. Par exemple, pour une application
fréquentée moyennement (un même article lu seulement quelque fois par jour), il
n'est pas forcément nécessaire d'activer le cache. À vous de juger...
=== Rafraîchissement du cache ===
Il est nécessaire de régénérer le cache quand les informations contenues sont
obsolètes. Cette régénération peut se faire automatiquement régulièrement
(toutes les //n// secondes), ou alors être forcée manuellement.
Vous utiliserez l'une ou l'autre des méthodes selon les cas. La deuxième méthode
est moins gourmande en ressource puisque le cache se régénère uniquement en
temps voulu. L'inconvénient c'est qu'il faut explicitement effacer le cache dans
vos classes métier. La première méthode évite ce travail, mais consomme plus de
ressources, et le contenu de la zone n'est pas à jour pendant le délai indiqué.
À réserver donc pour afficher des informations non vitales, dont la "fraîcheur"
n'a pas vraiment d'importance.
== Automatique ==
Pour un rafraîchissement automatique, il suffit d'indiquer dans la propriété
@@P@$_cacheTimeout@@ le délai d'invalidité du cache, en secondes :
<code php>
class testZone extends jZone {
protected $_useCache = true;
protected $_cacheTimeout = 60;
}
</code>
Ici le cache sera régénéré toutes les 60 secondes. Si vous mettez 0, il n'y aura
pas de rafraîchissement automatique.
== Forcé ==
La suppression "manuelle" du cache se fait via les méthodes statiques
@@M@clear()@@ et @@M@clearAll()@@.
Par exemple, dans la classe métier de votre article, au moment de modifier
l'article (en base de données par exemple) ou de le supprimer, vous allez
appeler ''jZone'' pour qu'il supprime le cache correspondant, afin qu'il soit
régénéré au prochain affichage. Bien sûr, il faut indiquer les valeurs des
paramètres qui identifient le cache. Dans notre exemple donc, ''id_article''.
<code php>
jZone::clear('mymodule~article', array('id_article'=>546));
</code>
Si vous voulez effacer tous les caches d'une même zone, vous pouvez appeler @@M@clearAll()@@ :
<code php>
jZone::clearAll('mymodule~article');
</code>
Et si vous voulez effacer tous les caches de toutes les zones :
<code php>
jZone::clearAll();
</code>
=== Empêcher dynamiquement la mise en cache ===
Il faut noter que les méthodes @@M@_createContent()@@ et @@M@_prepareTpl()@@
(que vous pouvez surcharger), ne sont appelées que lorsque le cache doit être
régénéré.
Il se peut que pour une raison ou pour une autre (en fonction de la valeur d'un
certain paramètre par exemple), vous ne vouliez pas que parfois le résultat de
la zone soit mis en cache.
Il suffit alors, dans @@M@_createContent()@@ ou @@M@_prepareTpl()@@, de mettre
la propriété @@P@$_cancelCache@@ à @@true@@.
<code php>
protected function _prepareTpl(
// ....
$this->_cancelCache=true;
//...
}
</code>
=== Désactiver les caches pendant le développement ===
Parfois, il peut arriver que l'on veuille désactiver le cache des zones, pour
voir le résultat de ces zones quand on les modifie. Pour cela, vous pouvez
modifier un paramètre dans la configuration, au niveau de la section "zones"
<code ini>
[zones]
disableCache = on
</code>
==== Paramètres automatiques ====
L'affichage d'une zone peut dépendre de paramètres donnés explicitement, mais
aussi de paramètres "externes" implicites. C'est le cas par exemple pour une
zone qui affiche la version d'un article en fonction de la langue configurée
dans l'application. On peut bien sûr passer à chaque appel de zone le code
langue, mais ce n'est pas forcément pratique. On pourrait ne pas avoir à
l'indiquer dans les paramètres, et le récupérer soi-même dans
@@M@_createContent()@@ ou @@M@_prepareTpl()@@, mais alors il n'est pas possible
que cela devienne un critère discriminant pour le système de cache si vous
l'utilisez.
La solution est de surcharger le constructeur, et d'initialiser ce paramètre :
<code php>
class articleZone extends jZone {
protected $_useCache = true;
public function __construct($params=array()){
$params['lang'] = jApp::config()->locale;
parent::__construct($params);
}
}
</code>