La réécriture des URL « à la volée »

Le module Apache mod_rewrite

SPIP fournit en standard tout ce qu’il faut pour présenter des URL à l’apparence statique. Pour permettre au Webmaster de mieux comprendre le mécanisme de cette réécriture, découvrons ensemble la puissance du module Apache mod_rewrite, le « couteau Suisse de la manipulation »

Le module Apache mod_rewrite et la réécriture d’URL

Une des fonctions les plus puissantes permises par le fichier .htaccess est la réécriture « à la volée » des URL.
Sur le site officiel Apache, le module mod_rewrite est présenté à raison comme le couteau suisse de la manipulation.
Il est utile de préciser que certains hébergeurs n’ont pas activé le module de réécriture. Dans ce cas, vous n’avez malheureusement aucune possibilité de l’utiliser, à moins de casser le petit cochon en porcelaine qui traîne chez vous et changer d’hébergeur.

Si vous gérez votre propre serveur dédié, assurez-vous que le module mod_rewrite est activé en modifiant le cas échéant le fichier de configuration du serveur Apache (httpd.conf).
Vérifiez que les deux lignes suivantes ne soient pas mises en commentaire :

LoadModule rewrite_module modules/mod_rewrite.so
AddModule mod_rewrite.c


Si vous devez changer ces deux lignes, il vous faudra redémarrer Apache pour que vos modifications soient prises en compte.

On teste d’abord !

Avant de se lancer plus loin dans les explications, voici comment tester si le module mod_rewrite est actif chez votre hébergeur. Comme pour toutes manipulations qui peuvent impacter le bon fonctionnement de votre site, nous vous conseillons de faire ces essais en période creuse, en évitant par exemple la période de « full crawl » de Google.

1. Créez un fichier html simple, nommez le « trouve.html ».
2. Modifiez le fichier .htaccess en y ajoutant les 3 lignes suivantes. Faites très attention à utiliser la syntaxe précise ou mieux, utilisez le copier/coller :

Options +FollowSymlinks
RewriteEngine on 
RewriteRule   ^nexistepas.html$   trouve.html  [L]

Nous reviendrons plus tard sur l’explication de ces deux instructions

3. Télécharger le fichier .htaccess et le fichier trouve.html à la racine de votre site web, ou mieux encore dans un répertoire de test créé pour l’occasion. Laissez votre client FTP ouvert pour pouvoir enlever le fichier .htaccess au cas où cela ne fonctionne pas.
4. Lancez votre navigateur et entrez l’URL : http://www.votresite.com/nexistepas.html

Et là, deux solutions se présentent :

-  Soit votre page test « trouve.html » s’affiche c’est parfait, le module est activé.
-  Soit vous avez une erreur 404 ou encore plus probablement une erreur 500 et malheureusement il n’y a pas grand-chose à faire... si ce n’est retirer tout de suite le fichier .htaccess avec le client FTP (vous l’aviez bien laissé ouvert comme suggéré plus haut, non ?).

Si vous êtes face à ce deuxième cas, vous comprendrez mieux pourquoi nous vous avons suggéré de choisir une période creuse ainsi qu’un répertoire de test. Nous ne pouvons que répéter ici que toute modification du fichier .htaccess peut fortement impacter le fonctionnement de votre site web.

Heureusement, les problèmes rencontrés ne sont pas irréversibles et disparaissent avec la suppression du fichier ou des règles erronées. La prudence s’impose.

Quelques explications sur la règle précédente.

Dans les trois lignes de l’exemple ci-dessus, la première autorise le serveur Apache à suivre les liens symboliques dans ce répertoire. Son utilité permet de corriger un éventuel défaut de configuration dans le fichier httpd.conf.
La deuxième ligne est une instruction d’activation de la réécriture d’URL. Quelles que soient les règles de réécriture que vous voulez mettre en place, de la plus triviale à la plus complexe, l’instruction « RewriteEngine on » devra toujours être insérée dans le fichier .htaccess.
Elle donne simplement au serveur Apache l’instruction de lancer le moteur de réécriture.
La troisième ligne est la règle de réécriture proprement dite, analysons la plus en détail :

RewriteRule ce mot-clé introduit toute règle de réécriture, il est indispensable
^nexistepas.html$ c’est la première partie de la règle, celle qui determine la chaîne de caractères que le module devra rechercher pour la réécrire.
Elle contient deux caractères spéciaux marquant le début (^) et la fin ($) de la ligne
trouve.html la chaîne par laquelle il faudra remplacer celle trouvée à l’étape précédente. En règle générale, elle correspond au nom d’un fichier existant réellement dans votre espace Web.
[L] Un flag (drapeau) signifiant que cette règle est la dernière à appliquer dans ce cas ( L = last = dernier ) et que le module ne doit plus rechercher à réécrire cette chaîne.

Ce premier exemple est bien évidemment trivial mais vous servira de base à l’établissement de toutes les règles de réécriture que vous serez amené à rédiger.
Vous la trouvez trop simple ? Assurez-vous d’avoir parfaitement compris le mécanisme avant de passer aux étapes suivantes, cela va se corser !

Les pièges dans lesquels il ne faut pas tomber.

Nous l’avons déjà mentionné, mais jugeons utile de le répéter. La réécriture d’URL permet le meilleur comme le pire.
Imaginez 2 règles, la première réécrivant abc.html en def.html, la seconde réécrivant def.html en abc.html . Si aucune des deux règles ne comporte le flag [L], vous voilà face à une version informatisée du mouvement perpétuel. Vous avez créé une boucle de laquelle votre serveur ne pourrait pas sortir s’il n’avait ses propres mécanismes de sécurité.
L’aisance avec laquelle une règle mal écrite peut mettre un serveur « sur les genoux » est la raison principale de la non implémentation du module de réécriture chez certains hébergeurs.

Des règles plus utiles.

Il est clair que l’exemple précédent n’a pas de véritable utilité. Ce simple exemple aurait pu s’écrire beaucoup plus simplement avec une seule instruction « Redirect ».
Prenons un cas plus concret...
Les réécritures d’URL sont le plus souvent utilisées pour présenter aux visiteurs une URL plus mnémotechnique ou pour permettre à certains moteurs d’indexer des pages dynamiques avec de nombreux paramètres qu’ils n’auraient pas visité sans réécriture.
Pour les robots d’indexation, la raison en est simple.
Dans le cas d’une URL dynamique du type article.php?num=12 , un moteur ne peut pas déterminer s’il ne va pas tomber dans une boucle sans fin. Un script article.php mal écrit - volontairement ou non - peut l’entraîner vers une multitude de pages satellites ne différant que par leur URL. C’est pour la même raison qu’ils n’indexent pas les pages avec des identifiants de session PHP, une même page étant retournée au navigateur avec une multitude d’identifiants de session différents.

Vous avez un site sur lequel vous présentez un catalogue en ligne. Sur ce site, chaque article comporte 2 pages, par exemple une page commerciale et une fiche technique.
De plus, les informations concernant l’article sont extraites d’une base de données, en se basant sur le numéro d’article.
Les URL des deux pages de l’article 8125 seront donc sous la forme (si votre script se nomme article.php) :

http://www.votresite.tld/article.php?numero=8125&page=1
http://www.votresite.tld/article.php?numero=8125&page=2 

Vous préféreriez, et cela se comprend, que vos visiteurs accèdent à cet article par :

http://www.votresite.tld/article-8125-1.html 
http://www.votresite.tld/article-8125-2.html

Analysons point par point comment réécrire cette règle toujours simple.
Nous voyons dans ces URL qu’elles contiennent deux parties variables : le numéro d’article et le numéro de page, tout le reste étant fixe comme le nom du script et le nom des variables.
La règle s’écrirait comme ceci :

RewriteEngine on
RewriteRule ^article-([0-9]+)-([0-9]+)\.html$  article.php?numero=$1&page=$2  [L]

Cela vous semble compliqué ? Il n’en est rien, voici l’explication :

Nous ne reviendrons pas sur la ligne RewriteEngine on qui est, vous le savez, indispensable. Nous l’omettrons d’ailleurs de manière systématique pour la suite de nos exemples.

Nous retrouvons dans notre règle les parties constantes « article - - .html » et « article.php ?numero= &page= » que nous avons identifiées.
De même, les caractères de début (^) et fin ($) de ligne ont été expliqués précédemment.

Appliquons nous à remplir les blancs.

-  Partie gauche de l’expression

Dans cette partie, nous trouvons deux fois une même chaîne de caractères « ([0-9]+) » qui est basée sur les expressions régulières (regular expressions) familières aux utilisateurs Unix/Linux.
Les parenthèses carrées [ ] déterminent un intervalle, donc [0-9] détermine l’intervalle des nombres « 0 » à « 9 ».
Le signe « + » qui suit immédiatement l’intervalle signifie « une ou plusieurs occurrence(s) de l’expression qui précède », notre intervalle [0-9] dans cet exemple.
Ce qui signifie qu’avec l’intervalle suivi du signe « + », nous sommes en mesure de matérialiser tout nombre entier supérieur ou égal à 0 , ce qui correspond bien à la forme de notre numéro d’article.
Enfin, les parenthèses qui entourent le tout « ([0-9]+) » donnent instruction au moteur de réécriture de grouper la chaîne trouvée et la stocker dans une variable interne parce que nous souhaitons l’utiliser plus tard. Apache stockera donc ces chaînes dans les variables $1, $2, ... $n dans l’ordre dans lequel elles sont analysées, de gauche à droite et nous pourrons y faire référence dans la partie droite de notre règle.
Dans notre exemple, Apache aura stocké les chaînes « 8125 » dans la variable interne $1 et « 2 » dans la variable $2.
Le point décimal ayant une signification particulière dans les expressions, il est utile dans notre cas de le faire précéder par le caractère d’échappement « \. ». Nous verrons ceci plus en détail par la suite.

-  Partie droite de l’expression

Une fois compris ce qui précède, elle est vraiment triviale à comprendre.
Dans l’expression « article.php ?numero=$1&page=$2 » les variables $1 et $2 sont remplacées
respectivement par les chaînes « 8125 » et « 2 » ce qui nous donne bien l’URL avec les paramètres que notre script article.php s’attend à recevoir.
Le dernier élément « [L] » fait comprendre, comme expliqué précédemment que c’est la dernière règle qui s’applique pour cet élément.

Quelques expressions régulières à connaître :

. n’importe quel caractère
[abcd] n’importe lequel de cette liste de caractères
[^abcd] tout caractère non compris dans la liste (autre que a, b, c ou d)
blanc|noir alternative, soit « blanc », soit « noir »
+ Une ou N occurrence(s) de l’expression qui précède (N > 1)
* Zéro ou N occurrence(s) de l’expression qui précède (N>0)
(texte) Groupement permettant l’utilisation des références inverses ($1,... $n)
Est aussi utilisé pour délimiter une alternative comme dans (blanc|noir)
ancre de début de ligne
$ ancre de fin de ligne
\ permet d’échapper tout caractère qui suit et lui ôter sa signification particulière, par exemple \.

Quelques drapeaux (ou flags) utiles.

Voici quelques drapeaux utiles pour faciliter la maintenance d’un site :

[L] Celui-ci vous semble familier, comme nous l’avons vu dans notre précédent exemple. Il mérite toutefois une précision. Lorsque le module de réécriture est actif, les règles sont lues séquentiellement et l’URL est comparée ligne à ligne avec le premier argument de celles-ci jusqu’à la dernière.

Si une réécriture est effectuée, c’est la forme réécrite qui sera utilisée en entrée pour les règles suivantes.

Le flag [L] permet de sortir prématurément de la boucle.

Un autre exemple serait, en début d’une liste de règles :

RewriteRule ^.*\.gif$  -  [L]
RewriteRule ^.*\.jpg$  -  [L]
Nous introduisons ici un nouveau concept, à savoir un second argument vide (ou presque, car il consiste en un seul caractère « - » ) . Cette règle particulière implique qu’il n’y a pas de réécriture, l’URL étant passée sans modification aucune. Elle signale au serveur Apache de passer toutes les URL d’images gif ou jpg sans réécriture, ni traitement successif.
[R]

[R=code]

