Mettre en place une navigation Ajax dans WordPress

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é 5801 fois – 4 MB

Willy Bahuaud

Développeur freelance, spécialiste de WordPress

73 Commentaires

BreiZh SEO Le 26 juillet 2011 à 10h28
Il semblerait que google est réussi l'indexation de la page sur le mots clé défini dans l'exemple :D

Résultat de l'indexation

Bonne nouvelle pour les personnes qui veulent utiliser l'ajax.
Strategio Le 26 juillet 2011 à 10h45
Excellent !
Je rajouterai juste qu'il serait judicieux de prévoir un gif animé lors du chargement des pages ou n'importe quelle action lors du clic car sinon on a l'impression que notre action n'a pas été prise en compte.
Par exemple, le fadeout sur le contenu peut être fait avant la requête ajax.
    Willy Bahuaud Le 26 juillet 2011 à 12h06
    @Breizh oui l'indexation marche bien, tant qu'on veille à avoir des url qui ne comportent qu'une seule ancre. Actuellement j'attends de voir comment réagit google analytics (vu qu'on ne change pas de page).

    @Strategio tout à fait, indiquer que l'action a été prise en compte est une bonne idée (car la requête est asynchrone). Par contre il faut prévoir que celle-ci peut échouer, et alors prévoir aussi un comportement pour re-afficher un état normal de la page. Je ne te conseilles donc pas de faire un fadeOut avant la requête. Mais un gif "loading" pourquoi pas (penser à l'enlever si la requête renvoie un "error", et mettre un message explicatif)...
Jérémie Le 26 juillet 2011 à 14h31
Beaucoup de modifications directement dans le code.

Ça ne risque pas de sauter à la première mise à jour d'un thème ?
Où il faut arrêter les mises à jour du thème après la modification. Heureusement ce n'est pas l'élément le plus mis à jour.

Après, je reste sceptique sur l'utilisation de l'ajax pour le chargement des pages.

De plus, on se prive de tous les utilisateurs sans Javascript et l'accessibilité (aveugles notamment) n'est-elle pas réduite ?

Je m'en pose des questions...
    Willy Bahuaud Le 26 juillet 2011 à 15h27
    @Jérémie les seuls modifications apportées ici se font dans la page functions.php du thème, peu de risque que cela change tous les jours comme tu dis ^^ Après rien n'empêche d'externaliser ces 25 lignes de codes dans un plugin...
    Pour la technologie Ajax c'est normal d'être sceptique, son utilisation pour les sites web est relativement récente. Cependant je ne pense pas qu'il faille prendre pour excuse de perdre les gens n'utilisant pas le javascript. D'abord parce qu'il sont très peu, ensuite parce que pour satisfaire ces internautes le mieux est de concevoir une version parallèle du site qui leur est dédié (comme l'on conçoit aujourd'hui des versions pour les périphériques nomades).

    @Vincent Pour le suivi analytics je suis en train de tester, à suivre donc... pour l'instant il me semble qu'il n'arrive pas à comprendre nativement qu'il y est plusieurs pages. Mais je pense qu'on peut parer ça à l'aide de quelques filtres :-)
Vincent Le 26 juillet 2011 à 14h45
Superbe article qui montre encore une fois qu'on peut tout faire avec un Wordpress.

Ca pose pas trop de problème pour le suivi analytics par contre ?
Laurent H Le 26 juillet 2011 à 16h33
Pour analytics, tu peux très bien faire le suivi en rajoutant ce genre code javascript au moment de la récupération de la page :

if (typeof window._gaq != "undefined") {
window._gaq.push(['_trackPageview', '/']);
}
Masamune Le 27 juillet 2011 à 10h57
Superbe article, je verrais pour mettre en place le tuto dès que j'aurais un moment à moi.

