WordPress – Transformer les liens absolus en liens relatifs

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.

Il y a une légende urbaine chez certains experts en référencement qui dit que les liens internes relatifs sont à privilégier aux liens absolus. Mais le seul expert SEO que j’ai consulté m’a dit« tant qu’on arrive sur la bonne page ». Légende, ok, faites-en ce que vous voulez !

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).

Attention : cette technique fonctionne dans le cas d’un blog en sous-dossier (comme ici : http://creativejuiz.fr/blog/), mais n’a aucun intérêt puisqu’en cas de déménagement du blog, les URLs conservées auront cette forme : /blog/wp-content[…]

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.

Ce script ne modifie pas les URL déjà écrites dans les articles existants.

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 ;)

8 commentaires et 2 trackbacks sur “WordPress – Transformer les liens absolus en liens relatifs”

  1. 12 février 2012

    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.

  2. 13 février 2012

    Excellent tuyau, merci !

  3. BoiteAWeb dit :
    20 février 2012

    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 !

  4. Geoffrey dit :
    21 février 2012

    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 !

  5. BoiteAWeb dit :
    21 février 2012

    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

  6. Geoffrey dit :
    21 février 2012

    Je t’ai envoyé un mail, plus simple pour l’affichage des erreurs.
    Merci pour ton implication.

  7. BoiteAWeb dit :
    21 février 2012

    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

  8. Geoffrey dit :
    21 février 2012

    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…

Laisser un commentaire

Les sites qui en parlent

  1. Wordpress | Pearltrees le 22 février 2012
 
Le studio web