Dans ces deux formes une redirection est effectuée.

Si l’argument code n’est pas précisé, une redirection 302 (déplacé temporairement) est effectuée. Si vous souhaitez faire savoir au navigateur/robot qu’une page a été remplacée définitivement, utiliser le code 301 comme dans :

RewriteRule ^ancien\.html$ http://domaine.tld/nouveau.html [R=301,L]

Dans ce cas précis, une réécriture "externe" s’impose (utilisation de http://...)

Vous voyez ci-dessus que nous avons combiné deux flags en les séparant par une virgule.
[F] Forbidden - interdit. Retourne un code 403, par exemple :

RewriteRule ^secret.html$ - [F]

( pas de réécriture vu le deuxième argument - )

[NC] NoCase, ou « insensible à la casse ». La règle suivante :

RewriteRule  ^script\.php$  programme.php  [NC,L]

S’appliquera aussi bien à script .php, SCRIPT.PHP ou ScRiPt .PhP

[G] Gone. Cette page n’existe plus et retourne une entête http 410
[N] Force l’analyse et l’exécution de toutes les règles en repartant du début de la liste. Ici encore, comme expliqué plus haut ([L]), c’est l’URL modifiée après exécution de la dernière règle qui est utilisée en entrée, et non l’URL originelle. Attention aux boucles infinies !!
[C] Chain, chaînage avec la ou les règles suivantes jusqu’à la première règle ne se terminant pas par [C]

Apache interprète ce flag comme suit : s’il y a réécriture (la règle est vérifiée), la règle suivante est exécutée avec la chaîne réécrite en entrée.

Si la règle ne se vérifie pas, toutes les règles qui suivent jusqu’à la première ne comportant pas le flag [C] ne sont pas appliquées.

Cette liste n’est pas exhaustive, car il existe d’autres flags supportés. La liste complète est décrite dans la documentation du module mod_rewrite sur le site d’Apache.

Attention aux « répertoires virtuels »

Dans les exemples qui précèdent, nous avons effectué des réécritures qui n’impactaient pas l’arborescence apparente de vos pages, pour simplifier les exemples.

Si, au lieu de réécrire, en reprenant l’exemple précédent :
RewriteRule ^article-([0-9]+)-([0-9]+)\.html$  article.php?numero=$1&page=$2  [L]
nous utilisons
RewriteRule ^article/([0-9]+)/([0-9]+)\.html$  article.php?numero=$1&page=$2  [L]

L’URL apparente aurait la forme /article/8126/2.html au lieu de /article-8126-2.html
Dans ce cas, le navigateur « estime » que la page se trouve dans un répertoire /article/8126 qui n’a pas d’existence réelle sur votre site. Toute tentative de résolution de liens relatifs se fera donc à partir de ce répertoire inexistant et sera vouée à l’échec.

Pour éviter cela, deux solutions se présentent :

-  Utiliser des liens absolus, ou mieux...
-  Faire usage de la balise <base href="http://www.votresite.tld/repertoire/" > à mettre dans l'entête de votre page, entre <head> et  </head>

Les réécritures conditionnelles

Dans les quelques exemples qui précèdent, nous n’avons vu que des réécritures d’URL inconditionnelles, c.à.d. s’appliquant indépendamment du navigateur, de l’adresse IP ou du domaine émettant la requête.
Nous allons maintenant passer à l’étape suivante, à savoir la réécriture sous conditions, à travers quelques exemples concrets.

Une page d’accueil différente selon le navigateur

RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
RewriteRule  ^/$    /complexe.html  [L]
RewriteCond  %{HTTP_USER_AGENT}  ^Lynx.*
RewriteRule  ^/$    /simple.html  [L]
RewriteRule  ^/$    /standard.html  [L]
Un nouveau mot-clé fait son apparition ici : « RewriteCond » ou « condition de réécriture ».

La syntaxe est simple et de la forme :
RewriteCond variable_testée valeur_de_comparaison

Dans l’exemple, testons si l’identifiant du navigateur (%{HTTP_USER_AGENT}) commence par Mozilla (^Mozilla) et est suivi par une chaîne quelconque. (.*)
Si cette règle est vraie, nous réécrivons le répertoire racine du site(^/$ signifie « début de ligne/fin de ligne » ou simplement / seul sur la ligne)) en page « complexe.html » et arrêtons nos réécritures [L]
Procédons de meme pour Lynx, qui se satisfera d’une page simple vu ses fonctionnalités réduites et enfin, si aucune des 2 règles précédentes ne s’applique, soit pour tous les autres navigateurs, redirigons les vers notre page « standard.html »

Protégeons nos fichiers images

Evitons maintenant que d’autres sites ne fassent un lien direct vers nos images, en nous détournant de la bande passante :

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://www.votredomaine.net/.*$ [NC]
ReWriteRule .*\.(gif|png|jpe?g)$ - [F]
En mettant plusieurs conditions à la suite, un ET logique est effectué entre elles. Pour que la règle de réécritue soit effectuée, il faut donc que toutes les conditions soient varies prises isolément. A la première condition FAUSSE, le moteur de réécriture branche directement après la règle et ne teste pas les conditions suivantes.
Si un OU logique est nécessaire, on rajoute le drapeau [OR] en fin de ligne, en le combinant aux autres le cas échéant [NC,OR]

Dans notre exemple, on compare la variable HTTP_REFERER au domaine du site.
Les conditions s’énonceraient en clair « Si la variable HTTP_REFERER n’est pas vide et n’est pas égale au nom de domaine http://www.votredomaine.net/ suivi de n’importe quelle chaîne de caractères (même vide) en faisant abstraction de la casse [NC], alors... »

Notez que le point d’exclamation inverse le test et signifie donc « n’est pas ».
Changez aussi le nom de domaine pour qu’il corresponde au vôtre.

La règle donne instruction de ne pas réécrire l’URL (grâce au signe - utilisé en second argument) mais de retourner une entête « 403 - Forbidden » pour tout fichier se terminant en .gif, .png , .jpeg et .jpg [F]

Le point d’interrogation suivant le « e » dans « jpe ?g » rend cette lettre facultative. Il y aura donc correspondance pour « jpg » et « jpeg ».

Un commentaire toutefois : Certains navigateurs permettent de masquer le HTTP_REFERER, et certains proxies ou firewall ne transmettent pas cette référence.
C’est la raison pour laquelle nous avons la première condition testant si HTTP_REFERER n’est pas vide. Sans cette règle, les visiteurs derrière certains firewall ou proxies ne verraient pas vos images.
Cette dernière limitation démontre bien qu’il n’est pas possible d’éliminer 100% des liens sauvages vers vos images puisqu’il suffit de masquer le HTTP_REFERER pour éviter l’interdiction. Une élimination de 95-98% des liens représente déjà une économie substantielle de bande passante.

Si vous souhaitez autoriser certains domaines amis à faire des liens directs, il suffit d’ajouter pour chacun d’eux une condition supplémentaire :

RewriteCond %{HTTP_REFERER} !^http://votredomaine.net/.*$ [NC]

Cet exemple permet d’accéder aux images dans le cas où votre domaine serait invoqué sans le sous-domaine « www ».

Débarrassons-nous des visiteurs indésirables

La condition s’écrira généralement sous une des formes suivantes :

RewriteCond %{REMOTE_HOST} ^badhost\.baddomain\.tld$
-  teste le nom d’un ordinateur hôte spécifique

RewriteCond %{REMOTE_HOST}  baddomain\.tld$
-  teste le domaine complet (se termine par..., notez l’absence du caractère ^)

RewriteCond %{HTTP_USER_AGENT}   ^VilainRobot.*
-  teste le nom du robot indésirable (HTTP_USER_AGENT commence par la chaîne « VilainRobot »)

RewriteCond %{REMOTE_ADDR}  ^123\.45\.67\.12[5-9]$
-  teste une plage d’adresses IP (de 123.45.67.125 à 123.45.67.129 inclus)

Pourquoi éviter certains robots ?

Tous les robots ne sont pas bénéfiques pour votre sites.
Certains d’entre-eux sont des aspirateurs de site, d’autres collectent les addresses email et finissent par remplir votre boîte aux lettres de courier non-sollicité (spam). Ils ont tous une caractéristique commune : utiliser les resources de votre serveur sans vous apporter aucun visiteur « utile ».
Tous ces robots « indélicats » ne respectent pas le protocole d’exclusion représenté sous la forme du fichier « /robots.txt ».

Soyez très attentifs dans l’écriture de vos règles d’exclusion, par exemple la condition :

RewriteCond %{HTTP_USER_AGENT}   Bot

est beaucoup trop générique et vous priverait du passage de GoogleBot, ce qui n’est sûrement pas ce que vous souhaitez.

Un exemple concret :

RewriteCond %{REMOTE_HOST}  \.laurion\.(com|net)$  [OR]
RewriteCond %{REMOTE_HOST} \.cn$ [OR]
RewriteRule ^.*$   -   [F]

La première condition interdit toute visite en provenance de laurion.com et laurion.net. Cela peut sembler un peu brutal comme règle mais ce robot ne respectant pas le protocole d’exclusion et ne se gênant pas pour « pomper » plus de 100 pages/minutes nous n’avons pas vraiment eu envie de mettre de gants le concernant.

Elle aurait pu s’écrire, en se basant sur le HTTP_USER_AGENT :

RewriteCond %{HTTP_USER_AGENT}  ^IPiumBot   [OR]

La deuxième condition élimine encore plus radicalement tout visiteur provenant de Chine.
Ces règles et conditions ne sont que des exemples et ne sont pas dictées par une quelconque xénophobie de la part de l’auteur. Elles ont néanmoins contribué à réduire de manière significative la bande passante utilisée.

Comment tester différents HTTP_USER_AGENT ?

Il est bien évident que nous ne pouvons pas installer tous les USER_AGENT possible, la liste est trop longue. Certains navigateurs tels que Opera permettent de choisir le USER_AGENT sous lequel on « butine »...
Certains sites Web permettent de vérifier les entêtes reçues très facilement, par exemple http://www.wannabrowser.com/
Cette page, combinée avec une analyse approfondie de vos fichiers logs, vous permettra de mettre au point vos conditions de réécriture pour les différents visiteurs de votre site.

Pour effectuer vos tests, il est judicieux de créer un répertoire temporaire sur votre site, dans lequel vous mettrez un fichier index.html et le fichier .htaccess sur lequel vous travaillez.
Une fois votre fichier .htaccess mis au point, déplacez le dans le répertoire que vous voulez protéger, ou à la racine de votre site.

Des règles différentes selon les répertoires

Un fichier .htaccess placé dans un répertoire régit l’accès à ce répertoire ainsi qu’à tous les sous-répertoires et fichiers de celui-ci.
Vous pouvez bien sûr avoir plusieurs fichiers .htaccess dans des répertoires différents, selon les différentes protections ou réécritures que vous désirez appliquer.

Dans le cas d’un fichier .htaccess situé dans un sous-répertoire du site, les règles et conditions remplacent celles définies à l’échelon supérieur.
Si votre souhait est d’ajouter des règles de réécriture à celles du niveau supérieur au lieu de les remplacer, ajoutez la ligne suivante juste après le « RewriteEngine on » :

RewriteOptions inherit

Cette instruction spécifie que toutes les règles et conditions définies au niveau supérieur sont héritées, en supplément à celles que vous rajouterez dans le fichier .htaccess

Discussion

