ajax theme wordpress

L’ajax est une technologie qui a longtemps été réservée aux applications web, ou utilisé dans des sections de site n’ayant pas d’intérêt à être indexé.

C’est pourtant une solution intéressante pour dynamiser son site internet, en chargeant des sections de page de façon animé.

Depuis peu, son utilisation est devenue perméable à Google qui peut, par un moyen dérivé, indexer le contenu des pages en ajax. Alors pourquoi se priver, c’est peut être l’occasion de donner une touche de jeunz’ à votre vieux thème WordPress ?

Voici comment facilement et rapidement ajaxiser son thème WP…

Un thème full ajax

L’idéal pour construire une navigation en Ajax, c’est que chaque changement significatif de contenu soit accompagné d’un changement dans l’URL pour indiquer à l’internaute où il se trouve sur le site.

En javascript, la seule partie de l’adresse que l’on va pouvoir modifier sans provoquer de rechargement de page, c’est l’ancre, le hash, représenté par le symbole #.

Mais plutôt que de modifier le hash à chaque requête on va faire l’inverse :

  • chaque lien va simplement modifier l’ancre
  • un script nommé « hashchange » va nous permettre de détecter cet évènement et d’y associer une action
  • l’action va être de faire la requête ajax et de charger le contenu souhaité

Procéder ainsi va nous permettre de conserver les fonctions d’historique des navigateurs (un clic sur le bouton « retour » rechargera le contenu précédent).

Au final nous allons obtenir un site full ajax avec ce système :

Démonstration d'un système de navigation ajax sous WordPress
Démo : Un thème WordPress full ajax

Le site de démonstration : Ajax & WordPress

Commençons à coder

Modifier l’affichage des URLs internes

Pour commencer, on va s’arranger pour que WordPress n’affiche plus aux internautes la véritable URL des pages mais une URL « ajax friendly », utilisant le « #!« . Pour ça on va ajouter quelques lignes dans le fichier functions.php de votre thème.

<?php
add_filter('post_link', 'ajaxed_links');
add_filter('category_link', 'ajaxed_links');
add_filter('page_link', 'ajaxed_links');

function ajaxed_links($fullLink){
$ndd = get_bloginfo('url');
$ancre = str_replace($ndd,'',$fullLink); //on décompose
return $ndd.'/#!'.$ancre; //on recompose
}
?>

Nous venons de créer une fonction qui récupère un lien, et y ajoute #! juste après le nom de domaine. Puis on l’applique avec un add_filter sur toutes les fonctions qui génèrent des liens internes, en front office.

Ici je l’ai seulement fait pour les liens vers les articles, les pages et les catégories ; selon votre thème il faudra très certainement ajouter des filtres. Il faudra aussi vérifier les liens crées/modifiés par vos plugins.

Supprimer les ancres des liens

Vu que toutes les URLs internes du site contiennent maintenant un #, il faut veiller à ce que tous les liens qui ciblaient déjà une ancre soient modifiés (par exemple le read-more).

On ajoute dans le functions.php un code déjà proposé sur seomix :

<?php
function remove_more_jump_link($link) {
$offset = strpos($link, '#more-');
if ($offset) {
$end = strpos($link, '"',$offset);
}
if ($end) {
$link = substr_replace($link, '', $offset, $end-$offset);
}
return $link;
}
add_filter('the_content_more_link', 'remove_more_jump_link');
?>

Omettre cette étape ne devrait normalement pas gêner la navigation (seule la première ancre est prise en compte par le navigateur), par contre cela bloquerait l’indexation

Jouons avec les scripts !

Les javascripts dont nous avons besoin

Pour faire un thème ajax, on va utiliser quelques scripts dans le but de nous faciliter le codage :

  • jQuery, qui va nous permettre de coder la requête ajax et les animations sans s’arracher les cheveux
  • hashchange, qui va nous permettre de détecter le changement d’ancre dans la barre de navigation pour lancer une fonction. Avec lui, on ne perd pas l’usage des boutons précédent/suivant du navigateur
  • Si votre site est en html5, il faudra aussi utiliser innerShiv. Ce script permet à des navigateurs ne supportant pas le html5 de pouvoir parser le contenu des pages chargées en ajax.

Le script de navigation

Donc après avoir appelé tous ces scripts, ajoutons le notre, puis créons une fonction qui sera lancée dès que le Hash de l’url sera modifié :

$(document).ready(function(){
$(window).hashchange(function(){

});
});