Excellent travail en tout cas ;)
Fabrice Le 28 juillet 2011 à 22h42
Super comme technique,
Il subsiste un soucis avec jquery, en effet après un changement de page, toutes les actions jquery sont inopérantes.
Dans mon utilisation courante je fais un appel du script JS pour l'append avec la page que j’appelle, sauf que là, si je place une balise script dans le contenue il ne l’interprète pas...
Vous auriez une idée ?

Merci :D
    Willy Bahuaud Le 28 juillet 2011 à 23h31
    @Laurent Cette méthode corrige "un peu" le problème, mais elle ne permet pas d'avoir beaucoup de données relative aux différentes page chargées. On sait quelles pages ont étés visités, mais pas combien de temps par exemple (enfin, y'a moyen mais c'est du boulot ^^)

    @Masamune Merci !

    @Fabrice Je ne suis pas sûr de saisir ton problème. Il est normal que les éléments chargés en ajax ne soit pas concerné par les actions jQuery car ceux-ci n'existait pas au chargement de la page. Pour cela, il faut leur associer des événements avec la fonction .live()"
    Sinon, si tu veux charger un js en ajax c'est possible en utilisant .getScript(). Le code chargé sera alors interprêté :-)
Fabrice Le 29 juillet 2011 à 0h00
@Willy .live() résout effectivement une partie de mon problème merci!

.getScript j'avais tenté, il charge bien mon script avec ma fonction $('#test').click... mais elle n'a aucun effet dommage.
Quentin Le 29 juillet 2011 à 21h42
Je suis méfiant avec ce type de thèmes.
C'est pas vraiment conseillé pour le SEO
    Willy Bahuaud Le 01 août 2011 à 10h16
    @Quentin Qu'est ce qui fait que tu sois méfiant, niveau SEO, avec ce type de thème en ajax ?
Julien Le 01 août 2011 à 19h53
Bonjour,
j'ai un comportement bizarre en "ajaxant" le thème twentyeleven(WordPress 3.2.1), lorsque je clique sur un lien, il m'affiche d'abord une page avec "Rien a été trouvé" puis 1 seconde après la bonne page s'affiche....
Merci par avance
Julien Le 02 août 2011 à 0h18
oups ! en fait je n'avais pas saisi qu'il faillait laisser la page d'accueil "vierge". Ca fonctionne donc bien mais comment afficher la page demandée plus rapidement, car j'ai à peu près 5 sec ... :(

EDIT : finalement en ajoutant un "/" avant le # dans functions.php, tout marche nickel :
Ligne :
return $ndd.'/#!'.$ancre; //on recompose

désolé d’encombrer les commentaires !!!
    Willy Bahuaud Le 02 août 2011 à 12h36
    @Julien ah oui, désolé, l'article à été corrigé ^^
jeuxfr Le 02 août 2011 à 14h04
Pour ne pas pourrir son référencement il ne serait pas possible de transformer les liens à la volée pour la navigation ajax tout en conservant les liens seo friendly ?
    Willy Bahuaud Le 02 août 2011 à 15h54
    @jeuxfr bien sûr que si, on peut toujours utiliser des liens "normaux", le soucis c'est que tes visiteurs vont partager sur la toiles des liens ajax...
    Par contre, normalement, si ton site est bien conçu, ce type de liens est SEO friendly (voir l'article). Le système à l'origine mis en place par Google à également été adopté par bing et yahoo.
    Donc pas de raisons d'avoir peur pour son référencement :-)
Jonathan Path Le 13 août 2011 à 17h56
Super tuto dont j'attendais la sortie :)
J'ai travaille également sur un thème Wordpress avec une navigation en AJAX, j'ai fait un peu différement : j'ai utilisé le fichier wp-admin/admin-ajax.php pour lancer une fonction dans function.php... (http://geekpreneur.blogspot.com/2009/06/how-to-use-wpajax-in-wordpress.html)
Pour le référencement, je mise sur un google sitemap. En gros, Google ne vera que mes pages statiques que mes utilisateurs ne verront pas, est-ce une bonne manière de le faire ?
Daniel Roch Le 24 août 2011 à 11h31
C'est effectivement plus simple à mettre en place, et le sitemap permettra d'indexer toutes les pages. Cependant, le site n'aura aucun maillage interne car les liens sont des ancres et non pas des liens en dur, ce qui va fortement nuire au SEO
johnne22 Le 26 octobre 2011 à 16h42
Bonjour,

L'article date d'aout 2011, mais j'espère que tu auras l'envie de répondre à mes interrogations.

Voilà, j'ai lu et parcourru ton blog de manière frénétique en admirant ce que tu as pu faire (thème du blog par exemple).
Je suis impressionnée par la différence entre tes pages d'accueil (plusieurs blocs) et les pages de tes articles.

Je souhaitais savoir si cette différence est du justement à "Ajax" et plugins que tu abordes dans cet article ?
En effet, n'ayant pas un visuel concret et n'étant pas "fortiche" en informatique, je n'arrive pas à visualiser concrettement ce que cela donne.

PS : Si ce n'est pas "Ajax" qui te permet de faire par exemple des blocs dynamiques, pourriez tu s tu veux bien me dire qu'est ce qui le permet ?

Merci d'avance.
J'attends avec impatience ton retour ;-)
A+
Daniel Roch Le 26 octobre 2011 à 23h11
Les deux éléments n'ont rien à voir. L'Ajax permet de changer de manière dynamique des contenus.

En ce qui concerne SeoMix, c'est un thème sur mesure qui me permet de faire cela, en faisant appel aux taxonomies.
Sev Le 27 octobre 2011 à 5h19
Donc les taxonomies te permettent d'obtenir les boxes que l'on peut voir sur la page d'accueil ?
Daniel Roch Le 27 octobre 2011 à 7h47
Oui et non : une taxonomie permet de classer des contenues. Les catégories et les mots clés sont les taxonomies par défaut. C'est mon thème ensuite qui décide ou non de faire appel aux taxonomies pour cet affichage en page de catégorie.
Sev Le 27 octobre 2011 à 8h36
Merci pour toutes ces précisions ;-)
Antoine R Le 17 novembre 2011 à 16h36
Bonjour,

Je déterre légèrement ce topic pour savoir si vous avez trouvé une solution concernant Internet Explorer. Les pages ne se chargent pas sous ce navigateur quelle que soit la version :(
Charles-L Le 19 novembre 2011 à 15h43
Bonjour,

Tout d'abord un grand merci pour cet excellent tuto!!

Je n'arrive pas à utiliser la class current_page_item_a pour mettre en avant le lien vers la page active.
Tous les liens de mon menu sont de la couleur active.

Quelqu'un a-t-il une piste pour permettre le marquage des liens actifs ?

Par avance merci!
Charles-Louis Le 20 novembre 2011 à 19h31
Bonsoir,

@Antoine R : je croyais avoir le même problème avec IE.
Je l'ai résolu en déclarant les elements (html5) du DOM non reconnus par IE avant leur utilisation ex:



Je t'invite à lire les explications de John Resig ici : http://ejohn.org/blog/html5-shiv/

En espérant que cela résolve ton problème.

PS: je suis toujours preneur d'une astuce pour mettre en avant le lien ACTIF...any idea ??

EDIT: @Antoine : Re

Il me semble que tu peux soit intégrer :

"

document.createElement("header");
document.createElement("footer");
document.createElement("nav");
document.createElement("article");
document.createElement("section");
document.createElement("figure");
document.createElement("x,y,z...");

"

Soit plutôt appeler le script html5.js (dans le header):

""

Tu trouveras le script ici (merci Remy Sharp):
http://html5shim.googlecode.com/svn/trunk/html5.js

Charles-Louis
Willy Bahuaud Le 20 novembre 2011 à 23h33
Bonjour @antoine , je pense que tont soucis viens du JS,a au moment ou jquery doit charger les pages... Essayer de faire un console.log de ce que renvoie data (pour être sûr que data renvoie bien quelquechose sur IE)
Willy Bahuaud Le 20 novembre 2011 à 23h33
Bonjour @antoine , je pense que ton soucis viens du JS, au moment où jQuery doit charger le contenu... Essaye de faire un console.log de ce que renvoie data (pour être sûr que data renvoi bien quelque chose sur IE)
Ed Le 25 janvier 2012 à 1h45
Bonjour Willy. Merci pour ce tutoriel, très très intéressant !

J'ai une petite question néanmoins, cette méthode à l'air de marcher sur IE8 (en testant ton site de démo), mais avec le site que je mets en place ce n'est pas le cas, les pages ne se chargent pas (ça marche sur ie7, chrome, firefox... mais pas ie8 !).

Aurais-tu une idée d'où pourrait venir ce problème ?

Merci d'avance !
Ed
unknownclubberz Le 26 février 2012 à 10h35
Merci pour cet excellent article que je cherchais en vain depuis un bon moment !

Il subsite néanmoins un petit détail qui me chagrine : Lorsque l'on appelle une page autre que la home, on passe tout de même par la home. Y'a t'il un moyen d'éviter ce "rebond" ?
Willy Bahuaud Le 26 février 2012 à 12h35
@Ed il faudrait que je vois le code de ta page pour te dire d’où vient le problème.
Personnellement, la dernière fois que cela m’est arrivé, c’était un console.log() qui se promenait (et ie8 / ie9 n’aime pas les console.log() ^^)

@unknownclubberz tout d’abord féléicitation pour ton site, il est très réussi !!
Cependant je ne parvient pas à voir le bug dont tu parles, pourrais-tu me donner un cheminement précis où tu rencontre ce bug ?
unknownclubberz Le 26 février 2012 à 13h03
Merci pour le site :)

Appelle directement la page article et tu passeras par la home, puis fadeOut et fadeIn de la page article, exemple sur la démo :

http://ajax.wuiwui.net/#!/ajax/theme-ajax-wordpress/

On voitd'abord s'afficher http://ajax.wuiwui.net/ puis fadeOut et fadeIn puis http://ajax.wuiwui.net/#!/ajax/theme-ajax-wordpress/

Suis-je plus clair ?
mic Le 07 avril 2012 à 22h59
Bravo pour ce tuto simple et très clair !

Dans ton exemple tu charges effectivement toute la page (le template single.php ou page.php de Wordpress) et ensuite tu fais un filtre.
Tu parlais en fin d'article de ne charger qu'une portion souhaitée.
Tu aurais des exemples ??

Je suis aussi impatient de lire ton tuto sur le référencement de se genre de site sans 'headless browser' car cela me parais un peu lourd à mettre en place.
Je préfère pour l'instant transformer les liens 'naturels' en liens Ajax avec Jquery. Cela laisse le site consultable si le JavaScript est désactivé...

Merci encore de partager tes connaissances.
m4c3 Le 08 avril 2012 à 16h29
Bonjour,

j'ai installé le thème full ajax sur mon wordpress mais ça ne fonctionne pas lorsque je clique sur more... J'ai alors une page sans contenu...

Est-ce que tu pourrais m'expliquer comment fonctionne l'affichage de ta page? D'ailleurs ça fonctionne avec les articles me semble-t-il...

Merci d'avance
mic Le 09 avril 2012 à 16h49
Bon, j'ai un peu creusé la question pour ne charger q'une partie de du contenu.
Je fais passer une variable dans la requête Ajax qui va me permettre d'avoir un template single.php ou post.php personnalisé et donc allégé.
Ex: j'ai rajouté la variable Ajax en plus de l'url.
[pastacode lang="bash" provider="manual"]$.ajax({
url:link,
data: "ajax=true",
processData:true, //résultat sous forme d'objet
dataType:html, //type html

success:function(data){
//fonction callback }
});[/pastacode]

Dans le template Single.php , je vais charger un header allégé si la variable ajax est passée dans la requête.

[pastacode lang="bash" provider="manual"]if ($_GET["ajax"]==true) get_template_part('header-ajax');
else get_header();[/pastacode]

Si la requette provient du script Ajax, la page retournée ne comportera q"un header allégé (sans tous les JS, CSS etc). Sinon le template header.php par défaut est toujours utilisé.
Toujours dans l'esprit de pouvoir utiliser le site avec ET sans Ajax.

Voilà ma première approche, je suis bien sûr preneur d'une meilleure solution (je ne suis pas programmeur dans l'âme...)

A+
Olivier Le 05 juin 2012 à 11h16
Bonjour,

J'utilise ce script pour mon blog, mais je me posais une question à laquelle je n'ai toujours pas de réponse, qu'en est-il des liens d'archive ? J'ai testé ceci :

add_filter('archive_link', 'ajaxed_links');

Mais cela n'existe pas apparemment, une idée ?
banji Le 05 juin 2012 à 17h28
Pour ma part, j'ai créé une nouvelle fonction qui se charge des archives :

[pastacode lang="bash" provider="manual"]function ajaxed_archived_links($fullLink){
$ndd = get_bloginfo('url');
$ancre = str_replace($ndd, $ndd.'/#!', $fullLink);
return $ancre;
}
add_filter('get_archives_link', 'ajaxed_archived_links');[/pastacode]
mana Le 07 juillet 2012 à 15h06
bonjour Bravo pour ton site et ton tuto.. tes tuyaux.
je rencontre quelques difficultés ...
lorsque je selectionne un element de mon menu il devient noir ( a hover: ) hors avec l'ajout de cette fonction ajax il laisse la page par defaut en noir.
-J'utilise un plugin easy fancybox, qui se retrouve désactiver dans la div sur laquelle l'ajax est appliqué. une solution ?

- quand je veux lire un article je repasse par la page d'accueil avant de voir afficher l'article ...
- si j'ai une page qui change legerement de design comment ne pas appliqué l'ajax sur cette page..
merci
Beejeridou Le 11 juillet 2012 à 18h21
Merci ! Je file donc le lien du site que j'ai pu réaliser grâce à toi ! http://www.pulco.fr

Pour l'exécution des scripts js sur les pages chargées en ajax, j'ai utilisé la fonction delegate() de jquery ! Bye !
mana Le 13 juillet 2012 à 12h00
BEEJERIDOU<>> boujour super ton site.
comment utilise tu STP cette fonction delegate() je ne suis pas tres callé javascript ...pour moi c'est pour faire fonctionner easy-fancybox ... ( effetightbox).
ton site a été réalisé avec wordpress?
Merci
Yanik_Lab Le 14 juillet 2012 à 3h27
Bonjour, je rencontre un problème avec ce script pourtant bien sympathique, je pense que par commentaire il sera pas facile de faire un point de la situation, mais à plusieurs endroits où j'utilise le script, j'ai ma requête ajax qui s'exécute plusieurs fois ... C'est assez problématique, et je n'arrive pas à solutionner tout ça, need help (et de ce que je vois c'est un problème récurrent sur les sites utilisant ce script, donc la solution pourrait intéresser du monde).
Contact par mail ?
beejeridou Le 15 juillet 2012 à 10h16
Bonjour Mana, oui le site que j'ai posté a été fait avec Wordpress ;) et la précieuse aide de cette page ! Si tu regardes mon code source, tu peux ouvrir le fichier js.js, j'ai toute une partie qui s'appelle AJAX SYSTEM où dedans il y a des conditions pour lancer les scripts js sur ces pages précises. Dans ton cas, tu n'en a normalement pas besoin pour lancer une lightbox mais rien ne t'empêches de l'utiliser !

@Yanik_Lab, pour ton ajax qui s'execute 2 fois (une response 404, et une response 200), est tu en local ? c'était pareil pour moi mais le problème a été résolu une fois mis en ligne.
Yanik_Lab Le 16 juillet 2012 à 12h15
@beejeridou, non malheureusement, j'ai le souci en ligne, (sur plusieurs sites), et le pire c'est que ce ne sont pas des 404 ^^ mais bien deux fois 200 OK ... peu être est-ce une erreur de ma part mais j'ai remarqué ce problème sur d'autre site cité ici en exemple. (ici par exemple pulco.fr)
beejeridou Le 16 juillet 2012 à 18h26
@Yanik_Lab, Il y a une 301 et une 200 sur pulco, la 301 renvoie le html et la 200... rien ? lol mais rien de grave me semble-il...

Bon courage !
Yanik_Lab Le 17 juillet 2012 à 9h15
Je pose cette question car sur le site d'exemple il n'y a que la 200 OK du coup, sur les autres les deux, et sur le mien 4 ... encore une fois c'est surement une erreur de ma part, mais j'aimerai comprendre ;)
Yanik_Lab Le 18 juillet 2012 à 0h42
Alors ma question n'était pas stupide, il est très important et conseillé, de passé le "/" à la fin de l'url.

En faite il semble y avoir 2 requète qui partent, mais les 2 ne sont pas en 200. Il s'agit d'une 301 (redirection permanente) et d'une 200 ok (la première requete redirige vers la seconde).
Si on regarde mieux, on s'aperçoit que la première requête est balancée sur :
monsite.fr/monarticle
et la seconde sur
monsite.fr/monarticle/

Se qui n'est pas la meme chose. Wordpress redirige l'adresse qui n'a pas de "/" vers l'adresse avec, pour évité le duplicate content !
Parce que meme si, on est d'accord pour nous c'est la meme chose, pour google, quand il va indexer le site, pour lui c'est 2 pages différentes, parce qu'il se base sur la chaine de caractere formant l'url.
Voila pourquoi il est important de faire cette redirection.

Alors ça ne règle pas totalement mon souci, puisque maintenant j'ai deux requête en 200 OK. Pour information j'utilise le .load() à la place du .html(), et j'animate mon #content.
beejeridou Le 18 juillet 2012 à 9h54
Merci pour l'info ! ;)
Matthieu Le 02 août 2012 à 16h31
Merci pour ce super tutoriel !! J'aurais une question : comment peut on changer l'effet? ici, nous avons un fade, si je veux pouvoir rajouter des slideUp/slideDown etc comment puis-je m'y prendre?
Jean-David Le 18 août 2012 à 10h29
Merci infiniment pour ce tutoriel très très pratique. Vous pouvez voir ma mise en pratique sur mon site : http://jean-david.eu.
J'ai utilisé les hashchange sur les liens de navigation en modifiant le hook :
[pastacode lang="bash" provider="manual"]add_filter('get_pagenum_link', 'ajaxed_links'); [/pastacode]

Merci encore, au final, c'est simple, mais il fallait penser à l'utilisation des hashtags !
mika Le 02 septembre 2012 à 18h37
hello :)

dataType:html ==> dataType:'html'
Daniel Roch Le 03 septembre 2012 à 9h17
Merci Mika : c'est corrigé ;)
Yann Le 18 novembre 2012 à 5h11
bonjour,

super tuto, j'aimerai l'utiliser sur un site que je suis en train de développer, malheureusement, il se trouve que ce site est en page unique et que le menu est composé d'ancres pour un effet parallax sans javascript tout en css donc.

je me retrouve donc avec deux ancres dans l'url, et quand je clique sur un titre de post, le site remonte tout en haut sans aucune autre info.

y aurait-il un moyen pour que je reste sur le page avec la deuxième ancre ? (ancre #s2)
Vincent Le 02 avril 2013 à 9h48
Bonjour,

Super tuto que j'ai suivi et mis en place sur un des mes sites.
Cependant, j'ai un soucis lorsque j'accède directement à une page avec une ancre
comme par exemple :

ndd.fr/blog/hot/!#/post-3
l'event JS hashchange n'est pas appelé donc pas de requête ajax et donc pas de nouvelle page... du coup, c'est un brin embêtant... :/
Une idée?
Lalaina Le 25 juin 2013 à 16h50
Merci pour l'article, je l'ai adopté sur mon site, du coup quand je fais un console.log j'ai une messager d'erreur du type :

[pastacode lang="bash" provider="manual"]Uncaught ReferenceError: innerShiv is not defined [/pastacode]

Sachant que j'ai bien intégré innerShiv.js
de [pastacode lang="bash" provider="manual"]https://code.google.com/p/html5shiv/ [/pastacode]
dans mon theme.

Donc pour faire marcher le truc je suis obligé de supprimer
[pastacode lang="bash" provider="manual"]data = innerShiv(data,false);[/pastacode]

Le fait d'enlever cela aura un impact sur les navigateurs ne supportant pas le html5 non?
Lalaina Le 25 juin 2013 à 17h10
Re-bonjour,

Suivant mon problème précédent, même si je commente [pastacode lang="bash" provider="manual"]data = innerShiv(data,false);[/pastacode]

je ne reçois rien dans mon bloc recepteur.

voici le contenu de mon code javascript:

[pastacode lang="bash" provider="manual"]$.ajax({
url:link,
processData:true, //résultat sous forme d'objet
dataType:'html', //type html
success:function(data){

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("#singleContent"); //on trouve la balise qui nous intéresse
$('#parseContent').fadeOut('200',function(){ //on masque le contenu à changer...
$(this).html(contenu.html()).fadeIn('200'); //...puis on charge le nouveau et on affiche
console.log(contenu);
});

}
});

[/pastacode]

le [pastacode lang="bash" provider="manual"]console.log(contenu);[/pastacode] affiche bien dans le console.log par contre je reçois rien dans le div recepteur càd #parseContent

Qu'est ce que je doit modifier?

Merci bcp.
Lalaina Le 27 juin 2013 à 9h33
J'ai mixé depuis une semaine à peu près, mais y a rien qui sortait :)
    Daniel Roch Le 30 juin 2013 à 12h02
    Il faudra attendre le retour sur cette page de Willy Bahuaud pour avoir une réponse malheureusement.
willy Le 03 juillet 2013 à 10h21
Coucou,

Essaye de remplacer cette ligne :
[pastacode provider="manual"]$(this).html(contenu.html())[/pastacode]

... par celle-ci :

[pastacode provider="manual"]$(this).html(contenu)[/pastacode]

Le HTML à charger semble déjà être la variable 'contenu'

:-)
Lalaina Le 03 juillet 2013 à 16h03
Slt Willy, j'ai fait ce que tu as recommandé mais je reçois toujours rien.

Dans console.log j'ai un [pastacode provider="manual"] context: undefined [/pastacode]
beejeridou Le 04 juillet 2013 à 9h44
En tous cas, la requete ajax renvois bien le contenu de la nouvelle page.

Moi je testerai :
[code]
$('#contenu').html(contenu);
[/code]

tu n'est vraiment pas loin !!
beejeridou Le 04 juillet 2013 à 9h46
En gros, tu dois charger le nouveau contenu dans une div existante au chargement de ta première page.
Lalaina Le 04 juillet 2013 à 10h36
Re-salut,

J'ai pu résoudre mon pbm, merci encore pour l'article.
Lalaina Le 04 juillet 2013 à 12h43
[pastacode lang="bash" provider="manual"]var title = $(data).filter('title').text(); //on trouve le titre de la page
document.title = title; //on change le titre
var contenu = $(data).find("#singleContent"); //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
FullScreenBackground(".slideShow"); // redimensionner l'image de fond à la fin du chargement ajax
})[/pastacode]
Lalaina Le 05 juillet 2013 à 8h46
J'ai pu effectivement résoudre mon problème précédent, par contre lorsqu'on navigue avec les boutons précédent et suivant la page est devenue blanche. Un tuyau?
Poke Le 10 avril 2014 à 1h29
Bonjour bonjour, déjà un merci pour le code, et bien joué :)