49 discussions

  • Bonjour,
    comment créer un url rewriting qui fonctionne pour les liens suivants :

    "[(#URL_PAGE{article}|parametre_url{'id_rubrique',#ID_RUBRIQUE})]"

     ?

    Je ne suis pas très bon en code et votre aide serait vraiment bienvenue !
    Merci, Mickaël.

    Répondre à ce message

  • Bonjour

    j’ai un souci de référencement google

    ex :
    http://www.mondomaine.fr/Nouvel-atelier-de-transfo-de,338.html

    au lieu de
    http://www.mondomaine.fr/spip/Nouvel-atelier-de-transfo-de,338.html

    mon domaine pointe sur mon serveur sur une page index.html avec une anime flash
    puis le site (spip) ce trouve dans un sous dossier nommé « spip »
    ( j’utilise les url propre )

    sinon mon htaccess à la racine du site débute par ceci et je pense que mon problème vient de là

    ### Configuration sous-repertoire
    # Chez la plupart des hebergeurs il faut indiquer « RewriteBase / »
    # sinon modifiez cette ligne

    RewriteBase /spip/

    malheureusement il y as énormément de référencements du site
    avec le même problème

    j’ai donc ajouté

    Redirect permanent /-Espace-Grand-Public-.html http://www.mondomaine.fr/spip/-Espace-Grand-Public-.html

    et ça pour de multiples adresses ...
    Quelle est la solution pour redirigé l’ensemble des référencement google

    je ne voudrais pas faire de bourde

    merci pour toutes aide

    fabien

    Répondre à ce message

  • 2

    Bonjour

    Sur mon site SPIP, j’utilise les forums associés à chaque article mais aussi les forums de rubriques.

    Pour les forums de rubriques, je souhaiterai que les messages soient bien indexés par les moteurs de recherche.

    Et que donc, on y accède par des url propres au lieu d’url du type :

    www.monsite.info/spip.php?page=forum-message&id_rubrique=8&id_forum=2338

    Comment faire de l’url rewriting avec les pages des forums ?

    Merci

    • Salut Bruno, moi aussi je cherche à faire : « je souhaiterai que les messages soient bien indexés par les moteurs de recherche. » pour ne pas avoir ça :

      http://www.monsite.info/spip.php?page=forum-message&id_rubrique=8&id_forum=2338

      mais je ne trouve pas non plus - as tu trouvé depuis le temps ?

      merci

    • OUI, j’ai trouvé la solution. L’idée c’est de créer un format d’url spécial pour les forums. Et de réorienter vers un squelette thread.html avec le htaccess.
      Je te donne ce que j’ai fait mais c’est à adapter à ton site.

      Dans le htaccess, ajouter cette ligne :

      ###
      # Redirection des threads (forums)
      RewriteRule thread([0-9]+)/?(.+)?$	spip.php?page=thread&id_thread=$1 [QSA,L]

      et ajouter en l’adaptant le fichier thread.html dans le dossier squelette :

      #FILTRE{mini_html}
      [(#PARAMETRES_FORUM|?) Cette balise (invisible) provoque le recalcul du forum la premiere fois qu'un message est poste (cf. inc/invalideur). ]
      <BOUCLE_thread(FORUMS) {id_thread}>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="#LANG" lang="#LANG" dir="#LANG_DIR">
      <head>
      <title>Question #ID_THREAD : [(#TITRE|textebrut)]</title>
      <meta name="description" content="[(#TEXTE|textebrut|couper{100})]" />
      <INCLURE{fond=inc-head}>
      <link rel="canonical" href="#URL_SITE_SPIP/thread#ID_THREAD/[(#TITRE|url_from_text)]" />
      </head>
      
      <body class="page_article">
      <div id="page">
      	[(#REM) Entete de la page + titre du site
      	-----------------------------------------]
      	<INCLURE{fond=inc-entete}>
      
      	[(#REM) Fil d'Ariane et traitement logo
      	---------------------------------------]
      	<BOUCLE_HIER_ART(ARTICLES){id_article=#ID_ARTICLE}>
      		<div id="hierarchie"><a href="#URL_SITE_SPIP/"><:accueil_site:></a><BOUCLE_ariane1(HIERARCHIE){id_article}> &gt; <a href="#URL_RUBRIQUE">[(#TITRE|couper{60}|supprimer_numero)]</a></BOUCLE_ariane1> &gt; <a href="#URL_ARTICLE">[(#TITRE|couper{60}|supprimer_numero)]</a>[ &gt; (#_thread:TITRE|couper{60}|supprimer_numero)]</div>
      			[(#LOGOTYPE|=={'1'}|?{' ',''})
      				[(#SET{image,[(#LOGO_ARTICLE_RUBRIQUE|logorond{100}|extraire_attribut{src})]})]
      			]
      			[(#LOGOTYPE|?{'',' '})
      				[(#SET{image,[(#LOGO_ARTICLE_RUBRIQUE|image_reduire{100,100}|extraire_attribut{src})]})]
      			]
      	</BOUCLE_HIER_ART>
      	</B_HIER_ART>
      		<BOUCLE_HIER_RUB(RUBRIQUES){id_rubrique=#ID_RUBRIQUE}>
      			<div id="hierarchie"><a href="#URL_SITE_SPIP/"><:accueil_site:></a><BOUCLE_ariane2(HIERARCHIE){id_article}> &gt; <a href="#URL_RUBRIQUE">[(#TITRE|couper{60}|supprimer_numero)]</a></BOUCLE_ariane2>[ &gt; (#_thread:TITRE|couper{60}|supprimer_numero)]</div>
      				[(#LOGOTYPE|=={'1'}|?{' ',''})
      					[(#SET{image,[(#LOGO_ARTICLE_RUBRIQUE|logorond{100}|extraire_attribut{src})]})]
      				]
      				[(#LOGOTYPE|?{'',' '})
      					[(#SET{image,[(#LOGO_ARTICLE_RUBRIQUE|image_reduire{100,100}|extraire_attribut{src})]})]
      				]
      		</BOUCLE_HIER_RUB>
      	<//B_HIER_ART>
      
      
      	<div id="conteneur">
      
      		[(#REM) Contenu principal : contenu de la thread
      		------------------------------------------------]
      		<div id="contenu">
      			[(#REM) Préparation infos auteur
      			-------------------------------- ]
      			<BOUCLE_TESTAUTEUR1(CONDITION) {si #ID_AUTEUR|>{0}}>
      				[(#REM) Auteur enregistré]
      				<BOUCLE_AUTEUR1(AUTEURS){id_auteur=#ID_AUTEUR}{tout}>
      					[(#SET{cartouche,<div class="cartouche"><a rel='nofollow' class='nopuce' href='[(#URL_AUTEUR)]'>	[(#LOGO_AUTEUR|=={''}|?{' ',''})<img src="[(#CHEMIN{auteur.png})]" alt='Membre' />] [(#LOGO_AUTEUR|!={''}|?{' ',''})[(#LOGO_AUTEUR|logorond{60})]] </a><p><small><abbr class="published" title="[(#DATE|date_iso)]">[(#DATE|affdate_jourcourt)][&nbsp;(#DATE|heures)][:(#DATE|minutes)]</abbr>[,<br/><:par_auteur:> <a rel='nofollow' class='nopuce notvisited' href='[(#URL_AUTEUR)]'>(#NOM)</a>][<br/>&#91;<a rel='nofollow' class='nopuce' href="/ecrire/?exec=auteur_infos&id_auteur=(#ID_AUTEUR)"><span class="notvisited">Profil</span></a>&#93;][<br/><a class="spip_out" href="#URL_SITE">(#NOM_SITE)</a>]</small></p></div>})]
      				</BOUCLE_AUTEUR1>
      			</BOUCLE_TESTAUTEUR1>
      				[(#REM) Auteur anonyme]
      				[(#SET{cartouche,<div class="cartouche"><img src="[(#CHEMIN{anonyme.png})]" alt='Non-Membre' /><p><small><abbr class="published" title="[(#DATE|date_iso)]">[(#DATE|affdate_jourcourt)][&nbsp;(#DATE|heures)][:(#DATE|minutes)]</abbr>[,<br/><:par_auteur:> (#NOM)]</small></p></div>})]
      			<//B_TESTAUTEUR1>
      
      			[(#INCLURE{fond=box_start}{boxtype=3}
      				{img1-file=#GET{image}} {img1-class=img-article}
      				{text-title=<big>[(#TITRE|supprimer_numero|textebrut)]</big>} {text-class=#EDIT{titre} titre text-title-article #EDIT{titre}}
      				{text-subtitle=[(#SOUSTITRE)<br />][(#GET{cartouche})]} {text-subtitle-class=soustitre}
      				{text-tag=h1}
      			)]
      				<div class="article">
      					[<p class="#EDIT{hyperlien} lien"><:voir_en_ligne:> : <a href="(#URL_SITE)" class="spip_out">[(#NOM_SITE|sinon{[(#URL_SITE|couper{80})]})]</a></p>]
      					[<div id="texte" class="#EDIT{texte} #EDIT{fichier} forum-texte">(#TEXTE*|accordeon|autoriser_php|br|propre|liens_ouvrants|image_reduire{560,0})</div>]
      
        					[(#REM) Document lié au message
      						--------------------------------]
      						<BOUCLE_doc_lien(spip_documents_liens) {id_objet=#ID_FORUM} {objet=forum} >
      							<BOUCLE_doc(DOCUMENTS) {id_document=#ID_DOCUMENT}>
      								 [(#LOGO_DOCUMENT|#URL_DOCUMENT)]
      							</BOUCLE_doc>
      						</BOUCLE_doc_lien>
      
      
      						[<p class="#EDIT{hyperlien} forum-lien"><:voir_en_ligne:> : <a href="(#URL_SITE)" rel="nofollow" class="spip_out">[(#NOM_SITE|sinon{[(#URL_SITE|couper{80})]})]</a></p>]
      
      						<p class="forum-repondre-message"><a class="spip_in notvisited" href="#repondre"><:repondre_message:>&nbsp;&#40;#NOM&#41;</a></p>
      
      
      
      [(#REM) prépare une partie du formulaire de déplacement du message qui est inclu dans inc_deplacer_forum
      pour que le calcul ne soit fait qu'une seule fois et pas pour chaque message du forum
      uniquement pour l'administrateur]
      <BOUCLE_test_session1(CONDITION){si #SESSION{statut}|=={0minirezo}|oui}>
      	ADMIN
      	#SET{select_rub,<select name="rubrique_dest" style="width:200px;">}
      	<BOUCLE_depforum_rubriques(RUBRIQUES){tout}{par titre}>
      		[(#SET{select_rub,#GET{select_rub} <option value="#ID_RUBRIQUE">[(#TITRE|supprimer_numero)]</option>})]
      	</BOUCLE_depforum_rubriques>
      	#SET{select_rub,#GET*{select_rub}</select>}
      
      	#SET{select_art,<select name="article_dest" style="width:200px;">}
      	<BOUCLE_depforum_articles(ARTICLES){tout}{par titre}>
      		[(#SET{select_art,#GET{select_art} <option value="#ID_ARTICLE">[(#TITRE|supprimer_numero)]</option>})]
      	</BOUCLE_depforum_articles>
      	#SET{select_art,#GET*{select_art}</select>}
      </BOUCLE_test_session1>
      
      					[(#SESSION{statut}|=={0minirezo}|oui)
      					<INCLURE{fond=inc_supprimer_forum}{id_forum=#ID_FORUM}>
      					<INCLURE{fond=inc_deplacer_forum}{id_forum=#ID_FORUM}{select_rub=#GET{select_rub}}{select_art=#GET{select_art}}>
      					]
      
      
      
      
      
      					<div class='forum-fil'>
      						<B_forums_fils>
      							[(#REM)	le bandeau de pub au début de l'article
      							------------------------------------------------]
      							[(#CONFIG{'article/pub2'}|=={'0'}|?{'',' '})
      								[(#NO_PUB|=={'oui'}|?{'',' '})
      									[(#INCLURE{fond=inc-pub2}{id_article})]
      									<br clear='all'>
      								]
      							]
      
      							<ul class='forum'>
      						<BOUCLE_forums_fils(FORUMS){id_parent}{par date}>
      
      						<li>
      							<div class="forum-message" >
      								<div class="forum-chapo">
      									[(#REM) Infos Auteur
      									--------------------]
      									<BOUCLE_TESTAUTEUR2(CONDITION) {si #ID_AUTEUR|>{0}}>
      										[(#REM) Auteur enregistré]
      										<BOUCLE_AUTEUR2(AUTEURS){id_auteur=#ID_AUTEUR}{tout}>
      											<a rel='nofollow' href="#URL_AUTEUR">
      												[(#LOGO_AUTEUR|!={''}|?{' ',''})[(#LOGO_AUTEUR|logorond{60})]]
      												[(#LOGO_AUTEUR|=={''}|?{' ',''})<img src="[(#CHEMIN{auteur.png})]" alt='Membre' />]
      											</a>
      											<div class="#EDIT{titre} forum-titre"><a href="#forum#ID_FORUM" name="forum#ID_FORUM" id="forum#ID_FORUM">#TITRE</a></div>
      											<small>[(#DATE|affdate_jourcourt)][&nbsp;(#DATE|heures)][:(#DATE|minutes)][, <:par_auteur:> <a href="#URL_AUTEUR"><span class="#EDIT{qui} notvisited">(#NOM|couper{80})</span></a>]&nbsp;[<a rel='nofollow' href="/ecrire/?exec=auteur_infos%26id_auteur=#ID_AUTEUR"><span class="notvisited">Profil</span></a>]&nbsp;<a class="spip_out" href="#URL_SITE">#NOM_SITE</a></small>
      										</BOUCLE_AUTEUR2>
      									</BOUCLE_TESTAUTEUR2>
      										[(#REM) Auteur anonyme]
      										<img src="#CHEMIN{anonyme.png}" alt='Non-Membre' />
      										<strong class="#EDIT{titre} forum-titre"><a href="#forum#ID_FORUM" name="forum#ID_FORUM" id="forum#ID_FORUM">#TITRE</a></strong>
      										<small>[(#DATE|affdate_jourcourt)][&nbsp;(#DATE|heures)][:(#DATE|minutes)][, <:par_auteur:> <span class="#EDIT{qui}">(#NOM|couper{80})</span>]</small>
      									<//B_TESTAUTEUR2>
      								</div>
      
      								<div class="#EDIT{texte} forum-texte">
      									[(#TEXTE|lignes_longues)]
      									[<p class="#EDIT{hyperlien} forum-lien"><:voir_en_ligne:> : <a href="(#URL_SITE)" rel="nofollow" class="spip_out">[(#NOM_SITE|sinon{[(#URL_SITE|couper{80})]})]</a></p>]
      
      									<br class='nettoyeur' />
      									[(#REM) Document lié au message
      									--------------------------------]
      									<BOUCLE_doc_lien_fils(spip_documents_liens) {id_objet=#ID_FORUM} {objet=forum} >
      										<BOUCLE_doc_fils(DOCUMENTS) {id_document=#ID_DOCUMENT}>
      											 [(#LOGO_DOCUMENT|#URL_DOCUMENT)]
      										</BOUCLE_doc_fils>
      									</BOUCLE_doc_lien_fils>
      
      
      									[(#SESSION{statut}|=={0minirezo}|oui)
      										<INCLURE{fond=inc_supprimer_forum}{id_forum=#ID_FORUM}>
      										<INCLURE{fond=inc_racine_forum}{id_forum=#ID_FORUM}>
      									]
      
      									[<p class="forum-repondre-message"><a class="spip_in notvisited" href="(#PARAMETRES_FORUM|url_reponse_forum|parametre_url{'url_retour',#SELF})"><:repondre_message:>&nbsp;&#40;#NOM&#41;</a></p>]
      								</div>
      							</div>
      							<BOUCLE_Forums_Boucle(boucle_forums_fils)></BOUCLE_Forums_Boucle>
      						</li>
      
      						</BOUCLE_forums_fils>
      							</ul>
      						</B_forums_fils>
      					</div> <!-- forum-message -->
      
      					[(#REM)	la pub en fin d'article
      					--------------------------------]
      					[(#CONFIG{'article/pub3'}|=={'0'}|?{'',' '})
      						[(#NO_PUB|=={'oui'}|?{'',' '})
      							[(#INCLURE{fond=inc-pub3}{id_article})]
      						]
      					]
      
      					<br class='nettoyeur' />
      				</div> <!-- article -->
      			[(#INCLURE{fond=box_end}{boxtype=3})]
      
      			<p id="repondre"></p>
      			#FORMULAIRE_FORUM{#SELF#forum#ID_FORUM}
      
      			[(#REM) Abonnement Ó la lettre d'informations
      			---------------------------------------------]
      			<br class='nettoyeur' />
      			[(#CONFIG{'article/newsletter'}|=={'1'}|?{' ',''})
      				#FORMULAIRE_SPIP_LISTES_INSCRIPTION{#CONFIG{'article/newsletter_num'}}
      			]
      
      
      			[(#REM) Affiche une formulaire de devis KELTRAVO
      			------------------------------------------------]
      			[(#INCLURE{fond=inc-keltravo}{id_rubrique})]
      
      		</div> <!-- contenu -->
      
      		[(#REM) Menu de navigation laterale
      		-----------------------------------]
      		<div id="navigation">
      
      
      			[(#REM) Navigation THELIA
      			-------------------------]
      			[(#INCLURE{fond=inc-thelia-nav})]
      
      			[(#REM) Affiche un tÚmoignage alÚatoire.
      			L'option peut Ûtre dÚs/activÚe globalement dans CFG Article
      			Si c'est le cas, l'option peut Ûtre dÚs/activÚe pour chaque article
      			-------------------------------------------------------------------]
      			[(#NO_TEMOIN|=={'oui'}|?{'',' '})
      				[(#CONFIG{'article/temoin'}|=={'0'}|?{'',' '})
      					<INCLURE{fond=inc-temoignage}{id_article}>
      				]
      			]
      
      
      			[(#REM) Capture des prospects
      			-----------------------------]
      			[(#NO_SQUEEZE|=={'oui'}|?{'',' '})
      				[(#INCLURE{fond=inc-squeeze})]
      			]
      
      			[(#REM) Affiche un encart pour inscription Artisans KELTRAVO
      			-----------------------------------------------------------]
      			[(#INCLURE{fond=inc-keltravo-artisan})]
      
      		</div><!-- fin navigation -->
      	</div><!-- fin conteneur -->
      
      	[(#REM) Pied de page ]
      	[(#INCLURE{fond=inc-pied})]
      
      </div><!-- fin page -->
      
      </body>
      </html>
      
      </BOUCLE_thread>
      <//B_thread>

    Répondre à ce message

  • Pascal Boulerie

    L’article ne parle pas de la directive RewriteBase , essentielle quand le site est hébergé dans un sous-répertoire et non pas à la racine.

    L’adresse http://immo.wildcroft.com/publication/article27.html est obsolète et ne permet plus d’accéder à l’article consacré au fichier .htaccess. Cet article semble toutefois être disponible ici-même :
    http://www.spip-contrib.net/Le-fichier-htaccess

    Répondre à ce message

  • Bonjour,

    J’ai cherché sur le Net, mais n’ai point trouvé. Y aurait-il moyen que l’URL rewriting de SPIP convertisse toutes ses URLs en minuscules ? C’est tout simple, on est culturellement habitué aux minuscules dans les URLs, et SPIP respecte la casse du titre d’origine. Existe-t-il un moyen simple de convertir et d’utiliser des URLs toutes en minuscules ?

    Je précise, j’utilise SPIP 1.9.2 et bientôt — dès que j’ai trouvé des équivalences de plugins — SPIP 2.0.

    Je vous remercie d’avance.

    Répondre à ce message

  • Bonjour,
    J’ai mis en place sur mon site la réécriture d’URL. J’utilise pour cela le fichier inc-urls-html.php3 et j’ai mis dans .htacces ceci :

    RewriteEngine on

    # urls spip

    RewriteRule ^article([0-9]+)\.html$ /article.php3 ?id_article=$1 [L]

    RewriteRule ^rubrique([0-9]+)\.html$ /rubrique.php3 ?id_rubrique=$1 [L]

    RewriteRule ^breve([0-9]+)\.html$ /breve.php3 ?id_breve=$1 [L]

    Cela marche sauf pour deux choses :

    -  le surlignage dans le moteur de recherche : j’obtiens une url du type article55.html ?var_recherche=xxx mais sans surlignage du mot cherché

    -  la découpe d’un article en pages et le sommaire (voir http://www.spip-contrib.net/article175.html) : j’obtiens une url du type article55.html ?artsuite=2#sommaire_1 mais je n’arrive pas à changer de page.

    Bref tout se passe comme si ce qui suit articlexx.html n’était pas interpreter.

    Merci d’avance pour votre aide.

    Répondre à ce message

  • Juste une chose que personne ne dit ! Et en local histoire de tester tout ca avant de le mettre en exploitation comment on fait ? Bon en cherchant j’ai fini par comprendre mais j’ai du changer tout mes liens de par exemple
    index.php ?id=untexte
    en
    index-untexte.html

    Sinon est-ce normal de ne pas avoir eu a écrire

    AddModule mod_rewrite.c

    dans le fichier httpd.conf

    Répondre à ce message

  • pl4tipus

    Bonjour à tous !
    Juste au sujet des dossiers virtuels, (arrêtez moi si je me goure), l’ajout de la balise <base /> n’est pas forcement necessaire dans l"hypothese ou l’on insererait un « \ » juste avant le slash, pour enlever au caractere sa signification veritable au sein d’une expression, ce qui donnerait un truc du genre :

    Options +FollowSymlinks

    RewriteEngine on

    RewriteRule ^(.+)\/([0-9]+)\.html$ index.php ?page=$1&id=$2 [F]

    Répondre à ce message

  • Je viens de découvrir les variantes de squelette, c’est Génial !
    Les réécriture d’url c’est génial !!!!
    Mais est ce que quelqu’un saurait combiner les deux ??????
    merci d’avance !

    Répondre à ce message

  • Excellent article ! très pédagogique :-)

    j’ai quelques peu modifié les lignes « Protégeons nos fichiers images »

    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http://www.domaine.net/.*$ [NC]
    RewriteRule .*\.(gif|png|jpe?g)$ http://www.domaine.net/stop_vol.img [R=301,L]

    le fichier « stop_vol.img » étant en fait une image (renommée) GIF ou autre ...

    c’est un peu « bourrin » mais je ne trouve pas comment faire mieux :

    -  empêcher toutes les images sauf celle qui viendra en remplacement, qui pourra donc afficher un message, une bombe, un truc fun ...

    si vous trouvez ça m’intéresse,
    merci :-)

    Répondre à ce message

  • bonjour
    j’essaie de passer mon site ou plutot mes articles au format « url rewriting » mais cela ne fonctionne pas pourtant après le petit test recommandé il n’y a pas de probleme celui-ci marche (je suis chez nuxit et le rewriting est activé)pour l’instant je fais mes essais en local avec lampp.j’ai mis dans mon « htaccess » ceci en chachant que mon url de départ est celle-ci

    http://localhost/Lienversversion4_6/articles.php?lng=fr&pg=4

    dans mon htaccess ceci

    RewriteEngine on
    RewriteRule ^nexistepas.html$ trouve.html [L] ... pour le test
    RewriteRule ^article-([0-9]+)-([0-9]+)\.html$ article.php ?lng=$1&pg=$1 [L]

    et bien sur cela ne marche pas
    une idée ? merci

    Répondre à ce message

  • 4

    C’est vrai qu’il est interessant cet article, mais alors je dois vraiment être con, car j’essaie de le mettre en action sur easyphp, et ca marche po

    J’ai enlevé le commentaires aux 2 lignes indiqués en début de texte et je regarde dans mon phpinfo mais je ne vois pas de mod_rewrite

    Y a til une action spéciale à faire ?

    • Dan Hetzel

      Normalement, des deux lignes suffisent pour faire fonctionner le mod_rewrite...

      Mais easyphp 1.6 installe Apache 1.3.24 qui a un bug au niveau du morule rewrite.c sous windows...

      Tu devrais installer le version 1.7RC1 qui vient de sortir, cela te fera apache 1.3.8 et php 4.3.2 (ou 4.3.3 je ne sais plus)

      Si tu coinces encore, viens sur le Hub, on essayera de faire fonctionner ça :-)

    • Dan Hetzel

      Tu as bien redémarré Apache tout de même ? ;-)

    • Oui j’avais relancé le server plusieurs fois. J’avais lu justement les problèmes avec les vieilles versions d’apache. J’ai donc : php 4.3.3, mysql 1.3.28.
      Malheureusement tjrs rien n’y fait. Dans le phpinfo(), je n’ai pas la ligne du additional module, et l’exemple ne marche tjrs pas.

      Par contre j’ai lu qu’il y avait des soucis avec les sessions. Si c’est le cas, je dois me passer de l’url rewriting car j’ai absolument besoin des sessions

      Merci de votre aide

    • Il n’y a pas de problème avec les sessions, dans la mesure où le répertoire servant à les stocker existe bien...
      Recherche dans php.ini la partie ressemblant à ;

      ; Handler used to store/retrieve data.
      session.save_handler = files
      
      ; Argument passed to save_handler.  In the case of files, this is the path
      ; where data files are stored. Note: Windows users have to change this 
      ; variable in order to use PHP's session functions.
      session.save_path = C:/phpdev\php\temp;

      En adaptant le répertoire à ton cas...

      Dan

    Répondre à ce message

  • 6
    KotKotCodec

    Bonjour a vous j’utilise APACHE 1.3.2 sur WIn 2000 server.

    Avec un PHP 4.2.2 et postgresQL

    Ouf

    Voila mon PB,

    RewriteRule ^/frm_boutique.asp$ http://192.168.231.156/commande_express.php [L]

    Cette regla marche bien

    toute personne essayant d’aller sur ....asp et rediriger vers ....php

    PAR CONTRE

    RewriteRule ^fiche_produit-([a-z]2)-([a-z]3)-([0-9]3)\.html$ fiche_produit.php ?langue=$1&id=$2 [NC,L]

    Celle la ne marche pas

    PK ??

    Le but est de creer une page html depuis mes pages dyn PHP, on ne passe que 2 parametres ’langue=XX’ et id=’XXX000’

    Merci

    • Dan Hetzel

      Bonjour,

      Comme je vois certains chiffres en italique, j’imagine que tu as mis les parenthèses qui vont bien :

      RewriteRule ^fiche_produit-([a-z]{2})-([a-z]{3})-([0-9]{3})\.html$ fiche_produit.php ?langue=$1&id=$2 [NC,L]

      Tu as donc 2 lettres, suivies de 3 lettres, suivies de 3 chiffres.
      Par contre, dans la deuxième partie de l’expression, tu ne traites que 2 variables... il t’en manque donc une.
      Si tu donnais une URL complète telle que tu la voudrais, et sa correspondance dynamique, ce serait plus simple.

    • KotKotCodec

      Quelle rapidité

      Ok

      Mes urls sont de la formes :

      http://192.168.231.156/fiche_produit.php?langue=FR&id=NIA001

      Avec FR ou EN ou IT ou ES pour la langue et c’est tout.

      Et NIA001 ou NIA002 ou LAV001 pour l’id

      Et je voudrais avoir

      http://192.168.231.156/produits/produit-FR-NIA001.html

      voili voilo

    • Dan Hetzel

      Salut,

      La rapidité vient de l’alerte email lorsqu’un message est ajouté à la suite de l’article. Merci à Spip pour cela. ;-)

      C’est donc ta règle de réécriture qui est mauvaise...
      En effet, ton deuxième paramètre comprend des chiffres/lettres (lettres en majuscule)

      Pour convertir http://192.168.231.156/produits/produit-FR-NIA001.html , il suffit d’analyser ce que tu as en entrée et ce que tu veux en sortie...

      RewriteRule  produit-([A-Z]{2})-([A-Z0-9]{6})\.html  fiche_produit.php?langue=$1&id=$2 [L]

      Dans ce cas,tu isoles les parties variables en 2 groupes distincts :
      -  2 lettres majuscules pour la langue ($langue)
      -  6 lettres majuscules et digits pour la référence ($id)

      Ces 2 groupes sont donc repris en deuxième partie d’expression sous les variables $1 et $2

      Comme tes deux exemples ne sont pas consistants, vu que dans le deuxième tu utilises un répertoire /produits/ , garde à l’esprit qu’il te faudra peut-être utiliser la balise <base href=.....> pour que tes liens/images soient résolus. ;-)

      Cordialement

      PS : il y a d’autres articles sur la réécriture et le PHP sur le Hub, dans la partie « publications » rédigée sous Spip

      PS2 : si tu as majuscules et minuscules, il faut modifier la règle :

      RewriteRule  produit-([A-Za-z]{2})-([A-Za-z0-9]{6})\.html  fiche_produit.php?langue=$1&id=$2 [L]
    • KotKotCodec

      Merci encore.

      Ca marche mais comme ca chez moi :

      RewriteRule ^/produit-([A-Z]2)-([A-Z0-9]6)\.html$ http://192.168.231.156/fiche_produit.php?langue=$1&id=$2 [L]

      toutefois

      ce n’est pas EXACTEMENT le comprotement que je recherche.

       :)

      En effet je voudrais CREER a la volee la copie HTML de mes pages PHP.

      Car google ne reference pas nos page produits ( a cause de la SESSION PHP, parait il).

      Je cherche donc une solution pour que si QQ1 (google) passe sur mon site il puisse enfin indexe mes pages.

      Voili Voilo

    • Dan Hetzel

      La réécriture d’URLs ne va pas créer pour toi des pages HTML... parce qu’elle fonctionne dans l’autre sens.

      Elle permet de « présenter au monde » des URLs fictives qui ressemblent à des pages HTML, et de s’occuper de la conversion de ces URLs en appels de pages dynamiques.

      Si tu veux que les robots puissent indexer tes pages sans identifiants de session, il faut que tu te charges toi-même de la détection de ces robots et le cas échéant ne pas lancer de session php. Il faut pour cela que ton site puisse être visité en profondeur sans que l’absence de sessions ne soit un obstacle. C’est donc une problématique de conception de site, et non de réécriture d’URL.

      Tu peux utiliser ce code pour déteminer s’il faut démarrer une session ou non. A toi à compléter la liste des robots...

      /* Ouverture d'une session, utilise une variable tableau SESSION 
      pour stocker les variables à tracer */
      
      // Spider/Bot pour référencement 
      $spiders = array("Googlebot", "crawler", "Slurp", "Fast","ia_archiver","Scooter","Robot","VoilaBot","W3C","ZyBorg","Deepindex","xecho"); 
      $from_spider = false; 
      foreach($spiders as $Val) 
      { 
      	if (eregi($Val, $_SERVER["HTTP_USER_AGENT"])) 
      	{ 
      		$from_spider = true;
      		break; 
      	} 
      } 
      
      // Session 
      ini_set("session.use_trans_sid", "0");
      if(!$from_spider) {
      	session_start();
      	session_register("SESSION");
      }
    • Bonjour,
      et merci grandement pour ce tutoriel très instructif. Enfin quelqu’un qui explique ces notions barbares ! Chez mon hébergeur mutualisé, la redirection fonctionne, si je tape article=28.html, la page article.php ?id_article=28 s’ouvre bien sous son adresse virtuelle.

      Cependant, les boucles de SPIP appelant les articles par #URL_ARTICLE court-circuitent cette merveilleuse réécriture à la volée et c’est bel et bien l’adresse réelle avec le ? qui s’affiche dans la barre d’adresse du navigateur. Horreur et putréfaction !!! Y a-t-il un moyen de corriger cela ?

      Pour le script de désactivation des sessions, pour les moteurs de recherche, où est-ce qu’on le place au juste ?

      Merci d’avance

    Répondre à ce message

  • 3

    Magnifique article !
    Alors je suis encore plus déçu que cela ne marche pas chez moi - toujours ’Error 404’ au premier test.

    J’utilise EasyPHP 1.7 avec Windows xp. J’ai bien vérifié (et corrigé) les 2 lignes mentionnées dans httpd.conf

    Que puis-je faire encore ?

    merci, Paolo

    • j’ai trouvé !
      en fait avec easyphp 1.7 il suffit d’aller activer le chargement et
      l’utilisation du module rewrite dans le fichier httpd.conf (clicker-droit sur
      l’icône easyphp, configuration, apache) puis chercher les lignes :

      LoadModule rewrite_module modules/mod_rewrite.so

      et

      AddModule mod_rewrite.c

      qu’il suffit de décommenter.

      redémarrer ensuite easyphp
      et voilà !

      J’ai aussi trouvé pour redhat si jamais ça vous arrive : en fait ces deux lignes sont par défaut activées (non-commentées) mais il y a un autre endroit où il faut activer un truc : il faut trouver la ligne (où on parle d’htaccess
      dans les commentaires) suivie de :

      AllowOverride None

      qu’il faut changer en

      AllowOverride All

      voilà... ça marche.

      Maintenant, n’étant pas un expert je ne peux garantir ce que cela peut impliquer en terme de sécurité (AllowOverride All), ça marche certes ! mais peut-être l’avis d’un spécialiste serait bienvenu pour confirmer que c’est bien la marche à suivre, et qu’il n’y a pas quelques petits détails à peaufiner dans le fichier .htaccess lui-même ?...

    • Je découvre que cela ne marche pas, car mon site est dans un répertoire « Alias ». Quelqu’un sait peut-être que dois-je faire pour utiliser .htaccess là-dedans ?

      Paolo

    • err 404, ben il ne trouve pas la page.

      Regarde bien l url que tu as saisie, ss doute, il manque le dossier virtuel ou le nom du fichier en question.
      Si tj pas bon verif code de reecriture

    Répondre à ce message

  • 4

    Moi j,ai un erreur 400 a la place :s

    • Dan Hetzel

      Salut,

      Tu ne donnes pas beaucoup d’infos, donc je sors la boule de crystal... ;-)
      Windows + easyphp 1.6 ?

      Si c’est le cas, c’est normal car la version Apache installée (1.3.24) a un bug de réécriture identifié sous windows. Ce bug est corrigé avec la 1.3.27, il te suffit donc d’installer EasyPhp 1.7 et tout rentrera dans l’ordre.

      Dan

    • Salut à tous, et merci à Dan pour ces explications de haut niveau et d’excellente qualité !

      ... sauf que je comprends pas pourquoi ça ne marche pas chez moi :(

      (j’ai une erreur plus classique : la fameuse 404)

      je bosse sur un redhat 9 (sur lequel j’ai downgradé Apache en 1.3.27 et PHP en 4.3.2 - pour pouvoir intégrer pdflib - jusque là ça marche super bien)
      mais quand je fait le test du nexistepas.html/trouve.html il me fait encore une erreur 404 (j’ai bien vérifié que httpd.conf load le module rewrite, tout va bien, on voit bien apparaître mod_rewrite aussi dans phpinfo, je ne vois pas d’erreur particulière dans les logs, sauf apache qui ne trouve pas le fichier bien entendu)

      j’ai essayé aussi sur mon poste (win2000 pro SP4 avec tous les patchs etc. avec easyphp1.7, tout neuf, rien n’a été modifié après l’installation, je fais tourner easyphp en services) et là encore erreur 404 !...

      Kess kiss pass ?...
      (merci d’avance)

    • PS : Dan, j’ai bien vu le « et malheureusement il n’y a pas grand-chose à faire... » mais c’est bien ce point précis que je souhaite élucider.

      Comment est-il possible que ça marche chez l’un et pas chez l’autre ? (je peux facilement comprendre que sur linux telle ou telle distro contient un paramétrage particulier qui empêche le fonctionnement normal, mais sous windows avec le même easyphp... ça devient plus étrange !)

    • mmmmmmmm, ben j’étais pas bien réveillé ! (dur dur le début de l’année) en fait pour easyphp il suffisait d’aller activer le mod_rewrite dans httpd.conf

      désolé !

      ... mais j’ai toujours mon problème sur la Redhat. Je continue les investigations...

    Répondre à ce message

  • 1

    Article très complet. Tout fonctionne sur notre site, mais pas depuis easyphp (quand je suis dans le train ;o).
    Si je mets dans le htaccess :

    DirectoryIndex sommaire.php index.html index.php
    Options +FollowSymlinks
    ErrorDocument 404 /404.php
    RewriteEngine on
    RewriteRule ^agence\.html$ agence_atypik.php [QSA,L]

    j’ai une erreur 404, sans rediriger sur la 404.php

    Les modules nécessaires ne sont pas en commentaire dans le fichier de config d’apache, et pas activés dans le phpinfo !

    Une info à ce sujet ?

    • Dan Hetzel

      Salut Pascal,

      Merci pour tes compliments sur l’atricle, cela fait toujours plaisir. ;-)

      Tu as probablement une version 1.6 d’EasyPhp.
      La version Apache 1.3.24 installée par défaut avec celle-ci est connue pour ses bugs (documentés) sous windows (principalement dans le module rewrite.c)

      Le mieux serait d’installer la dernière version EasyPhp qui comprend une version plus récente d’Apache (1.3.27 si je ne m’abuse) ne présentant plus ces bugs.

      L’erreur 404 non redirigée est normale dans ce cas, comme la redirection (interne à Apache) ne représente plus l’URL « à l’examen » ... donc la directive ErrorDocument ne s’applique pas.
      Le ErrorDocument devrait jouer si tu entres une mauvaise URL dans la barre d’adresse. Si ce n’est pas le cas, c’est que la directive AllowOverride n’a pas les bons arguments dans le fichier httpd.conf.

      Cordialement,

      Dan

    Répondre à ce message

  • 1

    Bonjour,

    comme cette contrib a plus que 3 ans j’aimerais bien savoir si elle fonctionne toujours sans problème avec la version spip actuelle.

    Est-ce que quelqu’un pourrais m’éclaircir la dessus avant que je me lance à comprendre comment cela marche ?

    Merci d’avance

    joz

    • Bavant devant les fonctionalités de SPIP 1.9, Il fallait bien un jour y passer. MAIS comment garder les 1100 aticles et 600 rubriques sous 1.8.3 si bien référencés chez Goooogle à l’aide de url friendly... Pour ceux qui souhaite faire le pas, voici la démarche :
      Pré-requis : Le kit url-friendly (le fichier inc-url-friendly.php3 surtout) ; je ne reviens pas sur la forme des url.

      copier inc-url-friendly.php3 en friendly.php dans ecrire/url/ de votre 1.9 en ayant changé la ligne « require... » en :

      ...
      require ’ecrire/charsets/iso-8859-1.php’ ;
      ...

      modifiez votre fichier .htaccess de la manière suivante :
      -  commentez toutes les lignes sauf celles concernant les fichiers ou repertoire existant, et RewriteEngine On ;)
      -  ajoutez la règle de réécriture :

      ######### de quoi décortiquer les adresses virtuelles######################
      RewriteRule ^.*(article|rubrique|breve|auteur|mot|forum)(.*).html$ spip.php ?page=$1&id_$1=$2 [QSA,L]

      Pour finir n’oubliez pas de modifier dans ecrire/mes_options.php la ligne concernant le type d’url en :

      $type_urls = ’friendly’ ;

      le tour est joué, vous pouvez passer en 1.9 avec url-friendly, sans perdre votre référencement. Il manque certainement des choses à ce post mais je suis certains que des spécialistes vont se pencher dessus. (ATTENTION, ne sont pris en compte que les pages article|rubrique|breve|auteur|mot|forum, et bien sûr aucune garantie n’est fournie !

      à vous lire.

    Répondre à ce message

  • Bonjour,

    J’ai lu cet article (un parmi tant d’autre sur rewrite de apache) je suis entrain de virr fou avec ce module. Y a rien qui fonctionne ! Je voulais modifier un url de : http://monsite.com/sgc/accueil/pid/737?parent=701
    en : http://monsite.com/sgc/accueil/pid/737/parent/701

    mais rien n’a faire j’ai essayé beaucoup de truc que j’ai vu et j’ai lu et relu la doc de apache.

    1)
    RewriteEngine On
    RewriteRule ^([0-9]+)/parent/([0-9]+)$ $1 ?parent=$2 [L]
    RewriteLogLevel 9
    RewriteLog rewrite.log

    2)
    RewriteEngine On
    RewriteCond %QUERY_STRING ^parent=([0-9]+)$
    RewriteRule ^([0-9]+)/parent/([0-9]+)$ $1 ?parent=%1 [L]
    RewriteLogLevel 9
    RewriteLog rewrite.log

    3)

    RewriteEngine On
    RewriteCond %QUERY_STRING ^parent=([0-9]+)$
    RewriteRule ^/sgc/accueil/pid/([0-9]+)/parent/([0-9]+)$ /sgc/accueil/pid/$1 ?parent=%1 [QSA]
    RewriteLogLevel 9
    RewriteLog rewrite.log

    et bien d’autre...
    tout ce que je fait n’apporte rien aucune modification. Y a t-il encore un guru sur ce forum qui peut m’aider ?

    Répondre à ce message

  • Bonjour,

    J’ai conscience d’arriver bien après tout le monde mais je m’en sors pas là

    Je travaille avec un site qui existe déjà dont on a fait une copie locale

    J’ai easyphp 1.8, j’ai décommentés les 2 modules et l’exemple avec trouve.html marche très bien

    Or quand je reprends l’ancien fichier de redirection (qui faisait entre autre

    RewriteRule ^(.*)/(article|rubrique|breve|auteur|site)(.*).html$ $1/$2.php3 ?id_$2=$3 [QSA]
    RewriteRule _([0-9]+)\.html$ /article.php3 ?id_article=$1 [QSA]

    # Un article
    RewriteRule _([0-9]+)\.html$ /article.php3 ?id_article=$1 [QSA,L]

    (je comprends pas bien pourquoi j’ai 2 règles pour les articles mais passons), ça ne fonctionne pas -> article464.html fait not found alors que article.php3 ?id_article=464&recalcul=oui marche très bien

    je suis sous spip agora j’ai donc le fichier qui se nome agora.htaccess à la racine de mon site
    J’ai essayé de le renommer en htaccess tout court mais toujours le problème, or sur le site en ligne ca fonctionne donc j’hésite à penser que les règles sont mal faites...

    Ca m’énerve en lisant l’articles j’avais l’impression que c’était clair et là paf jsuis coupée net dans mon élan >_<

    Répondre à ce message

  • bonjour, bon meme si j’ai pas forcément tout compris je doit reconnaitre que j’en ai déjà pas mal appris !!
    merci beaucoup

    cependant il me reste un petit souci :
    pour les rubriques ca marche (j’ai meme réussi à modifier l’affichage)
    les articles pas de problèmes mais pour les pages de mot-clé l’url normal (mot.php ?id_mot=...) et je ne comprends pas pourquoi ! quelqu’un peut m’aider ?

    Répondre à ce message

  • 1

    Bonjour,
    La réécriture d’url ne fonctionne pas :
    Erreur 404 systématique
    SAUF pour le test avec
    « RewriteRule ^nexistepas.html$ trouve.html [L] »

    Ma configuration :

    Serveur local (debian)

    Apache 2, PHP5, SPIP 1.8.3, Mysql 5.0.18

    mod_rewrite activé dans apache,

    url propres2 dans mes_options.php3,

    fichier .htaccess par défaut

    Une idée ?

    • erreur dans le texte : ne fonctionne pas non plus avec « RewriteRule ^nexistepas.html$ trouve.html [L] »

    Répondre à ce message

  • 1

    Bonjour,
    je suis face à un petit problème dont personne n’a trouvé la solution sur le phorum : J’utilise la réécriture d’url, tout fonctionne... sauf que quand je change le titre d’un article existant, l’url ne change pas !

    Y a t il un « cache » ou sont stockées ces urls ? J’ai tout tenté, mais même en réinstallant la base sur un autre spip, c’est toujours les premières url qui apparaissent !!!!

    Help, je sèche !!

    • Bon, quand on cherche, on finit toujours par trouver. Les url propres sont stockées dans la base de données !!

      Mais, existe-t-il une fonction cachée pour vider les champs stockés dans la base ?

      Bon, peut-être que ça ne sert à personne d’autre que moi, mais quand je bosse sur 5 site à la structure identique, je fais la base sur le premier, puis je la recopie sur les autres. Je n’ai plus qu’a changer quelques titre d’articles et hop !

    Répondre à ce message

  • 1

    j’ai lu tout le tutorial mais j’ai toujours pas la solution a mon probleme (bien que l’article soit extremement bien redigé)
    jaimerais empecher les gens d’aller à toute url qui n’est pas un fichier à la racine de mon hebergement (soit, avoir une redirection de tous les .php qui sont dans des sous dossiers) mais j’arrive pas à le faire, et faire une redirection pour chaque fichier serait longue et repetitive, je sui ssur qu’il y a un moyen simple.

    Si vous le connaissez merci de m’aide =)
    _Marikou

    • Tu peux peut-être essayer de mettre un .htaccess dans chacun des répertoires que tu veux rediriger.

    Répondre à ce message

  • 1

    Bonjour et bravo pour ce site, son equipe et son travail.
    cette contrib et super...mais...j’arrive pas a la mettre en place... :(
    . Je voudrais ré-ecrire mes fichiers de squelette de cette facon
    agenda.php3 ?id_rubrique=xx a la facon agendaxx.html
    J’ai donc fait modif ds htaccess de la facon suivante
    Options +FollowSymlinks
    RewriteEngine on

    RewriteRule ^/agenda([0-9]+)\.html$ /agenda.php3 ?id_rubrique=$1 [QSA,L]
    RewriteRule ^/planning([0-9]+)\.html$ /planning.php3 ?id_rubrique=$1 [QSA,L]]
    RewriteRule ^/categorie([0-9]+)\.html$ /categorie.php3 ?id_rubrique=$1 [QSA,L]]
    RewriteRule ^/ou([0-9]+)\.html$ /ou.php3 ?id_mot=$1 [QSA,L]]

    # urls spip]
    RewriteRule ^/rubrique([0-9]+)\.html$ /rubrique.php3 ?id_rubrique=$1 [QSA,L]]
    RewriteRule ^/article([0-9]+)\.html$ /article.php3 ?id_article=$1 [QSA,L]]
    RewriteRule ^/breve([0-9]+)\.html$ /breve.php3 ?id_breve=$1 [QSA,L]]
    RewriteRule ^/secteur([0-9]+)\.html$ /secteur.php3 ?id_rubrique=$1 [QSA,L]]
    et....rien du tout alors que le test avec trouve.html fonctionne....]
    Si quelqu’un peu me donner un indice...

    • As tu essayé d’écrire l’url directement dans la barre de navigation ?

      ex : http://monsite/rubrique1.html

      la balise #URL_RUBRIQUE renvoi l’url a la old school rubrique.php3 ?id_rubrique=2

      c’est peut être de là que vient ton soucis.

    Répondre à ce message

  • 2
    wonderphone

    Bonjour !

    En gros, voici mon problème : dans une appli, je cherche à rediriger toutes les archives archive.jar dans un script appelé force-jar.php.

    Voici ma ligne de code dans le htaccess :

    RedirectMatch (.*)\.jar$ http://www.mon-serveur.com/wap/downloadservice/upload/force-jar.php?jarpath=$1.jar

    mais au lieu d’éffectuer la requête, apache me fais une redirection infinie.

    c’est à dire :

    http://www.mon-serveur.com/wap/downloadservice/upload/force-jar.php?jarpath=/wap/downloadservice/upload/force-jar.php?jarpath=/wap/downloadservice/upload/force-jar.php?jarpath etc...

    Une suggestion ?

    Merci

    • Peut-être parce que ta redirection pointe vers une adresse valide pour ta règle...

      Essaye d’ajouter [L] à la fin de la ligne pour stopper les redirections suivantes, sinon enleve le .jar après $1 et force le à l’intérieur du script.

    • Autre solution :
      RedirectMatch (.*\.jar)$ http://domain/path/to/script.php?jarpath=$1 [L,QSA]

      Permet de ne plus faiure d’autre redirection et ajoute les autres paramètres à la fin.

    Répondre à ce message

  • 1

    ça ne marche pas bien en fait.

    le MAJ_htaccess.php3 rajoute du contenu au précédent .htaccess, alors qu’il devrait d’abbord l’effacer.
    actuellement, on a un .htaccess qui grossit, grossit, grossit. il faut le vider à la main avant de le réécrire. c’est pas très embétant mais un peu dans la mesure ou c’est censser permettre l’actualisation des url sans acces ftp ou trucs du genre.

    si quelqu’un à des pistes, pour l’insant, je ne sais pas faire.

    salut

    Répondre à ce message

  • tito@infokiosques.net

    salut

    j’ai l’impression d’avoir vraiment saisi une nouvelle dimension de la réécriture des url. alors peut-être que ce petit post deviendra une contribution avec plus d’explications.

    les 2 choses :
    -  création du .htaccess avec des boucles spip.
    c’est le squellette MAJ_htaccess.htlm qui écrit le .htaccess

    -  éviter les boucles infinies dans la redirection d’anciens url.
    l’astuce, c’est de nommer autrement mes fichier .php3 de squellettes. là, c’est un petit 2 en plus. distro2.php3 à la place de distro.php3. voir aussi l’usage des RewriteCond et de ? bien placé.

    voilà en tous cas où j’en suis :

    le code que j’ai mis dans un squellette MAJ_htaccess.html un
    peu spécial :

    <?php
    
           $somecontent = '
    
    ##################################
    # FICHIER GENERE PAR MAJ_htaccess.php3
    ##################################
    
    RewriteEngine on
    
    
    ##################################
    #URL POUR LES ARTICLES
    ##################################
    
    RewriteCond %{QUERY_STRING} id_article=([0-9]+)
    RewriteRule article.php3 /%1? [R=permanent,L]
    
    RewriteCond %{QUERY_STRING} id_article=([0-9]+)
    RewriteRule article-spe.php3 /%1? [R=permanent,L]
    
    RewriteRule ^([0-9]+)$    /article2.php3?id_article=$1 [QSA,L]
    
    ##################################
    #URL POUR LES IMPRESSIONS
    ##################################
    
    RewriteCond %{QUERY_STRING} id_article=([0-9]+)
    # ? n'est pas un caractère comme les autre. je me suis tapper la tête contre les murs
    # avant de comprendre que c'est le début d'une query_string et donc qu'il faut
    # utiliser  un RewriteCond. je pensais qu'un contreslash devait faire l'affaire
    # ceci dit, peut-être que ça marche et que c'était d'autres choses qui foiraient
    # comme les boucles infinies. vu que je suis mainteant sur mon petit mac et que
    # je n'ais pas les antislach, je vous laisse me répondre ou tester
    
    RewriteRule imprimersans.php3 /%1.html? [R=permanent,L]
    # le ? renvoie la string toute vide. si on ne met pas le ?, apache la colle sans rien demander
    
    RewriteRule ^([0-9]+).html$  /imprimersans2.php3?id_article=$1 [QSA,L]
    # le 2 rajouté, en vrai, sur le serveur. éviter à apache de tourner en rond.
    # de toutes manières, on les verra plus ces url de fichiers
    
    
    
    ##################################
    #URL POUR LES DISTROS
    ##################################
    
    <BOUCLE_distro(MOTS){id_groupe=2}>
    
    # #TITRE
    RewriteCond %{QUERY_STRING} id_mot=#ID_MOT
    RewriteRule distro.php3 /#DESCRIPTIF? [R=permanent,L]
    RewriteRule #DESCRIPTIF /distro2.php3?id_mot=#ID_MOT  [QSA,L]
    
    </BOUCLE_distro>
    
    
    ##################################
    #URL POUR LES THEMES
    ##################################
    
    <BOUCLE_themes(MOTS){id_groupe=1}>
    
    # #TITRE
    RewriteCond %{QUERY_STRING} ^id_mot=#ID_MOT$
    RewriteRule theme.php3 /#DESCRIPTIF? [R=permanent,L]
    RewriteRule #DESCRIPTIF /theme2.php3?id_mot=#ID_MOT  [QSA,L]
    
    </BOUCLE_themes>
    
    
    ';
    
    # on a mis tout dans $somecontent
    # maintenant, on va mettre $somecontent dans .htaccess
    # ce bout de script ne viens pas de ma tête, mais de je ne sais plus où
    # fr.php.net genre.
    
    
    $filename = '.htaccess';
    
    // Assurons nous que le fichier est accessible en écriture
    if (is_writable($filename)) {
    
       // Dans notre exemple, nous ouvrons le fichier $filename en mode d'ajout
       // Le pointeur de fichier est placé à la fin du fichier
       // c'est là que $somecontent sera placé
       if (!$handle = fopen($filename, 'a')) {
             echo "Impossible d'ouvrir le fichier ($filename)";
             exit;
       }
    
       // Ecrivons quelque chose dans notre fichier.
       if (fwrite($handle, $somecontent) === FALSE) {
           echo "Impossible d'écrire dans le fichier ($filename)";
           exit;
       }
    
       echo "L'écriture de ($somecontent) dans le fichier ($filename) a réussi";
    
       fclose($handle);
    
    } else {
       echo "Le fichier $filename n'est pas accessible en écriture.";
    }
    
    ?>

    avec, bien entendu, un MAJ_htaccess.php3 comme à l’habitude :

    <?php
    
    $fond = "MAJ_htaccess";
    $delais = 24 * 3600;
    
    include ("inc-public.php3");
    
    ?>

    quand je rentre un nouveau mot-clef, un petite visite avec mon navigateur sur MAJ_htaccess.php3 et les url sont à jour.

    (un grand merci à fil et lunar^)

    Répondre à ce message

  • J’avais repéré sur transfert.net une autre façon de proposer les urls, sans le .html :
    http://monsite.net/a384
    pour l’article 384.

    Ci-dessous
    dans .htaccess

    #pas de reecriture pour certaines ressources
    RewriteRule \.(gif|jpg|png|css|php|php3) - [NC,L]
    RewriteRule ^(ecrire|IMG|NAVPICS|oo)/ - [NC,L]
    #urls spip rediriger lancien format
    RewriteRule ^rubrique([0-9]+)\.html$   /r$1 [R,L]
    RewriteRule ^article([0-9]+)\.html$    /a$1 [R,L]
    RewriteRule ^breve([0-9]+)\.html$      /b$1 [R,L]
    RewriteRule ^secteur([0-9]+)\.html$    /s$1 [R,L]
    RewriteRule ^auteur([0-9]+)\.html$    /auteur$1 [R,L]
    RewriteRule ^site([0-9]+)\.html$    /site$1 [R,L]
    #urls spip
    RewriteRule ^r([0-9]+)$   /rubrique.php3?id_rubrique=$1 [QSA,L]
    RewriteRule ^a([0-9]+)$    /article.php3?id_article=$1 [QSA,L]
    RewriteRule ^m([0-9]+)$      /mot.php3?id_mot=$1 [QSA,L]
    RewriteRule ^b([0-9]+)$      /breve.php3?id_breve=$1 [QSA,L]
    RewriteRule ^s([0-9]+)$    /secteur.php3?id_rubrique=$1 [QSA,L]
    RewriteRule ^auteur([0-9]+)$    /auteur.php3?id_auteur=$1 [QSA,L]
    RewriteRule ^site([0-9]+)$    /site.php3?id_syndic=$1 [QSA,L]
    RewriteRule ^f([0-9]+)$    /forum.php3?id_article=$1 [QSA,L]

    et dans inc-urls-court.php3

    <?php
    
    // executer une seule fois
    if (defined("_INC_URLS2")) return;
    define("_INC_URLS2", "1");
    
    function generer_url_article($id_article) {
    	return "a$id_article";
    }
    
    function generer_url_rubrique($id_rubrique) {
    	return "r$id_rubrique";
    }
    
    function generer_url_breve($id_breve) {
    	return "b$id_breve";
    }
    
    function generer_url_mot($id_mot) {
    	return "m$id_mot";
    }
    
    function generer_url_auteur($id_auteur) {
    	return "auteur$id_auteur";
    }
    
    
    function generer_url_document($id_document) {
    	if ($id_document > 0) {
    		$query = "SELECT fichier FROM spip_documents WHERE id_document = $id_document";
    		$result = spip_query($query);
    		if ($row = spip_fetch_array($result)) {
    			$url = $row['fichier'];
    		}
    	}
    	return $url;
    }
    
    function recuperer_parametres_url($fond, $url) {
    	global $contexte;
    	return;
    }
    
    
    //
    // URLs des forums
    //
    
    // a mettre dans ecrire/inc_threads.php3 avec les autres trucs de forum
    function racine_forum($id_forum){
    	$query = "SELECT id_parent, id_rubrique, id_article, id_breve FROM spip_forum WHERE id_forum=".$id_forum;
    	$result = spip_query($query);
    	if($row = spip_fetch_array($result)){
    		if($row['id_parent']) {
    			return racine_forum($row['id_parent']);
    		}
    		else {
    			if($row['id_rubrique']) return array('rubrique',$row['id_rubrique'], $id_forum);
     			if($row['id_article']) return array('article',$row['id_article'], $id_forum);
    			if($row['id_breve']) return array('breve',$row['id_breve'], $id_forum);
    		}
    	}
    } 
    
    function generer_url_forum($id_forum, $show_thread=false) {
    	list($type, $id, $id_thread) = racine_forum($id_forum);
    	if ($id_thread>0 AND $show_thread)
    		$id_forum = $id_thread;
    	switch($type) {
    		case 'article':
    			return generer_url_article($id)."#forum$id_forum";
    			break;
    		case 'breve':
    			return generer_url_breve($id)."#forum$id_forum";
    			break;
    		case 'rubrique':
    			return generer_url_rubrique($id)."#forum$id_forum";
    			break;
    		default:
    			return "forum$id_forum.html";
    	}
    }
    
    ?>

    J’ai testé sur le site, tout semble fonctionner correctement. Maintenant ce qui n’est pas clair pour moi c’est la référence au fichier ecrire/inc_threads.php3, je n’ai pas déplacé ce bout de code. Si quelqu’un peut m’éclaire...

    Répondre à ce message

  • 1

    Très bon article, merci encore.

    > Uzume

    A mon avis c’est au cas où tu mettes :

    RewriteCond %HTTP_BIDULE ^blabla&blibli$

    Dans ce cas ça voudrais dire que HTTP_BIDULE peut valoir à la fois « blabla » et « blibli » ce qui n’a aucun sens. (Enfin c’est une supposition)

    J’aurais tout de même une question à poser.

    J’ai utilisé les régles de réécriture d’url pour un site php/mysql, ça marche nikel et j’ai donc des pages du style page-x.hmtl qui me renvoi vers page.php ?id=x et j’ai donc deux url possible pour mes pages (page-x.hmtl et page.php ?id=x).

    Cela peut me poser problème car si google essai d’indexer mes pages dans les deux versions il risque de me pénaliser (plusieurs pages avec le même contenu), de plus mes pages sous google sont toujours référencées sous la forme page.php ?id=x après plusieurs de ses danses ce qui n’est pas très élégant.

    L’idéal pour résoudre ce problème serait de lui faire une redirection 301. Mais si je met ce code dans mon .htaccess :

    Options +FollowSymlinks
    RewriteEngine on
    RewriteRule ^(.*)/page.php ?id=([0-9]+)$ $1/page-$2.html [NC,QSA,R=301,L]
    RewriteRule ^(.*)/page-([0-9]+)\.html$ $1/page.php ?id=$2 [NC,QSA,L]

    Je risque de tourner en boucle infinie ! :o/

    Quelqu’un a-t-il une suggestion ?

    • Après test visiblement je ne tourne pas en boucle infini et les deux url ont l’air de bien fonctionner, mais est-ce correcte de procéder ainsi ?

      Merci

    Répondre à ce message

  • ... Avec les accolades où il faut bien sûr ;o)

    Répondre à ce message

  • Bonjour,

    Juste une petite interrogation :

    Si : RewriteCond %HTTP_BIDULE blabla|blibli fonctionne.

    pourquoi : RewriteCond %HTTP_BIDULE blabla&blibli ne fonctionne-t-il pas ?

    Ca me titille !

    En tout cas, merci pour cet excellent article, très pratique.

    Répondre à ce message

  • Bonjour,

    Pour des raisons de maintenance, j’ai pris l’habitude d’intaller mes sites web en sous répertoires.
    j’ai donc physiquement : http://www.monsite.fr/spip/
    je souhaiterais que ce sous-répertoire « spip » soit invisible aux internautes et qu’ils naviguent sous spip avec l’adresse suivante http://www.monsite.fr/

    je ne trouve pas la règle à utiliser, et je me perd entre les notions de RewriteBase et RewriteRule

    Pouvez-vous m’aider ???

    Répondre à ce message

  • Bonjour,

    J’ai un probleme de rewriting avec Easy PHP 1.7

    je veux des urls du genre ->
    http://localhost/XXXX/XXXXX/index-navRubrique-18-SelectedRubrique-18.html

    qui rediriqent vers des de url de type --->

    http://localhost/XXXX/XXXXX/index.phtml?navrubrique=18&Selectedrubrique=18

    Dans mon .htaccess j’utilise la ligne suivante :

    RewriteRule ^index-(.+)-([0-9]+)-(.+)-([0-9]+)\.html$ index.phtml ?$1=$2&$3=$4 [L]

    (qui marche tres bien dans un environment unix)

    cette reecriture me renvoi sur la page index.phtml en oubliant les parametre.

    voici un extrait de mon rewrite log —>

    strip per-dir prefix : j :/www/XXX/XXXX/index-navrubrique-19-selectedrubrique-19.html -> index-navrubrique-19-selectedrubrique-19.html
    127.0.0.1 - - [19/Apr/2004:15:36:46 +0200] [localhost/sid#835860][rid#92edf0/initial] (3) [per-dir j :/www/XXX/XXXX/] applying pattern ’^index-(.+)-([0-9]+)-(.+)-([0-9]+)\.html$’ to uri ’index-navrubrique-19-selectedrubrique-19.html’
    127.0.0.1 - - [19/Apr/2004:15:36:46 +0200] [localhost/sid#835860][rid#92edf0/initial] (2) [per-dir j :/www/XXX/XXXX/] rewrite index-navrubrique-19-selectedrubrique-19.html -> index.phtml ?navrubrique=19&selectedrubrique=19
    127.0.0.1 - - [19/Apr/2004:15:36:46 +0200] [localhost/sid#835860][rid#92edf0/initial] (3) split uri=index.phtml ?navrubrique=19&selectedrubrique=19 -> uri=index.phtml, args=navrubrique=19&selectedrubrique=19
    127.0.0.1 - - [19/Apr/2004:15:36:46 +0200] [localhost/sid#835860][rid#92edf0/initial] (3) [per-dir j :/www/XXX/XXXX/] add per-dir prefix : index.phtml -> j :/www/XXX/XXXX/index.phtml
    127.0.0.1 - - [19/Apr/2004:15:36:46 +0200] [localhost/sid#835860][rid#92edf0/initial] (2) [per-dir j :/www/XXX/XXXX/] strip document_root prefix : j :/www/XXX/XXXX/index.phtml -> /XXX/XXXX/index.phtml
    127.0.0.1 - - [19/Apr/2004:15:36:46 +0200] [localhost/sid#835860][rid#92edf0/initial] (1) [per-dir j :/www/XXX/XXXX/] internal redirect with /XXX/XXXX/index.phtml [INTERNAL REDIRECT]

    Merci de votre aide.

    Seb

    Répondre à ce message

  • Article intéressant, mais je ne vois pas le rapport avec SPIP. mod_rewrite, c’est une fonctionnalité d’Apache... SPIP tout seul ne réécrit pas les URL, dire qu’il fournit en standard tout ce qu’il faut n’est pas la vérité.

    Répondre à ce message

  • Philippe034

    Bonjour,

    je viens chercher de l’aide ici, car je ne l’ai toruvé nul part.
    J’arrive à faire marcher le rewriting, mais uniquement dans la racine et sous-répertoire du serveur.
    Mais par contre, jai déclaré un alias, qui marche pour le reste, mais pour le rewriting, il ne veut rien savoir, il me donne l’erreur 400.

    Si quelqu’un sait comment faire, je suis preneur.

    Je pense que cela vient du fichier httpd.conf où il faut rajouter une directory, mais koi ? je ne sais pas.

    Merci de votre aide.
    Philippe

    Répondre à ce message

  • Salut ;o)
    bon le site est bien cool, y a pas à dire,
    mais j’ai une rediredtion qui me pose problème.
    j’ai une page avec un champ login et un bouton :
    http://www.toto.com/site1/login.html
    cette page appel /site1/redirect/redirect.html
    vu que je fais une methode GET
    ça donne :
    http://www.toto.com/site1/redirect/redirect.html?login=user1
    Je voudrais savoir comment faire une redirection
    vers :
    http://www.toto.com/support/site1/users/user1
    j’ai essayé plusieurs chose dont :
    RewriteCond %HTTP_URI ^(.*)redirect.html(.*)$
    RewriteRule ^(.*).com/(.*)/redirect/(.*)login=(.*)$ http://www.toto.com/support/$2/users/$4 [L]
    et ça ne marche pas ;o/

    Ca c du bricolage, si vous avez plus simple, en gros
    ce que je veux faire c :
    J’ai une page /site1/login.html avec un simple champ texte ’login’ et un bouton submit
    je veux recup le nom du site (site1) et ce que me balance
    ma page.

    je sais pas trop si s’st bien claire mais là j’en peux plus ;o/
    Merci par avance !

    Répondre à ce message

  • tres bon article
    merci pour ce travail

    Répondre à ce message

  • 2

    Bonjour,

    Je suis nouveau sur le site, et je profite de l’occasion pour féliciter le Webmaster :)

    Je suis aussi nouveau dans le Rewriting, j’ai une question si c’est possible ?

    comment remplaçer les e(accent) é dans le htaccess ? CAD :
    J’ai l’origine : « annuaire/index.php ?PID=Moteur-spécialisé » mais je n’arrive pas à remplaçer le « é »

    annuaire/index-Moteur-spécialisé.html

    Avec « annuaire/index-Moteur-specialise.html » ça marche

    Merci d’avance et bonne continuation :)

    • Dan Hetzel

      Bonjour,

      Le problème avec les caractères accentués est que l’encodage peut varier selon la plateforme que tu utilises.
      Les normes du W3C préconisent l’encodage de ces caractères exotiques, et il est souvent bien plus sage de s’en tenir éloigné si on veut éviter les soucis d’incompatibilité. Une URL avec un caratère « é » a toutes les chances de voir celui-ci converti en %E9 de toutes manières, au même titre que l’espace qui se retrouve converti en %20 ...

      La meilleure solution serait encore de modifier les sources de ton annuaire pour ne plus avoir des ?PID=Moteur-spécialisé mais bien ?PID=Moteur-spécialise

      Cordialement

    • Merci Beaucoup !
      Bonne continuation :)

    Répondre à ce message

  • et ne pas oublier le modifier spip et le fichier inc-urls.php3

    voir article spip.net

    Répondre à ce message

  • Fan des posts de DAN

    Dan est pour moi LE webmaster francais qui partage son savoir ...
    il en connait tellement et le fait si bien...
    Alors que d’autre sont la et retienne leur info....
    lui explique tout son savoir a merveille ..

    MERCI DAN !!!!!!

    Répondre à ce message

  • 2

    Réecrire dans le htaccess okay, mais ou dois-je mettre mes commandes si je ne souhaite pas utiliser le htaccess (dans le virtual host, surement, mais ou ?)

    Merci d’avance.
    alexandre

    • Dan Hetzel

      Salut,

      Tu as le choix, comme les directives RewriteEngine et RewriteCond peuvent être utilisées dans les 4 contextes suivants : server config, virtual host, directory, .htaccess

      Tu peux les mettre hors de tes déclarations de virtual hosts si elles sont globales... sinon au sein même du vitual host.
      Si tu utilises RewriteBase, il doit être au sein du Directory... donc tu peux aussi tout mettre là.

      Dan

    • ok, merci...

    Répondre à ce message

  • 1

    Bonjour,
    merci pour vos explications mais je voudrais un renseignement plus ciblé.

    En fait je suis webmaster d’un site et par l’intermediaire d’un visiteur, je me suis rendu compte que grace au logiciel « intellitamper », on pouvais scanner mon serveur et recuperer toutes les images dans le repertoire privé.
    J’ai donc tenté de mettre un fichier .htaccess mais qui a eu pour seule consequence d’empecher l’affichage des images par certains utilisateurs qui m’envoyaient des mails me disant « on n’a plus acces aux images ;-( » (point positif, intellitamper ne les voyais plus non plus mais bon....).
    J’aimerais donc savoir comment faire pour que cette pratique ne soit plus possible tout en permettant l’affichage des images par tout le monde visitant mon site ?
    Merci d’avance pour votre aide
    Alex

    • Dan Hetzel

      L’explication est donnée dans l’article... avec un RewriteCond.

      RewriteCond %{HTTP_REFERER} !^$
      RewriteCond %{HTTP_REFERER} !^http://www.domaine.tld/.*$ [NC]
      ReWriteRule .*\.(gif|png|jpe?g)$ - [F]

      Le seul problème est qu’on se base sur le HTTP_REFERER qui est parfois masqué pour les utilisateurs de proxies... donc il faut permettre aussi un HTTP_REFERER null.

      Cela évite le « hot linking » au départ d’autres sites, mais pas l’aspiration sauvage...

      Dan

    Répondre à ce message

  • 1

    Merci à Webrankinfo.com pour l’article !

    • Dan Hetzel

       :-o
      Un message anonyme ? LOL
      Pour ta gouverne, monsieur le corbeau, saches que l’article publié sur Webrankinfo est signé par moi-même et que j’en suis le seul auteur.
      C’est Webrankinfo qui publie cet article avec mon autorisation et non l’inverse !

      Je l’ai retiré du site des publications de l’immobilier pour le mettre sur mon nouveau site où il sera mieux à sa place : Webmaster Hub (cela semble te déranger... je me trompe ? :-) )

    Répondre à ce message

  • 1

    Super !

    Moi qui cherchais un moyen simple de cacher tous les paramétres situés dans l’url et bien voilà, j’ai trouvé et grâce à vous !

    J’utilise Easyphp et je confirme qu’ il faut installer une version Apache plus récente.

    Merci encore.

    • Dan Hetzel

      Salut Steph,

      Heureux que cela te plaise. :-)
      Tu trouveras d’autres articles techniques sur Webmaster Hub, qui est un nouveau site orienté Webmasters qu’on a lancé mi août.

      Il a une partie publication sous Spip qui commence à se remplir.

      (faut bien se faire un peu de pub :-D )

    Répondre à ce message

  • 1

    Article intéressant mais j’ai pas réussi à faire fonctionner avec easyphp. Il ne trouve jamais la page : ex. article102.hml -> une belle erreur 404

    • Dan Hetzel

      Bonjour,

      EasyPHP installe une version 1.3.24 d’Apache, dans laquelle le bug de réécriture Apache sous Windows n’est pas corrigé.(il faut au moins une version 1.3.26)

      Si tu mets en place le rewritelog, tu verras qu’au millieu de la chaîne réécrite tu trouveras « c :\... » qui n’a rien à y faire. :-(
      Tu peux arriver à circonscrire cela en utilisant la directive rewritebase ou en installant une versin apache 1.3.27 ou 1.3.28 par dessus l’ancienne.

      Dan

    Répondre à ce message

  • 1

    tres bon tutorial

    juste un precision sur le test

    sur un serveur mutualise ( la plupart des cas), ne mettre que :

    RewriteEngine on

    RewriteRule ^nexistepas.html$ trouve.html [L]

    et non :

    Options +FollowSymlinks

    RewriteEngine on

    RewriteRule ^nexistepas.html$ trouve.html [L]

    • Dan Hetzel

      Merci pour votre commentaire, cela fait toujours plaisir ;-)

      La ligne Options +FollowSymlinks dépend en fait de l’hébergeur, car certains le configurent par défaut, mais pas tous.

      D’autres hébergeurs ne mettent pas « options » dans la directive AllowOverride, ce qui empêche cette ligne de s’exécuter et donne une erreur.

      Cordialement,

      Dan

    Répondre à ce message

  • Pour ceux que cela intéresse, j’ai publié sur mon site une suite traitant de la récursivité.

    Attention, chaud devant ! ;-)

    Répondre à ce message

  • Magique !!! :-D :-D :-D
    Merci beaucoup pour cet article.

    Répondre à ce message

  • Merci pour cet article vraiment très didactique, le premier sur le sujet, en français, ou je comprends tout ! :-)

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom