Bonsoir tout le monde,
Voici pour les plus courageux d'entre vous un petit problème qui m'a coûté une bonne demie journée de cassage de tête.
Par souci esthétique, je souhaiterais réécrire les url d'un dokuwiki utilisé en interne. Pour rappel, la syntaxe de base de ce wiki est : http://monwiki/wiki/doku.php?id=dev:cdc:portail pour accéder à la page portail, explicitement localisée dans le namespace cdc, lui même situé dans le namespace dev. Il n'y a pas de limite de namespaces/sous-namespaces. L'idée est de transformer ceci en : http://monwiki/dev/cdc/portail.
Certes, DokuWiki propose d'implémenter une réécriture aboutissant à http://monwiki/dev:cdc:portail (on devine la complexité de la RewriteRule associée) mais je trouve ça plus élégant et plus pertinent sémantiquement d'utiliser des '/'.
Je peux facilement résoudre le problème en proposant 5-6 règles de réécriture, chacune couvrant un nombre de paramètres précis, comme suit :
Mais ce n'est pas très classe, et surtout pas infaillible. Si quelqu'un essaie d'accéder à une page "croulant sous les namespaces", il aura droit à une 404 toute moche plutôt qu'à un message clair dans l'interface du wiki prévenant que la page recherchée n'existe pas (elle existe peut-être d'ailleurs).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)$ /doku.php?id=$1:$2:$3:$4:$5 [QSA] RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)$ /doku.php?id=$1:$2:$3:$4 [QSA] RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ /doku.php?id=$1:$2:$3 [QSA] RewriteRule ^([^/]+)/([^/]+)$ /doku.php?id=$1:$2 [QSA] RewriteRule ^([^/]+)$ doku.php?id=$1 [QSA,L]
Puisqu'il s'agit d'un wiki existant et non d'une application écrite de toute pièce, je souhaiterais éviter tant que possible de toucher au code source et donc ne pas implémenter la solution inhérente à une appli Zend par exemple (réécriture de toute url en index.php, qui se charge ensuite de lire l'URI requêtée ($_SERVER['REQUEST_URI']) et de déduire les variables).
Je souhaite donc imiter le comportement http://monsite/application/controleu...n/param/valeur etc... de Zend mais uniquement avec des RewriteRule (et éventuellement des Cond, Map, Base, tout ce qui vous semblera utile).
La meilleure approche est selon moi de boucler sur un règle de réécriture du premier "dossier" passé en un premier argument, puis du deuxième etc... de façon à ce que l'URI a/b/c/d/e/f devienne successivement :
b/c/d/e/f/doku.php?id=a
c/d/e/f/doku.php?id=a:b
d/e/f/doku.php?id=a:b:c
e/f/doku.php?id=a:b:c:d
f/doku.php?id=a:b:c:d:e
et finalement doku.php?id=a:b:c:d:e:f
Voilà le fruit de ma tempête intellectuelle et de mes recherches, commenté comme j'ai pu :
J'ai l'impression de ne pas être loin de la solution mais pour l'instant, toute requête vérifiant le format réécrit fait mouliner le serveur à l'infini (risque bien connu du flag [N] mais je ne vois pas comment m'en passer).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 # Exemple concret : a/b/c/d/e/f -> /doku.php?id=a:b:c:d:e:f # Détecter c/d/doku.php?id=a:b et le transformer en d/doku.php?id=a:b:c RewriteRule ^([^/]+)/(.+)/doku\.php\?id=(.+) $2/doku.php?id=$3:$1 [QSA,N] # Bouclage pour continuer le passage de dossiers en paramètres # Si on franchit cette étape, c'est soit la première fois (la chaîne doku.php n'est pas détectée)... # Auquel cas, on applique une règle spéciale pour la première fois RewriteRule ^([^/]+)/(.+) $2/doku.php?id=$1 [QSA,N] # Bouclage pour continuer le passage de dossiers en paramètres # ...soit la dernière fois (il n'y a plus qu'un dossier devant doku.php) # Dans ce cas, on transforme le dernier dossier en paramètre RewriteRule ^([^/]+)/doku\.php\?id=(.+) doku.php?id=$2:$1 [QSA,L] # A l'issue de ce mécanisme, tout URI respectant le format initial doit avoir été transformé
Je viens donc vous demander de l'aide parce que je ne vois plus comment procéder et surtout où est la boucle infinie.
PS : le cas du paramètre unique est pour l'instant ignoré mais ne me semble pas très compliqué dans la mesure où le masque est assez restrictif, il suffit la règle de réécriture quelque part avant la fin et le tour sera joué, du moins je crois.
Merci par avance,
Jean
Partager