Voici une solution qui peut intéresser ceux qui ont installé drupal 5.x sur free.fr mais qui sont frustrés de ne pas pouvoir activer l’option «URLs simplifiées (Clean URL)».
Le principe
On fait appel à la redirection 404 (Page non trouvée) vers un script PHP comme décrit sur d’autres billets de ce site. Ce script émule le positionnement des variables super-globales correspondant à une requête HTTP standard. Ceci suffit pour les requêtes HTTP GET.
Pour les requêtes HTTP POST, cela ne marche pas car la redirection 404 oublie les variables POSTées et ce de manière irréversible apparemment. Ici, la solution consiste à débrayer l’option «Clean URL» lors de la soumission de requêtes HTTP POST. Dans la mesure où les modules installés (standards, additionnels ou persos) utilisent tous form.inc, il suffit d’intervenir à deux endroits : theme_form() et theme_hidden().
Détails
1) .htaccess
Tout d’abord ajouter la ligne suivante à votre fichier .htaccess :
ErrorDocument 404 /mod_rewrite.php
2) mod_rewrite.php
Créer un script mod_rewrite.php à la racine de votre site à partir du modèle ci-dessous. Les lignes marquées (*) doivent être modifiées si drupal est installé ailleurs qu’à la racine :
<?php
$url = $_SERVER['REQUEST_URI']; // On récupère l'URL demandée
if(preg_match("^(.*)$/", $url, $match)) // (*) "/^\/dir\/to\/drupal\/(.*)$/"
{
header("HTTP/1.1 200 OK");
$url = $match[1];
$start_query = strpos($url, '?');
if ($start_query !== FALSE) {
$path = substr($url, 0, $start_query);
$query = "q=" . $path . "&" . substr($url, $start_query + 1);
}
else {
$path = $url;
$query = "q=" . $path;
}
$params = explode("&", $query);
foreach($params as $p) {
$fields = explode("=", $p);
$key = $fields[0];
$value = $fields[1];
$_GET[$key] = $value;
$_REQUEST[$key] = $_GET[$key];
}
$_SERVER["REDIRECT_STATUS"] = 200;
$_SERVER["REDIRECT_URL"] = $url;
$_SERVER["QUERY_STRING"] = $query;
$_SERVER["SCRIPT_NAME"] = "/index.php"; // (*) "/dir/to/drupal/index.php"
$_SERVER["SCRIPT_FILENAME"] = $_SERVER['DOCUMENT_ROOT'] . $_SERVER["SCRIPT_NAME"];
$_SERVER["PHP_SELF"] = $_SERVER["SCRIPT_NAME"];
// chdir("dir/to/drupal"); // (*)
include("index.php");
exit();
}
/* Erreur 404: compléter par le code PHP ou HTML à utiliser pour les "vraies" pages non trouvées (autres que celles gérées par drupal)*/
...
?>3) includes/form.inc
Modifier les fonctions theme_form() et theme_hidden() contenues dans includes/form.inc comme ci-dessous. On peut évidemment créer ou modifier les fonctions mon_thème_form() et mon_thème_hidden() dans sites/themes/mon_thème/template.php pour éviter de toucher au noyau de drupal. Cependant, puisque celui-ci est déjà largement patché pour fonctionner sur free.fr autant continuer.
<?php
// [...]
/<strong>
* Format a hidden form field.
*
* @param $element
* An associative array containing the properties of the element.
* Properties used: value, edit
* @return
* A themed HTML string representing the hidden form field.
*/
function theme_hidden($element) {
// Patch free.fr
if ($element['#name'] == 'attach-url') {
$element['#value'] = patch_clean_url_exception($element['#value']);
}
// End patch free.fr
return '<input type="hidden" name="'. $element['#name'] . '" id="'. $element['#id'] . '" value="'. check_plain($element['#value']) ."\" " . drupal_attributes($element['#attributes']) ." />\n";
}
// [...]
/</strong>
* Format a form.
*
* @param $element
* An associative array containing the properties of the element.
* Properties used: action, method, attributes, children
* @return
* A themed HTML string representing the form.
*/
function theme_form($element) {
// Patch free.fr
$element['#action'] = patch_clean_url_exception($element['#action']);
// End patch free.fr
// Anonymous div to satisfy XHTML compliance.
$action = $element['#action'] ? 'action="' . check_url($element['#action']) . '" ' : '';
return '<form '. $action . ' method="'. $element['#method'] .'" '. 'id="'. $element['#id'] .'"'. drupal_attributes($element['#attributes']) .">\n<div>". $element['#children'] ."\n</div></form>\n";
}
/**
* Patch free.fr
*
* permet d'utiliser la méthode POST sur les pages dont l'URL a été réécrite (option clean_url=1)
* lorsque cette option est positionnée, les formulaires qui ont pour destination des url réécrites
* sont traités par le script d'exception 404 mod_rewrite.php qui interdit la méthode POST. Le patch
* consiste à forcer les formulaires utilisant POST à débrayer l'option clean_url durant la soumission
* du formulaire.
*
* Deux cas se présentent:
* - attribut action de <form> => modifié dans theme_form()
* - champ caché contenant une URL => modifié dans theme_hidden()
*/
function patch_clean_url_exception($uri){
global $base_url;
$script = 'index.php';
$abs_path = $base_url . "/";
$base_path = base_path();
if ($uri && (strlen($uri) > 0)) {
$path = $uri;
// trim base if any
if (strcmp($abs_path, substr($path, 0, strlen($abs_path))) == 0) {
$path = substr($path, strlen($abs_path));
}
elseif (strcmp($base_path, substr($path, 0, strlen($base_path))) == 0){
$path = substr($path, strlen($base_path));
}
// trim script if any
if (strcmp($script, substr($path, 0, strlen($script))) == 0) {
$path = substr($path, strlen($script));
}
if (
substr($path, 0, 1) != '?') {
// option clean_url débrayée sur cette URL
$uri = $base_path . "?q=" . preg_replace('/\?/', '&', $path, 1);
}
}
else {
// base url forcée car on ne sait pas de quelle page on vient
$uri = $base_path . "?q=" . $_GET['q'];
}
return $uri;
}
?>Configuration
Une fois ces modifications apportées, vous pouvez aller dans le menu d’administration et configurer l’option «Clean URL».
Conclusion
Ce patch implémente correctement l’option «Clean URL» pour un hébergement drupal sur free.fr, dans la mesure où on n’introduit pas de modules ou de modifications trop spécifiques.
En espérant que ça vous soit utile…
- Version imprimable
- Vous devez vous identifier ou créer un compte pour écrire des commentaires

Merci pour cette solution. J’ai ajouté votre contribution à la section «problèmes à l’installation» de notre documentation.
Damien Tournoud
808
Très intéressant et cela fonctionne bien : je remarque juste que tu as une erreur de syntaxe :
Ce n’est pas : if(preg_match(«^(.)$/», $url, $match))
mais bien if(preg_match(«/^(.)$/», $url, $match))
Le slash est important avant le ^.
poiuytaz
14
je vous remercie pour le tuto, mais pour Drupal 6.0 la case pour activé le clean url, reste grisée, donc pour activer le clean url il faut taper manuellement ESPACE.free.fr/admin/settings/clean-urls
Merci à vous encore une fois…
zemag
2
Bonjour Zemag,
Je n’ai pas compris comment vous avez fait.
Chez moi cela ne fonctionne pas.
Merci de l’aide
leroymth
38
Testé et approuvé ! Sa marche nickel. A noter que le fichier mod_rewrite.php doit se trouver à la racine de votre espace.free.fr et non pas à la racine de votre site drupal.
Grand_Lutin
17
Bonjour,
Je viens de re-essayer la solution sur une version 6.19 cependant le check box reste grisée.
Quelqu’un a réussi à contourner ce problème ?
Cdt,
leroymth
38
Les explications sont pour Drupal 5. Rien à voir avec Drupal 6
Indépendante, mandats Drupal et PHP
sahuni
911
Voir post de Zemag plus haut qui apparemment à réussi en version 6.
leroymth
38
Oui tu as raison.
Pour moi, c’est du chinois, je ne peux pas t’aider.
Indépendante, mandats Drupal et PHP
sahuni
911
Du coup la question est toujours viable….est ce possible de faire tourner ce patch en version 6 sur Free à aujourd’hui.
Actuellement cela ne semble pas marché pour moi.
leroymth
38
Bonjour,
Up.
Merci
leroymth
38
Bonjour,
as-tu trouvé une solution pour drupal 6.x ?
dilune
337