Dans celle-ci, on récupère la partie du hash qui nous intéresse (ce qu’il y a après #!/), puis on reconstitue le vrai lien de l’article.

//on récupère le hash ,sans ses 3 premiers caractères (#!/)
var arg = window.location.hash.substring(3);
//on reconstitue le vrai lien
var link = "http://www.nomdedomaine.com/"+arg;

Ensuite, on fait la requête ajax, avec la fonction $.ajax de jQuery.

$.ajax({
url:link,
processData:true, //résultat sous forme d'objet
dataType:'html', //type html
success:function(data){
//fonction callback
}
});

La requête récupère l’intégralité de la page (question de facilité, mais qui n’utilise pas tout le potentielle de l’ajax). C’est à nous, dans la fonction callback, de trouver les éléments qui nous intéressent et de les remplacer dans la page actuelle.

Comme ma page est en html5, j’utilise innerShiv pour que les navigateurs comme Internet Explorer puissent analyser les données renvoyées.

Ensuite, je trouve le titre de ma page et je le remplace. Je fais pareil avec tout le contenu de la div #contenu (avec une petite transition).

data = innerShiv(data,false); //on passe le résultat dans innershiv
var title = $(data).filter('title').text(); //on trouve le titre de la page
document.title = title; //on change le titre
var contenu = $(data).find("#contenu"); //on trouve la balise qui nous intéresse
$('#contenu').fadeOut('200',function(){ //on masque le contenu à changer...
$(this).html(contenu.html()).fadeIn('200'); //...puis on charge le nouveau et on affiche
});

Attention : pour trouver des éléments html dans data, j’utilise les fonctions .filter() et .find() de jQuery. Sachez que find ne permet pas de trouver un élément à la racine du body, il faut forcément une div contenante. La fonction .filter() ne pose pas ce souci. Merci à Géo qui m’a débloqué sur ce point !
De même il y a un petit souci de compatibilité entre la fonction .html() et Internet Explorer 9, que je n’ai pas réussi à résoudre…

 

Comportement au chargement de la page

Si on test le site maintenant, la navigation devrait correctement fonctionner. Cependant il nous reste un dernier comportement à prévoir: celui de l’internaute qui entre directement une url type « http://domaine.com/#!/page » dans son navigateur. S’il le fait, la page d’accueil va se charger, c’est seulement lorsqu’il cliquera sur un lien que le hash changera et qu’un contenu différent sera appelé.

Pour remédier à ça on peut ajouter, sous la fonction que l’on vient d’écrire, un code qui va détecter au chargement de la page si l’URL contient un hash non null. Si c’est le cas, il va simplement lancer l’évènement hashchange et exécuter la fonction précédente (exemple).

if(window.location.hash.substring(3)!=''){
$(window).trigger( 'hashchange' );
}

Derniers réglages

Voilà, on a maintenant un système de navigation Full Ajax facile à implémenter sur un thème WordPress.

A vous de bidouiller le script pour obtenir les transitions qui vous conviennent. Là c’est un  effet de fondu mais on peut tout aussi bien faire un slide façon Github, ou autre… Pensez aussi à mettre à jour des éléments comme votre menu, lors des changements de page.

Votre thème sera  indexable par google si vous utilisez l’astuce du healdess browser ; enfin presque, il vous reste une modification à faire…

Toutes les adresses du sites sont maintenant uniques, sauf une : votre page d’accueil. On peut y accéder à partir de deux URLs différentes, à savoir « http://domaine.com » et « http://domaine.com/#!/« . Pour corriger ça, Google recommande d’ajouter une balise meta dans le head cette page :

<meta name="fragment" content="!"/>

Elle sert simplement à indiquer au googlebot qu’il faut crawler uniquement la page avec l’URL en  #!/

Voilà, maintenant votre thème WordPress Full ajax est fini. Il reste bien sûr beaucoup de possibilité d’optimisation, notamment sur le fait que les requêtes appelent l’intégralité des pages, et pas uniquement les portions souhaités. Le but de cet article est surtout de montrer comment facilement adapter un thème pour l’ajax, sans forcément en créer un de toute pièces.

Pour conclure, encore merci à Géo qui m’a beaucoup aidé à déboguer mes scripts, et avec qui je rédigerai bientôt un article pour expliquer comment référencer son site Ajax sans utiliser de headless browser.

Démo & sources

  • La démonstration, avec un thème assez simple
  • Les fichiers sources de ce thème :

Télécharger “Le thème de démo” themeajax.zip – Téléchargé 4955 fois – 4 MB