/
significant.gtw
611 lines (468 loc) · 23.9 KB
/
significant.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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
~~LANG:EN@enman:urls/significant~~
Le moteur d'url “significant” permet d'attribuer à chaque action une URL
spécifique de la forme que l'on veut.
Le principe de configuration pour ce moteur est d'indiquer dans un fichier
@@F@var/config/urls.xml@@ toutes les formes d'URLs possibles de l'application et
les actions qui leur sont associées. Voici un exemple de fichier :
<code xml>
<urls xmlns="http://jelix.org/ns/urls/1.0">
<entrypoint name="index" default="true">
<url pathinfo="/news/:annee/:mois/:id-:title" module="news" action="view">
<param name="annee" type="year"/>
<param name="mois" type="month" />
<param name="id" type="number" />
<param name="title" escape="true" />
</url>
<url pathinfo="/articles/:rubrique/:id_art" module="cms" action="show">
<param name="id_art" regexp="\d+"/>
</url>
</entrypoint>
<entrypoint name="shop" type="classic">
<url pathinfo="/:category/:product" module="unittest" action="url2">
<param name="product" regexp="\d{2}" />
<static name="mystatic" value="valeur statique" />
</url>
</entrypoint>
<classicentrypoint name="foo/bar">
<url handler="urlsig" module="unittest" action="url4" />
</classicentrypoint>
<entrypoint name="news">
<url module="news" />
</entrypoint>
<entrypoint name="xmlrpc" default="true" type="xmlrpc" />
<entrypoint name="jsonrpc" default="true" type="jsonrpc"/>
</urls>
</code>
===== Balises entrypoint =====
La balise racine @@E@urls@@ contient autant de balises @@E@entrypoint@@ que de
points d'entrée disponibles dans votre application.
Chacune de ces balises a un attribut @@A@name@@ indiquant le nom du point
d'entrée (sans l'extension .php), ou plus exactement, son chemin, relatif à la
valeur du @@basePath@@ dans la configuration générale. Et vous ajouterez
éventuellement un attribut @@A@default@@ indiquant si ce point d'entrée est
celui par défaut pour le type de requête en question.
Il doit également y avoir un attribut @@A@type@@, qui indique le type de point
d'entrée, et vaut donc @@classic@@, @@xmlrpc@@, @@jsonrpc@@ etc.. Si cet
attribut n'est pas présent, la valeur par défaut est @@classic@@.
Pour des raisons de compatibilité avec les versions précédentes de jelix, les
balises @@E@entrypoint@@ peuvent avoir d'autres noms. Leur nom exact précise le
type de requête auquel ils sont affectés :
* @@E@classicentrypoint@@ pour les requêtes classiques
* @@E@xmlrpcentrypoint@@ pour du xmlrpc
* etc ...
Mais cet usage est dorénavant obsolète.
===== Balise url =====
Chaque point d'entrée définit une ou plusieurs formes d'URLs possibles, sachant
que celles qui ne sont pas définies seront acceptées lors d'une requête sur un
point d'entrée spécifié "default".
==== Spécifier une forme d'URL complète ====
=== Selon un pathinfo ===
Vous voulez indiquer le module et l'action à exécuter pour une forme
particulière d'URL. Vous indiquerez alors un attribut @@A@pathinfo@@, indiquant
le "modèle" de la partie pathinfo auquel l'URL doit ressembler, ainsi que le
module et l'action dans des attributs @@A@module@@ et @@A@action@@.
L'attribut @@A@pathinfo@@ doit donc contenir la valeur d'un pathinfo. Dans cet
exemple, toute URL qui aura pour pathinfo la valeur "/foo/bar" correspondra au
module et action indiqués (module hello, action default:world dans notre cas).
<code xml>
<url pathinfo="/foo/bar" module="hello" action="default:world" />
</code>
Vous pouvez mettre l'attribut @@A@optionalTrailingSlash="true"@@ si vous voulez
indiquer que l'éventuelle présence/absence d'un slash à la fin correspond à la
même action ( @@/foo/bar/@@ et @@/foo/bar@@ serait donc équivalent, ce qui n'est
pas le cas par défaut). On peut mettre cet attribut sur la balise
@@E@entrypoint@@ pour que ce soit pris en compte pour toutes les urls définies.
=== Selon un pathinfo contenant des parties indéfinies ===
Il est possible d'indiquer des parties "dynamiques" dans le pathinfo. Elles sont
à définir par un deux-points suivi d'un nom. La valeur trouvée sera alors
stockée dans un paramètre du même nom. Dans l'exemple qui suit, le pathinfo
contient deux parties dynamiques : ''rubrique'' et ''id_art''.
<code xml>
<url pathinfo="/articles/:rubrique/:id_art" module="cms" action="default:show" />
</code>
Si on appelle l'URL "/articles/aviation/544", alors les paramètres ''rubrique''
et ''id_art'' seront crées et auront pour valeurs respectives "aviation" et
"544".
Attention : pour éviter les ressemblances avec d'autres URLs, il faut au moins
une partie "statique" (ici "/articles/") dans l'URL pour la distinguer des
autres.
=== Des parties indéfinies typées ou formatées ===
Un autre moyen d'éviter ces ressemblances est de spécifier le format ou le type
de chaque paramètre. Par défaut le type est une chaîne classique.
Pour cela il faut indiquer des balises @@E@<param>@@ pour chacun des paramètres
dont on veut spécifier le type/format. Elles devront contenir un attribut
@@A@name@@ indiquant le paramètre et, soit un attribut @@A@type@@, soit un
attribut @@A@regexp@@, contenant une expression régulière du format (sans
délimiteur). Dans notre exemple, nous voulons spécifier que "rubrique" est une
chaîne et une expression régulière pour "id_art" :
<code xml>
<url pathinfo="/articles/:rubrique/:id_art" module="cms" action="show">
<param name="rubrique" type="string" />
<param name="id_art" regexp="\d+" />
</url>
</code>
Si l'expression régulière de l'attribut regexp contient des parenthèses, il est
nécessaire d'indiquer que celles-ci ne doivent pas être capturées. Exemple :
<code xml>
<param name="type" regexp="(?:0|1|2){1}" />
</code>
Quand le paramètre est de type string il n'est pas obligatoire de mettre une
balise @@E@param@@. Les types disponibles sont :
| string | une chaîne |
| letter | une seule lettre |
| number | un nombre entier, équivalent aussi à 'int' et 'integer' |
| digit | un chiffre |
| date | une date au format AAAA-MM-JJ |
| year | une année sur 4 chiffres |
| month | un mois sur deux chiffres |
| day | un jour sur deux chiffres |
| path | un sous chemin. dans ce cas ce paramètre doit être le dernier dans l'url |
| lang | un code langue (2 ou 3 lettres), voir section plus bas sur les paramètres automatiques de langue |
| locale | un code de locale (code langue + code pays), voir section plus bas sur les paramètres automatiques de langue |
Note : vous devrez bien entendu indiquer les valeurs de ces paramètres lors de l'appel à jUrl.
=== Des paramètres statiques ===
Il peut être nécessaire parfois de rajouter des paramètres "statiques",
attendues par l'action (celle-ci pouvant être attribuées à plusieurs URLs
différentes), mais non présent dans l'URL. Pour cela il faut ajouter une balise
@@E@<static>@@, avec nom et valeur, comme dans cet exemple :
<code xml>
<url pathinfo="/:category/:product" module="shop" action="product:view">
<param name="product" regexp="\d{2}" />
<static name="details" value="0" />
</url>
<url pathinfo="/:category/:product/details" module="shop" action="product:view">
<param name="product" regexp="\d{2}" />
<static name="details" value="1" />
</url>
</code>
Ici on utilise la même action pour deux URLs différentes. Son traitement
différera en partie selon le paramètre ''details'', qu'il ne faut donc pas
oublier de donner à @@M@jUrl::get()@@. Dans un cas on afficherait le produit
d'un catalogue avec ses caractéristiques générales, et dans l'autre avec ses
caractéristiques générales **et** détaillées. Cela évite donc de créer deux
actions différentes pour si peu de différence.
On peut aussi utiliser ce mécanisme pour supporter plusieurs langues :
<code xml>
<url pathinfo="/articles/en/:page" module="cms" action="page:view">
<param name="page"/>
<static name="lang" value="en_US" />
</url>
<url pathinfo="/articles/fr/:page" module="cms" action="page:view">
<param name="page"/>
<static name="lang" value="fr_FR" />
</url>
</code>
Là encore, il ne faut pas oublier de donner le paramètre @@lang@@ à jUrl pour
que ce dernier puisse savoir quelle url il doit renvoyer.
<code php>
jUrl::get('cms~page:view', array('page'=>'foo', 'lang'=>jApp::config()->locale));
// ou
jUrl::get('cms~page:view', array('page'=>'foo', 'lang'=>"en"));
</code>
<code html>
<a href="{jurl 'cms~page:view', array('page'=>'foo', 'lang'=>$j_locale}">my link</a>
<a href="{jurl 'cms~page:view', array('page'=>'foo', 'lang'=>'fr_FR'}">my link</a>
</code>
==== Paramètres automatiques de langues ====
=== avec les paramètres statiques ===
Nous avons vu que l'on pouvait déclarer des paramètres statiques contenant le code
d'une langue, pour différencier deux URLS pointant vers une même action. Cependant,
cette solution, telle que décrite, a deux inconvénients :
- il faut donner ce paramètre à @@jUrl::get()@@, et en général, on indique la valeur de la langue courante
- Dans l'action, il faut tenir compte de ce paramètre, et en général, il s'agit
de changer la configuration à la volée (le plugin autolocale n'étant pas forcément utilisé)
Jelix 1.4 apporte des améliorations en ce sens. Il suffit d'ajouter l'attribut @@A@type="locale"@@
sur la balise @@E@<static>@@, pour que tout soit automatique. Vous définissez par exemple :
<code xml>
<url pathinfo="/articles/english/:page" module="cms" action="page:view">
<param name="page"/>
<static name="lang" value="en_US" type="locale"/>
</url>
<url pathinfo="/articles/francais/:page" module="cms" action="page:view">
<param name="page"/>
<static name="lang" value="fr_FR" type="locale" />
</url>
</code>
Si vous faites simplement @@jUrl::get('cms~page:view', array('page'=>'foo'))@@,
alors jUrl générera @@/articles/english/foo@@ si la langue courante est "en_US",
ou @@/articles/francais/foo@@ si la langue courante est "fr_FR". Vous n'avez pas
besoin d'indiquer le code langue comme avant : @@jUrl::get('cms~page:view', array('page'=>'foo', 'lang'=>jApp::config()->locale))@@.
Cependant, vous pouvez toujours le faire pour forcer le code langue.
À l'inverse, lors de la demande de la page @@/articles/english/foo@@ ou
@@/articles/francais/foo@@, Jelix configurera automatiquement la locale, le temps
de l'execution de l'action. Ainsi, si l'utilisateur appelle la page @@/articles/english/foo@@,
la langue courante deviendra "en_US".
Vous pouvez aussi utiliser @@A@type="lang"@@. Dans ce cas, vous pouvez indiquer juste
le code langue ('en', 'fr'...), que ce soit dans l'attribut @@A@value@@, ou à @@jUrl::get()@@.
<code xml>
<static name="lang" value="fr" type="lang" />
</code>
=== Avec les paramètres dynamiques ===
Depuis Jelix 1.4, vous pouvez avoir des paramètres dynamiques de type "locale" ou "lang".
<code>
<param name="lg" type="lang"/>
<!-- ou -->
<param name="lg" type="locale"/>
</code>
Cela permet d'avoir dans le "pathinfo" de l'url l'information de la langue, sans même avoir à
l'indiquer à @@jUrl::get()@@, mais aussi de configurer la langue courante automatiquement pendant
l'éxecution de l'action lors de l'appel de l'URL en question.
Ainsi, l'exemple utilisé plus haut :
<code xml>
<url pathinfo="/articles/en/:page" module="cms" action="page:view">
<param name="page"/>
<static name="lang" value="en_US" />
</url>
<url pathinfo="/articles/fr/:page" module="cms" action="page:view">
<param name="page"/>
<static name="lang" value="fr_FR" />
</url>
</code>
peut en fait se résumer à :
<code xml>
<url pathinfo="/articles/:lang/:page" module="cms" action="page:view">
<param name="page"/>
<param name="lang" type="lang" />
</url>
</code>
Si vous faites juste @@jUrl::get('cms~page:view', array('page'=>'foo'))@@,
alors jUrl générera @@/articles/en/foo@@ si la langue courante est "en_US",
ou @@/articles/fr/foo@@ si la langue courante est "fr_FR".
Et si un navigateur appelle l'url @@/articles/en/foo@@, la langue courante
deviendra automatiquement "en_US".
Contrairement à Jelix 1.3 et inférieur, vous n'avez donc plus à dupliquer
vos déclarations d'URL pour chaque langue.
Même principe avec @@A@type="locale"@@, sauf que jUrl générera @@/articles/en_US/foo@@.
==== Utiliser un handler spécifique ====
Nous avons vu précédemment comment utiliser, en fin de compte, un système par
défaut d'analyse et de génération d'URL avec ses pathinfos et paramètres. Il se
peut que ce système ne soit pas suffisant. Imaginons par exemple que vous
vouliez transformer une partie de l'information contenue dans le pathinfo, comme
par exemple chercher dans une base de données un id correspondant à un titre
contenu dans le pathinfo, et fournir ainsi aux actions, non pas un titre, mais
un id (qui n'est pas contenu dans cette URL).
Ou encore que la partie pathinfo puisse être variable.
Aussi c'est à vous de développer l'analyse de l'URL et d'indiquer l'action à
exécuter. Vous le ferez dans une classe spécialisée :
<code php>
class myHandlerUrlsHandler implements jIUrlSignificantHandler {
function parse($url){
if(preg_match("/^\/(.*)$/",$url->pathInfo,$match)){
$urlact = new jUrlAction($url->params);
$urlact->setParam('page',jUrl::unescape($match[1]));
return $urlact;
}else
return false;
}
function create($urlact, $url){
$p=jUrl::escape($url->getParam('page'));
$url->pathInfo = "/$p";
$url->delParam('page');
}
}
</code>
Le nom de la classe doit commencer par un préfixe que vous voulez et se terminer
par ''UrlsHandler''. La classe sera stockée dans le répertoire @@F@classes/@@ du
module indiqué dans la balise @@E@url@@, sous le nom ''prefixe''.urlhandler.php.
Pour notre exemple, cela sera @@myHandler.urlhandler.php@@.
La méthode @@M@parse()@@ est chargée d'analyser une URL (objet @@C@jUrl@@ que
vous recevez en paramètre), en l'occurence, l'URL demandée dans l'application.
Si votre handler reconnaît l'URL, @@M@parse()@@ doit renvoyer un objet
@@C@jUrlAction@@ qui contient toutes les données pour l'action. Sinon il doit
renvoyer @@false@@.
La méthode @@M@create()@@ est appelée à chaque fois que l'application demande la
création d'une URL à partir de paramètres d'action. Elle reçoit donc un objet de
type @@C@jUrlAction@@, et un objet de type @@C@jUrl@@. @@V@$urlaction@@ contient
donc les paramètres de l'action. Ces paramètres ont déjà été inclus dans l'objet
@@V@$url@@. Vous devez donc modifier @@V@$url@@ de façon à produire l'URL
correspondante à l'action demandée. Dans l'exemple, on récupère le paramètre
page, que l'on incorpore dans le pathinfo. Et comme il est dans le pathinfo, on
le supprime alors des paramètres.
Notez l'usage de @@M@jUrl::escape()@@ et @@M@jUrl::unescape()@@, pour "nettoyer"
les chaînes à inclure dans un pathinfo (accents enlevés par ex).
Enfin dans le fichier @@F@urls.xml@@, vous devez indiquer l'utilisation de ce
handler :
<code xml>
<classicentrypoint name="wiki">
<url handler="myHandler" module="unittest" action="url4" />
</classicentrypoint>
</code>
Vous pouvez bien sûr indiquer un handler d'un autre module. Exemple :
<code xml>
<classicentrypoint name="wiki">
<url handler="autremodule~myHandler" module="unittest" action="url4" />
</classicentrypoint>
</code>
==== Une même URL pour plusieurs actions possibles ====
Imaginons que nous avons une URL de ce type @@/article/54-titre@@ et par défaut,
cela affiche l'article 54 avec une action nommée view, par exemple :
<code xml>
<url pathinfo="/article/:id_art-:title" module="cms" action="view" />
</code>
On veut pouvoir, sans changer l'url, indiquer d'autres actions dans certains
cas, avec un paramètre action :
* @@/article/54-titre?action=edit@@
* @@/article/54-titre?action=delete@@
Note : On pourrait faire aussi /article/54-titre/edit ou
/article/54-titre/delete , avec donc plusieurs balises @@E@urls@@, ce qui nous
éviterait ce qui suit. Mais ce n'est pas très pratique quand l'URL est appelée
suite à un formulaire par exemple.
Pour indiquer les actions alternatives autorisées, on ajoute un attribut
@@A@actionoverride@@, contenant la liste des actions séparées par un espace ou
une virgule :
<code xml>
<url pathinfo="/article/:id_art-:title" module="cms" action="view" actionoverride="edit,delete" />
</code>
==== Indiquer qu'un point d'entrée est dédié à un module particulier ====
Vous n'avez pas forcément envie d'indiquer une URL significative pour les
actions d'un module particulier. Par contre vous avez créé un point d'entrée
dédié à un module. Toutes ces actions passeront par ce point d'entrée. Vous avez
juste alors à faire comme ceci :
<code xml>
<classicentrypoint name="news">
<url module="news" />
</classicentrypoint>
</code>
Vous pouvez indiquer plusieurs modules de cette façon pour un même point
d'entrée.
==== Spécifier des URLs en https à certaines actions ====
Pour certaines actions vous voulez que l'accès soit en mode sécurisé de http
(SSL). Vous indiquez alors un attribut @@A@https@@ sur les balises @@E@<url>@@
en question avec la valeur true. Si cela concerne toutes les actions/URLs d'un
point d'entrée, alors vous mettrez cet attribut sur la balise @@E@<entrypoint>@@
correspondante.
Attention : pour le moment, Jelix ne vérifie pas lors de l'exécution d'une
action que la requête a été faite en https ou non.
==== Inclure un fichier d'urls d'un module particulier ====
Il est possible de déclarer les urls dans chaque module,
donc dans des fichiers séparés. Cela évite d'avoir un fichier urls.xml
volumineux, mais surtout évite d'avoir à définir ou à "recopier" les urls d'un
module réalisé par un tiers.
Pour ce faire, vous devez créer un fichier @@F@urls.xml@@ dans le répertoire du
module (vous pouvez choisir un autre nom que urls.xml). Ce fichier ne contient
pas une balise racine @@E@urls@@ mais @@E@suburls@@, et contient uniquement des
balises @@E@url@@ (pas @@E@entrypoint@@). Voici celui du module jauth comme
exemple :
<code xml>
<?xml version="1.0" encoding="utf-8"?>
<suburls xmlns="http://jelix.org/ns/suburls/1.0">
<url pathinfo="/dologin" action="login:in" />
<url pathinfo="/dologout" action="login:out" />
<url pathinfo="/login" action="login:form"/>
</suburls>
</code>
Et dans le fichier urls.xml principal, dans une des balises @@E@entrypoint@@, vous indiquez
<code xml>
<entrypoint name="index">
...
<url pathinfo="/auth" module="jauth" include="urls.xml" />
</entrypoint>
</code>
Cela signifie : il faut inclure toutes les urls qui sont dans le fichier
@@F@urls.xml@@ du module jauth, et préfixer le pathinfo de ces urls par le
chemin "/auth/". Autrement dit, l'url pour l'action "jauth~login:in" sera
"/auth/dologin".
Cela signifie aussi que les urls que vous indiquez dans un fichier de module ne
sont pas des urls complètes. Cela permet à l'utilisateur du module de choisir le
chemin (en tout cas, le début du chemin) pour les urls du module, et éviter donc
des doublons avec d'autres modules.
Dans un fichier URL de module, vous pouvez déclarer des urls avec un pathinfo
complet, avec un pathinfo avec variables (formatées ou non), avec des paramètres
statiques, avec un handler. Par contre, il est obligatoire de spécifier une url
pour chaque action. Notez aussi qu'il ne faut pas utiliser l'attribut
@@A@module@@, cela n'aurait pas de sens.
Bien sûr, vous devez faire un fichier d'urls pour chaque type d'action : un
fichier pour le point d'entrée classique, un fichier pour chaque autre type de
point d'entrée etc.
==== Mod_rewrite et suppression du nom du point d'entrée dans l'URL ====
Vous préférez peut être que l'analyse des URLs se fasse par le serveur web,
grâce au module rewrite pour apache par exemple. Vous allez donc écrire les
règles de réécriture.
=== Réécriture complète par le serveur web ===
On appelle ici réécriture complète, la réécriture qui consiste à fournir à Jelix
des URLs simples (@@index.php?module=...&action=...@@), à partir d'URLs
significatives.
Pour cela, vous devez indiquer à Jelix, dans la configuration, de ne pas
analyser les URLs :
<code ini>
[urlengine]
..
enableParser = off
</code>
Vous devez bien sûr remplir un fichier @@F@urls.xml@@ de façon à ce que Jelix
génère dans vos templates et ailleurs, les URLs attendues par vos règles de
rewrite.
Et bien sûr, vous devez ensuite mettre dans un fichier @@F@.htaccess@@ les
règles de réécritures.
Si vous voulez définir des URLs qui ne contiennent pas le nom du point d'entrée,
vous devez alors indiquer sur les balises @@E@<url>@@ l'attribut
@@A@noentrypoint="true"@@ (ou sur la balise @@E@<entrypoint>@@ si toutes les
URLs de ce point d'entrée sont concernées). Ainsi Jelix n'ajoutera pas le nom du
point d'entrée (index.php) dans l'URL.
=== Suppression du nom du point d'entrée dans l'URL ===
Un exemple d'utilisation du mod_rewrite n'est pas forcément de transformer
complétement les URLs comme indiqué précédement, mais par exemple d'ajouter le
fichier index.php dans les URLs dans lesquelles on l'aurait supprimé pour faire
"joli".
Par exemple nos URLs sont de la forme :
<code>
http://monsite.com/index.php/news/2017-02-08-il-neige-a-lille.html
</code>
Et on souhaite qu'elles deviennent :
<code>
http://monsite.com/news/2017-02-08-il-neige-a-lille.html
</code>
Voyons comment faire.
Tout d'abord, il faut bien sûr utiliser le moteur d'URL "significant" et définir
un fichier @@F@urls.xml@@. Comme pour la réécriture complète vous devez indiquer
sur les balises @@E@<url>@@ ou @@E@<entrypoint>@@ l'attribut
@@A@noentrypoint="true"@@. Ainsi Jelix n'ajoutera pas le nom du point d'entrée
(index.php) dans les URLs concernées.
Par contre, contrairement à la réécriture complète, vous devez laisser @@enableParser@@ à @@on@@:
<code ini>
[urlengine]
..
enableParser = on
</code>
Ensuite on va utiliser le rewriteEngine de Apache d'une façon toute simple : le
chemin appelé sera rajouté après index.php. En clair il faut copier ceci dans un
fichier @@F@.htaccess@@ dans le dossier @@F@www/@@ de votre application (ou dans
la section virtualhost de la configuration apache):
<code>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
</IfModule>
</code>
Observez bien :
* 2e ligne : vous n'en avez pas besoin si vous écrivez ces instructions dans
un @@F@.htaccess@@ dans le répertoire www de l'appli. Par contre, dans un
autre @@F@.htaccess@@ ou dans un virtual host, vous devez la mettre, et
adapter le chemin : @@F@/@@ si le www correspond au documentRoot, ou le
chemin pour accéder au répertoire www à partir d'une url (basePath). ex
@@RewriteBase /monapp/www/@@ si vous accédez à l'application par
@@http://localhost.local/monapp/www/index.php@@
* 3e et 4e ligne : Réécrire l'URL seulement si la requête ne correspond pas à
un fichier déjà existant, ou un dossier déjà existant. Ainsi on préserve ses
dossiers d'image, de feuille de style, etc. de la règle de réécriture.
* 5e ligne : Tout prendre, et mettre après index.php/
On retrouve ainsi notre point d'entrée index.php ainsi que notre pathinfo.
Il se peut que sur certaines configurations, vous ayez une erreur apache du type
"Error: No input file specified", en particulier quand PHP est exécuté en CGI
avec @@cgi.fix_pathinfo=0@@ dans php.ini. Mais il y a une solution. Il faut changer
la dernière rêgle en :
<code>
RewriteRule ^(.*)$ index.php?jpathinfo=/$1 [L,QSA]
</code>
Ainsi le but est de mettre le pathinfo dans un paramétre de la requête. Pour que
cela fonctionne pleinement, il faut ajouter dans la configuration de Jelix, dans
la section @@urlengine@@, le paramètre @@pathInfoInQueryParameter@@ qui doit
contenir le nom du paramètre (ici dans l'exemple @@jpathinfo@@) :
<code ini>
[urlengine]
...
pathInfoInQueryParameter = jpathinfo
</code>