Pour ma part j'ai un problème qui semble être au niveau du
[pastacode lang="bash" provider="manual"]$('#contenu').fadeOut('200',function(){[/pastacode]

Rien ne se passe hors mis le fait que je me retrouve en page d'accueil avec l'url pourtant bien changée. J'ai bien un élément #content pour accueillir les données, et les divers console.log de data sont corrects.

Des idées, suggestion ou piste qui pourraient m'aider ?
seb Le 13 mai 2014 à 12h16
Astuce super sympa par contre j'utilise souvent les body_class dans Wordpress.
Du coup j'ai trouvé l'astuce suivante sur StackOverflow qui permet de mettre à jour les classes du body.
A placer dans le callback success de $.ajax.

[pastacode provider="manual"]
var regex = /body([^>]*)class=(["']+)([^"']*)(["']+)/gi;
var body_class = regex.exec(data.substring(data.indexOf('<body'), data.indexOf('') + 7))[3];

jQuery('body').removeClass();
jQuery('body').addClass(body_class);
[/pastacode]

Cela semble fonctionner sous IE9+ et Chrome.
seb Le 19 mai 2014 à 15h49
J'ai ajouté le code ci-dessous avant de binder l'événement jQuery(document).ready(...) afin d'ajouter le hash de base lors du premier accès à la page d'accueil juste pour ajouter une sécurité en plus de la balise fragment.

[pastacode lang="bash" provider="manual"]if(window.location.hash == '')
window.location.hash = '#!/';
[/pastacode]

J'ai mis le code ci-dessous dans le success de la requête ajax pour mettre à jour la barre d'administration Wordpress si elle existe.

[pastacode lang="bash" provider="manual"]if(jQuery('#wpadminbar').length !== 0)
{
var admin_bar = jQuery(data).find('#wpadminbar');
jQuery('#wpadminbar').html(admin_bar.html());
}
[/pastacode]
Hugo8705 Le 22 mai 2014 à 21h30
Bonjour,
J'ai utilisé ce script pour l'instant sur un site que je développe (http://lyonsavate.com/dev/) mais l'utilisation d'un formulaire de contact pose problème.
Comment ajouter le filtre "/#!" également sur un bouton type input submit qui est dans un formulaire? Le plugin utilisé pour faire le formulaire de contact est contact form 7
Merci,
Hugo
Yann BP Le 02 mai 2016 à 18h31
Bonjour, je déterre, je déterre !!
Merci pour cet article, très instructif !
Je voudrais savoir si quelqu'un aurait trouvé une solution au problème qu'avait rencontré unknownclubberz, le 26 Fév 2012 ?
Ce serait génial, merci beaucoup !

Yann
Willy Le 09 mai 2016 à 10h42
Bonjour @Yann,

Alors tout d'abord, sache que cet articles est assez ancien : google à depuis déprécié l'usage du headless browser, et puis depuis il est possible de faire mieux (la méthode est détaillé dans la dernière édition du livre « optimiser son référencement WordPress ». Si tu souhaite tout de même utilisé la méthode détaillé" dans cet article, la méthode la plus simple est d'afficher un overlay au chargement (le temps de masquer l'animation en arrière plan).
Jérémy Le 03 juillet 2017 à 20h29
Top ton site ! Que des bons articles étant développeur PHP, j'en apprend beaucoup.
Merci pour ton travail !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *