WordPress – Transformer les liens absolus en liens relatifs
publié le 11 février 2012 à 19 h 35 min
Lu 497 fois.
WordPress propose un éditeur WYSIWYG plutôt riche et bien fichu. La possibilité d’insérer un contenu riche (lien, image, etc.) est à portée de tout le monde. Nous allons nous concentrer sur les chemins des liens et des images pour voir comment travaille cet éditeur.
Contenu inséré par l’éditeur
WordPress dispose de deux boutons pour insérer médias et liens. Le bouton des médias
situé au dessus du cadre de l’éditeur permet l’insertion d’une image, par exemple.
Si l’on regarde l’attribut src du code généré, voici ce qui ressort (code simplifié) :
<img src="http://yourawesomewebsite.us/wp-content/uploads/2012/02/image.png" alt="" />Pour les liens, le bouton
situé sur la première ligne des outils de l’éditeur permet leur insertion.

En utilisant le nouvel outil de liens internes, il est possible de faire des liens vers d’autres ressources de son propre site web (page et article).
Ces liens ont un attribut href absolu, eux aussi.
<a href="http://yourawesomewebsite.us/a-propos">la page à propos</a>Inconvénient
Si jamais il vous prenait l’envie de déménager votre blog sur un nouveau domaine ou sous-domaine, vous seriez bien embêtés !
En effet, il vous faudrait créer une petite moulinette (requête SQL par exemple) pour intervenir sur les bases de données de WordPress, ou vous retaper les articles à la main.
Solution ?
Cela n’a rien d’absolu, mais mes premiers essais sont plutôt concluants :
Dans functions.php glisser ce code :
if (!function_exists('juiz_absolute_2_relative')) {
function juiz_absolute_2_relative($post_ID, $post) {
// ScreenFeed - suggestion (http://screenfeed.fr)
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post->ID;
$nonce_action = 'update-' . $post->post_type . '_' . $post->ID;
if ( !isset($_POST[ '_wpnonce' ]) || !wp_verify_nonce( $_POST[ '_wpnonce' ], $nonce_action ) )
return $post->ID;
$post_type = get_post_type_object( $post->post_type );
if ( !current_user_can( $post_type->cap->edit_post, $post->ID ) )
return $post->ID;
// CreativeJuiz - replace absolute by relative link
$siteurl = get_bloginfo('url');
// if we are in sub folder installation (/!\) be carefull (/!\)
$after_domain = preg_replace('#http(s)?://(.+)/(.+)#', '$3', $siteurl);
// absolute links to relative links
$new_content = preg_replace('#href="'.$siteurl.'#', 'href="/'.$after_domain, $post->post_content);
//absolute src to relative src
$new_content = preg_replace('#src="'.$siteurl.'#', 'src="/'.$after_domain, $new_content);
// save the post
global $wpdb;
$wpdb->update( $wpdb->posts, array( 'post_content' => $new_content ), array( 'ID' => $post->ID ) );
}
add_action( 'save_post', 'juiz_absolute_2_relative', 10, 2 );
}Une fois ce code enregistré dans functions.php, lors d’un enregistrement d’un post, le script vérifiera s’il croise une valeur absolue des attributs src ou href et les passera en relative (à condition qu’il reconnaisse la base de l’URL de votre site WordPress).
Le code détecte la valeur de bloginfo('url') et prend en compte une installation dans un dossier (avec la nuance précédemment citée) ou en sous-domaine, ainsi qu’une installation plus classique bien évidemment.
Une alternative ?
Il existe un plugin qui vous permet d’effectuer un changement d’URL de base pour votre blog.
Ce plugin une fois activé vous offre deux champs texte à renseigner avec : l’ancienne URL, la nouvelle URL.
Il se charge de remplacer dans la base de données toutes les occurences de l’ancienne par la nouvelle URL.
Ce plugin ne vous permet pas d’avoir des liens relatifs !
WordPress.org
Plugin
Velvet blues update
Bref…
N’hésitez pas à me faire vos retours si jamais vous rencontrez un bogue, difficile d’avoir toutes les exceptions en tête ![]()



Bonjour,
je l’ai testé pour un site et je n’ai jamais eu de problème, le plugin est assez pratique comme tu l’expliques et il y a pas mal de support en cas de problème.
Excellent tuyau, merci !
Hello
Je te propose de supprimer la requête supplémentaire en utilisant un hook plus tôt « wp_insert_post_data », voici ta fonction modifiée :
function juiz_absolute_2_relative( $post_data ) {
global $post;
// ScreenFeed – suggestion (http://screenfeed.fr)
if ( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE )
return $post->ID;
$nonce_action = ‘update-’ . $post->post_type . ‘_’ . $post->ID;
if ( !isset($_POST[ '_wpnonce' ]) || !wp_verify_nonce( $_POST[ '_wpnonce' ], $nonce_action ) )
return $post->ID;
$post_type = get_post_type_object( $post->post_type );
if ( !current_user_can( $post_type->cap->edit_post, $post->ID ) )
return $post->ID;
// CreativeJuiz – replace absolute by relative link
$siteurl = get_bloginfo(‘url’);
// if we are in sub folder installation (/!\) be carefull (/!\)
$after_domain = preg_replace(‘#http(s)?://(.+)/(.+)#’, ‘$3′, $siteurl);
// absolute links to relative links
// var_dump($siteurl);
// var_dump($after_domain);
$new_content = preg_replace(‘#href= »‘.$siteurl.’#', ‘href= »/’.$after_domain, $post->post_content);
//absolute src to relative src
$new_content = preg_replace(‘#src= »‘.$siteurl.’#', ‘src= »/’.$after_domain, $new_content);
// replace the post content
$post_data['post_content'] = $new_content;
return $post_data;
}
add_action( ‘wp_insert_post_data’, ‘juiz_absolute_2_relative’ );
Merci de tester avant de modifier ton article si ça te plait.
Bye !
Hello,
L’idée me plait bien mais elle provoque pas mal d’erreurs.
La doc me parle d’un filter sur ce hook, ainsi que de deux paramètres.
Même en modifiant ta retouche de fonction les clefs du tableau que je lui retourne ne semble pas lui convenir.
Il estime ne pas recevoir de tableau dans le fichier wp-includes/wp-db.php ligne 1204, et donc forcément il a du mal ligne 1206 et suivantes.
J’essaye de voir ça demain si j’ai le temps, là je suis trop crevé
Merci pour ta proposition !
add_filter = add_action
On les différencie pour la maintenance du code, j’avoue mettre souvent add_actionlors de mes tests…
Pour ce qui est de 2 paramètres, oui, le filtre en attends 2, mais par défaut un add_filter c’est « 10″ pour la prio et « 1″ pour les arguments, et comme je ne lui en donne qu’un, ça ne pose pas de problème.
Pour l’erreur euh, je ne l’ai pas chez moi :s
Tu peux ressayer avec ma function et me donner ici l’erreur ? Merci à demain
Je t’ai envoyé un mail, plus simple pour l’affichage des erreurs.
Merci pour ton implication.
Bizarre, j’ai débuggé « $post_data » et c’est bien un array, ensuite je modifie le contenu d’un item de cet array, puis je return cet array.
Et dans ton erreur il dait que c’est une string o_O
#louche
Je confirme que j’ai toujours la même erreur.
Le problème ne se pose pas sur un article existant, mais sur un nouvel article.
C’est toujours problématique ces strings dans l’array…