Tout savoir sur WordPress

tuto Ajax dans WordPress : la méthode simple

Je vous partage aujourd’hui ma méthode simple et propre pour faire de l’ajax avec WordPress, pour notamment lancer une WP query et récupérer le résultat traité par un template (et pas une réponse brute)

Cette technique permet de lancer une WP_query personnalisée et préparer le template WP pour l’afficher dans la page sans complètement la recharger

Vous trouverez pas mal de tutos pour faire de l’Ajax avec WordPress, pour des besoins différents, avec des solutions plus ou moins complexes. Ma solution n’est pas forcément adaptée pour tous les cas mais elle vous sera utile si vous souhaitez :

  • faire un bouton « charger plus d’articles »
  • faire une recherche ajax en temps réel

WP ajax retournera donc un code HTML déjà mis en forme de votre résultat, que vous aurez plus qu’à injecter dans la page, et non pas des données brutes ou sous forme XML/Json.

La technique

On va procéder en 4 étapes

  1. Lancer une requête Ajax avec WP ajax qui sera traitée par WordPress
  2. Exécuter une WP_Query WordPress pour récupérer les informations que l’on veut
  3. Aller chercher le fichier de template souhaité et insérer le contenu dedans
  4. Renvoyer tout ça et l’afficher dans la page

Prérequis : préparation du script

Comme on va avoir besoin d’un script JS pour exécuter Ajax, on va proprement le définir dans notre functions.php :

function add_js_scripts() {
	wp_enqueue_script( 'script', get_template_directory_uri().'/js/script.js', array('jquery'), '1.0', true );

	// pass Ajax Url to script.js
	wp_localize_script('script', 'ajaxurl', admin_url( 'admin-ajax.php' ) );
}
add_action('wp_enqueue_scripts', 'add_js_scripts');

wp_enqueue_script nous permet de définir le script à charger.  C’est nécessaire de procéder comme cela et de ne pas le mettre à la main dans votre template.

Pourquoi ? Tout simplement à cause des dépendances. Par exemple notre script aura besoin de jquery, c’est pour cela qu’un des paramètres est : array(‘jquery’). Les thèmes, les plugins et WordPress définissent leurs scripts de cette manière. A l’affichage, WordPress va trouver l’ordre idéal d’affichage en fonction de ces dépendances.

Ajaxurl

Quand on fait une requête Ajax, il faut l’envoyer à une URL. WordPress a une page dédiée à l’ajax, qui se trouve : http://votresiteweb.ext/wp-admin/admin-ajax.php. Là encore, au lieu de la mettre à la main salement, on va récupérer cette valeur via WordPress, et l’envoyer à notre script. WordPress a une fonction prévue à cet effet : wp_localize_script

On indique là à WordPress que nous avons besoin d’une variable JS nommée ajaxurl , qui contient l’url vers admin-ajax.php. Avec cette méthode, même si vous changez d’URL, votre script fonctionnera toujours.

Etape 1 : La requête Ajax

Côté JS

Maintenant que l’on a tout ce qu’il nous faut, on peut écrire notre requête dans script.js, pour l’instant on écrit juste le code nécessaire. Je mettrais plus bas des cas de figure concrets.

jQuery.post(
    ajaxurl,
    {
        'action': 'mon_action',
        'param': 'coucou'
    },
    function(response){
            console.log(response);
        }
);

Pour le moment ce script se lancera au chargement de la page. N’oubliez pas de mettre un $(document).ready au début de votre document (pourquoi ?).

Côté PHP

Dans votre functions.php de votre thème, on va ajouter :

add_action( 'wp_ajax_mon_action', 'mon_action' );
add_action( 'wp_ajax_nopriv_mon_action', 'mon_action' );

function mon_action() {

	$param = $_POST['param'];

	echo $param;

	die();
}

Ici on fait plusieurs choses  :

D’abord, on définit les actions Ajax via add_action. On le fait 2 fois, afin que les personnes logguées et les personnes non logguées puissent faire fonctionner cette fonction.Les deux lignes sont importantes. Si vous gardez seulement la ligne avec nopriv, la requête ne marchera pas si vous êtes connecté en admin.

Notez que wp_ajax et wp_ajax_nopriv ne changent jamais, mais la suite doit être le nom de l’action que vous avez cité dans votre JS.

La fonction Mon action va gérer la requête ajax, récupérer le paramètre param que j’ai crée dans le js (c’est un nom abritraire, vous pouvez créer autant de valeurs avec les noms que vous souhaitez).

La dernière ligne : die() est très importante pour la sécurité. N’oubliez jamais de la mettre.

Ici on renvoie simplement la valeur de param à Javascript  qui l’affichera dans la console. Pour afficher la console faites un clic droit sur la page, puis Examiner l’élément ou Procéder à l’inspection de l’élément.

inspecteur

Sous l’onglet Network, vous pourrez voir la requête Ajax et son retour, ce que je vous conseille de faire pour débugguer vos requêtes Ajax plus facilement.

Ouvrez votre inspecteur et rechargez la page, dans la liste des fichiers chargés, trouvez admin-ajax.php :

network-tab

ETAPE 2 : Exécuter une requête WP_Query

Une fois qu’on est sûr que la requête fonctionne et renvoie une valeur, on va aller chercher quelque chose de plus concret dans la base de données de WordPress, via la la méthode WP_Query, qui permet de faire des boucles personnalisées afin de récupérer des données précises.

function mon_action() {

	$args = array(
	    'post_type' => 'post',
	    'posts_per_page' => 10
	);

	$ajax_query = new WP_Query($args);

	var_dump($ajax_query);

	die();
}

Ici on demande simplement à WordPress de récupérer les 10 derniers articles du blog. Visitez cette page du codex pour connaitre tous les paramètres possibles de WP_query.

On affiche le résultat en brut via var_dump. Pas super sexy mais on voit à peu près ce que l’on va récupérer.

not-sexy-response

Etape 3 : Envoyer les résultats au template

Ce serait toutefois mieux d’y afficher dans du HTML, comme le fait WordPress habituellement. On va donc passer par un template. Pour éviter de se répéter dans le code, on va prendre ce qui existe déjà mais on va devoir faire quelques changements. Prenons archive.php

get_header();

if ( have_posts() ) : while ( have_posts() ) : the_post();

        // Si vous avez besoin d'accéder à $post->ID par exemple
        global $post;

        get_template_part('article');
        
       // OU
      include(locate_template('article.php'));
      // si vous avez besoin d'accéder aux variables dans le template
endwhile; endif;

get_footer();

Au lieu d’afficher l’intérieur de la boucle directement ici, j’appelle un get_template_part() et je met le code dans un nouveau fichier que j’appelle article.php.

<div class="post">

<h2><?php the_title(); ?></h2>

	<?php the_excerpt(); ?>
	<a href="<?php the_permalink(); ?>">Lire</a>
</div>

Vérifiez, cela devrait changer le comportement du templating par défaut (hors ajax) de votre site. On envoie donc maintenant au template de cette manière :

function mon_action() {

	$args = array(
	    'post_type' => 'post',
	    'posts_per_page' => 10
	);

	$ajax_query = new WP_Query($args);

	//var_dump($ajax_query);

	if ( $ajax_query->have_posts() ) : while ( $ajax_query->have_posts() ) : $ajax_query->the_post();
		get_template_part( 'article' );
	endwhile;
	endif;

	die();
}

Le truc super cool, c’est que si vous passez par la fonction Ajax fournie par WordPress, vous aurez accès à toutes les fonctions du core (le templating, les wp_query, les transients…)

Etape 4 : Renvoyer le résultat et l’afficher dans la page

De retour à Javascript, vous allez pouvoir récupérer la réponse, qui est du HTML tout beau tout propre, et l’afficher ou bon vous semble dans la page, en remplacement d’un contenu, ou à la suite, via la fonction append de jQuery.

jQuery.post(
    ajaxurl,
    {
        ...
    },
    function(response){
    	// on affiche la réponse ou l'on veut
		$('.somewhere').append(response);
	}
);

Exemples concrets

Cas 1 : recherche dynamique AJAX

Grâce à cette méthode, mettons en place une recherche Ajax. Admettons que l’on ai un champ de recherche avec l’id #s

$('body').on('change', '#s', function() {
	var keyword = $(this).val();

	jQuery.post(
	    ajaxurl,
	    {
	        'action': 'search',
	        'keyword': keyword
	    },
	    function(response){
	    	$('.somewhere').html(response);
	    }
	);
});

Dès que l’on tape quelque chose, la recherche se lance en temps réel. Côté PHP :

add_action( 'wp_ajax_search', 'search' );
add_action( 'wp_ajax_nopriv_search', 'search' );

function search() {
	// récupération du mot tapé dans la recherche
	$keyword = $_POST['keyword'];

	$args = array(
	    's' => $keyword
	);

	$ajax_query = new WP_Query($args);

	if ( $ajax_query->have_posts() ) : while ( $ajax_query->have_posts() ) : $ajax_query->the_post();
		get_template_part( 'article' );
	endwhile;
	endif;

	die();
}

Cet exemple reste ultra simple, mais vous donne déjà une bonne idée du fonctionnement. la réponse sera renvoyée à Javascript qui l’affichera dans une div .somewhere.

Cas 2 : Charger de nouveaux articles

Même méthode pour charger de nouveaux articles. Le paramètre que l’on va envoyer c’est l’offset, c’est-à-dire à partir de l’article n° combien on commence à charger (sinon vous aurez toujours en réponse les 10 premiers). On déclenche cette fois sur le clic d’un bouton qui aurait la classe .load-more :

var offset = 10; 
$('body').on('click', '.load-more', function() {

	jQuery.post(
	    ajaxurl,
	    {
	        'action': 'load_more',
	        'offset': offset
	    },
	    function(response){
	    	offset= offset + 10;
	    	$('.alasuite').append(response);
	    }
	);
});

Et côté PHP :

add_action( 'wp_ajax_load_more', 'load_more' );
add_action( 'wp_ajax_nopriv_load_more', 'load_more' );

function load_more() {
        global $post; 

	$offset = $_POST['offset'];

	$args = array(
	    'post_type' =>'post',
	    'offset' => $offset
	);

	$ajax_query = new WP_Query($args);

	if ( $ajax_query->have_posts() ) : while ( $ajax_query->have_posts() ) : $ajax_query->the_post();
	       get_template_part( 'article' );

               // OU
              include(locate_template('article.php'));
              // si vous avez besoin d'accéder aux variables dans le template
	endwhile;
	endif;

	die();
}

Et cette fois on affiche le résultat à la suite, via la fonction append de jQuery. Capito ?

Quelques infos utiles

Contrairement à une WP Query dans un cadre classique, $post affichera Null dans ce cas. Il faut donc ajouter global $post au début de votre fonction afin d’accéder à la variable $post (par exemple $post->post_name, $post->ID…).

get_template_part ne vous permettant pas de passer des variables (comme $_POST) dans votre template, vous pouvez utiliser plutôt include(locate_template(‘article.php’)); à la place (ou passer vos variables dans $post comme il est global, genre $post->ma_variable)

Troubleshooting

Si ça ne marche pas vérifiez :

  • Avez-vous bien mis les 2 add_action ?
  • Si oui, avez-vous pensé à mettre le bon nom d’action où c’est marqué #là!#
add_action( 'wp_ajax_#là!#', '#là!#' );
add_action( 'wp_ajax_nopriv_#là!#', '#là!#' );

function #là!#() { ...
  • Vérifiez si vous n’avez pas d’erreur dans la console de votre navigateur. Si oui : l’erreur se trouve dans le JS
  • Vérifiez la réponse Ajax depuis l’onglet Network du navigateur. s’il y a une erreur PHP, vous la verrez

error

  • Est-ce que ajaxurl fonctionne bien en js ? Depuis l’inspecteur tapez ajaxurl, si le résultat est null, c’est que le localize script a pas fait son boulot

Rendre un site WordPress totalement ajax

Si votre besoin est de transformer votre site en full ajax, je vous conseille LE guide Ajax de Willy sur boiteàweb , qui utilise des load à partir des URLs WP et qui explique pourquoi cette méthode n’est pas forcément adaptée.

Cet article a été mis à jour il y a 1139 jours - Il n'est peut être plus à jour !

Article écrit par Maxime BJ

Développeur, bloggeur et formateur Web spécialisé WordPress. 31 ans. Grenoblois. Co-fondateur de WPChef, l’organisme de formation WordPress.

Organisateur de WPInAlps, le meetup WordPress Grenoblois. Vous pouvez me rencontrer lors d’événements tels que WordCamp Paris et Europe. Traducteur Français de l’extension Advanced Custom Fields. Également développeur d’applications web avec MeteorJs. Je m’occupe un site pour apprendre l’informatique aux débutants gratuitement.

J’aime les jeux vidéo, la rando, la bouffe bien grasse et les voyages.

62 Commentaires

  1. Bonjour,

    D’abord, merci pour ce magnifique tutoriel!!!! Je l’adore!
    J’ai un soucis au niveau du renomage de la function en php
    add_action( ‘wp_ajax_#là!#’, ‘#là!#’ );
    add_action( ‘wp_ajax_nopriv_#là!#’, ‘#là!#’ );
    function #là!#() {
    Lorsque je remplace mon_action par le nom que je souhaite, cela ne marche pas. Pourtant avec mon_action, ça marche et je ne comprend pas pourquoi.

    J’ai l’erreur suivante sur network
    Fatal error: Cannot redeclare test() in C:\wamp\www\wordpress\wp-content\themes\accesspress\functions.php on line 28 (Contient ma function test qui remplace mon_action)

    Si vous pouvez sur mon problème =D
    Merci d’avance pour l’aide =D

  2. Salut,

    D’après l’erreur tu as déjà défini une fonction test() (ou un plugin l’a fait) quelque part, et quand ça doublonne ça plante. essaye de l’appeler autrement c’est surement juste ça ;)

  3. Super article, cependant je me demandais si il y’avais un moyen de mettre à jour la pagination lorsque qu’un template différent est appelé ? Dans mon cas j’en ai 3 qui reclassent les articles en fonctions de leurs date / nombre de commentaire et nombre de like, et en plus la fonction de recherche.

    • Salut,
      Dans ce tu peux créer un array en php avec deux entrées : la première contient le code des articles à jour, et la deuxième la pagination à jour, tu serialise en json pour l’envoyer à JS, et à réception de la requête JS va injecter dans le contenu tes articles et dans la div de pagination ta nouvelle pagination. Du coup en PHP tu ne fais pas echo. Faut juste réussir à récupérer le contenu du get_template au lieu de l’afficher directement par contre, en utilisant ob_start() de PHP (exemple ici : http://stackoverflow.com/questions/5817726/wordpress-save-get-template-part-to-variable)

  4. Bonsoir,

    Merci pour l’exemple complet et clair, ca fonctionne très bien mais c’est lent.

    Si je fais une requête ajax sans passer par admin-ajax, c’est direct.
    (Mais je voudrais vraiment passer par le fichier admin-ajax car sinon, je dois mettre des includes et mettre des chemins absolu ds les js.)

    Le problème vient du au heartbeat de WP. Mais j’arrive pas à le désactiver.

    Merci

    • De rien :) normalement ce n’est pas sensé être lent (c’est toujours un poil plus long qu’en direct car WP charge pas mal de choses) Mais c’est sensé être assez fluide. Il vaut mieux passer par la fonctionnement WordPress afin d’éviter toute faille de sécurité. Sinon il y a l’API Rest WP qui est dispo et qui peut dans certains cas t’être utile !

  5. Hello,

    Je suis à la rue!!! Ingénieur polytechnique à la base, je pense être capable de comprendre les choses rapidement… Je suis développeur objet (jusqu’à 2007)… Et aujourd’hui je cherche à faire un site basé WP, mais avec derrière une BD relationnel ‘complexe’.

    Je fais cela sur mon temps libre, et donc n’ai pas la moindre formation HTML / AJAX / JQUERY / JSON / JSCRIPT… Bref, serait-il possible de te demander une aide privée (Skype ou autre) pour m’apprendre rapidement à pêcher le poisson, et non me le donner…

    Mon projet est très précis, et il ne me manque que la possibilité de :
    1. ‘Pluger’ ma base de donnée (déjà faite avec MySQL) sur mon site
    2. Appliquer 3 rôles (droits utilisateurs) :
    a. Membres (ayant une vision du site)
    b. Organisateurs d’événement (Ayant une 2ème vue)
    c. Administrateurs gérant le site (ajoutant les les membres / organisateurs / etc…)
    3. Savoir comment faire et afficher dans WP des requêtes suivant ce que les Membres cherchent

    Le dramatique dans tout ça, c’est que je serais totalement capable de le faire avec Delphi ou autre… Mais pas sur un site web :-(!!!

    A ces vieux de 37 ans!!!

    Merci pour une aide (qui serait rémunérée)

    A+

    Daric

    • Salut !
      Je vais être charette niveau temps mais on peut en parler oui avec plaisir. Si ton projet est pressé je te conseille de faire ta demande sur le groupe WordPress Academy sur Facebook où 2000 membres pourront t’apporter de l’aide. envoie moi tes coordonnées par mail via le formulaire contact et on définira ensemble un moment pour s’appeler. :)

    • De rien :) je me suis dit qu’elle pourrait être pratique pour beaucoup quand je l’ai découverte, car en plus elle est simple à mettre en oeuvre

  6. Bonjour,

    Tout d’abord merci pour ton tutoriel qui est bien plus clair que les 3/4 de ceux qu’on peut trouver sur internet.

    J’ai un problème avec ta fonction : je la copie/colle et rien ne fonctionne. Je suis allé voir dans l’inspecteur histoire de trouver le problème, et je n’ai même pas le fichier admin-ajax.php qui s’y affiche. Je ne m’y connais pas beaucoup en AJAX donc je ne sais pas vraiment comment résoudre le soucis…

    Je suis sous InstantWP, est-ce qu’il peut y avoir un conflit à ce niveau ?

    Merci d’avance !

    • Bonjour,
      je ne connais pas instantWP mais de ce que j’en vois c’est pour installer WordPress donc il ne devrait pas y avoir de souci. as-tu des erreurs js dans la console ?

    • J’ai en effet une erreur js dans la console, il ne trouve pas « ajaxurl ». Je me dit que si admin-ajax.php n’est pas appelé ce doit être normal…

    • Ok du coup c’est au niveau du début,; wp_localize_script que ca ne doit pas bien passer, le « script » dans localize script doit être le même nom que ton appel précédent de ton js principal.

    • Je n’ai pas bien compris mais de toute façon j’ai tout copié/collé et reproduit la même structure avec un dossier js dans le lequel je met script.js.

    • Est-ce que je dois déclarer le script « script.js » dans mon header ? Quand je le déclare j’ai l’erreur dont je te parlais précédemment et quand je ne le déclare pas je n’ai aucune erreur js.

    • Je déclare toujours mon script dans le footer. Si ton script est bien déclaré avec enqueue script ça devrait marcher

    • Donc je dois aussi le déclarer dans le footer ? Je pensais que c’était le rôle de enqueue_script.
      Voici enqueue et localize dans mon code :

      wp_enqueue_script( ‘script’, get_template_directory_uri().’/js/script.js’, array(‘jquery’), ‘1.0’, true );

      // pass Ajax Url to script.js
      wp_localize_script(‘script’, ‘ajaxurl’, url_admin(‘admin-ajax.php’) );

      (j’ai aussi essayé avec « /wp-content/themes/blog/js/script.js », mais ça ne fait rien, et ce peu importe si je déclare le script ou non).

  7. Bonjour,

    Merci beaucoup pour ce auto qui m’a vraiment bien aidé.
    Je tout de même une question, est-il possible de faire une requête sur des tables non wordpress ( que j’ai créé moi ) de la bdd?

    • Est-ce que tu as des bases en PHP et JS/AJAX ? Ca peut être un peu dur si tu en a jamais fait, sinon ça reste relativement simple si tu suis à la lettre :)

  8. Salut,
    Ton article m’a beaucoup aidé :)
    J’utilise ton exemple pour charger des articles supplémentaires en ajax.
    Tu as une idée de comment cacher un bouton ‘load more’ quand il n’est plus utile, c’est a dire quand il n’y a plus de posts à charger ?

    • Salut,
      en faisant une query tu peux récupérer le nombre total de résultats via $my_query->found_posts. Comme tu as le nombre d’articles chargés tu peux comparé facilement : si les chiffres correspondent, tu peux cacher le bouton :)

  9. bonjour
    je remercie pour ce tuto ne connaissant pas ajax et peu jquery
    ayant quelques connaissance en js mais
    j essaie par le deuxieme exemple de l’adapter pour changer le post_type mais je n’y arrive pas
    dans la fonction loadmore
    $posttype=’post’;
    $posttype== $_POST[‘post_type’];

    $args = array(
    ‘posts_per_page’ => 10,
    ‘showposts’ => 10,
    ‘post_type’ =>$posttype
    //’offset’ => $offset
    );

    //wp_reset_query();
    $ajax_query = new WP_Query($args);

    if ( $ajax_query->have_posts() ) : while ( $ajax_query->have_posts() ) : $ajax_query->the_post();
    echo  ».$posttype. »;
    get_template_part( ‘article’ );
    (…)

    ça affiche bien le posttype
    mais apres dans le script.js

    var posttype = ‘page’;
    $(‘body’).on(‘click’, ‘.load-more’, function() {

    jQuery.post(
    ajaxurl,
    {
    ‘action’: ‘load_more’,
    ‘post_type ‘: posttype
    },
    function(response){
    alert(posttype);
    ‘post_type ‘: posttype; //j’ai mis posttype tout seul posttype=posttype etc…
    // là je vois pas comment adapter j’essai un peu tout mais je m’enfonce et m’embrouille à chaque essai !!!
    $(‘.alasuite’).append(response);
    }
    );

    merci de me donner un tit coup de pouce
    et encore bravo sur ce tuto j’en ai vu plein mais pour debuter en plus de la particularité de wordpress pour ajax
    c’est le plus didactique que j’ai vu pour l’instant
    j’espère qu’il est pas trop long ce com
    });

    • merci pour ton message !
      à mon avis l’erreur est en ligne 2
      $posttype == … -> le double = sert à tester une condition dans un if seulement, du coup là il fait rien. et le fait d’assigner 2 fois ta variable (ligne 1 et 2) fait que la 2 écrase la 1. Enfin pas là comme la ligne 2 est un test dans le vide. Enleve la ligne 1, enleve un = à la ligne 2, ça devrait le faire

    • si j’ai mis une == c’est que j’ai tenté juste ça
      $posttype= $_POST[‘post_type’];
      mais ensuite
      echo  ».$posttype. »;
      n’affiche plus rien avec
      //$posttype=’post’;
      $posttype= $_POST[‘post_type’];
      ça a affichait ‘post’
      ça me servait de valeur de test que j’avais trouvé en tatonnant et donc me paraissait bon meme si je sais que c’est étrange hors condition
      de plus wordpress par défaut prendra les « post » donc je suis pas sur que le echo si il affiche rien n’est un pas un test correct pr moi pour etre sur
      j’ai plus de probleme de toute façon avec la fonction retour
      je test là mais je pense qu’il me faut deux parametres champs ‘post_type’ et valeur ‘post’ ou ‘page’ etc…
      bref un peu dans le flou encore

    • bon j’ai réussi
      en fait dans ton exemple non plus ‘offset’ n’apparait pas
      il sera intialisé une fois le param action du js ajax réussi
      j’avais pas tout compris ;)
      par contre mais je verrais plus tard (mal à la tete je viens de passer chez le dentiste moins drole)
      ça ne remplace pas la boucle principale meme si je fais un global mais bon donc je me coltine les post d’avant
      je met mon bout de code pour ceux qui voudraient voir :
      scripts.js:
      var posttype = ‘page’;
      $(‘body’).on(‘click’, ‘.load-more’, function() {

      jQuery.post(
      ajaxurl,
      {
      ‘action’: ‘load_more’,
      ‘post_type’: posttype
      },
      function(response){
      //alert(posttype);
      posttype+=posttype;
      $(‘#content’).append(response);
      }
      );
      });

      functions.php:

      add_action( ‘wp_ajax_load_more’, ‘load_more’ );
      add_action( ‘wp_ajax_nopriv_load_more’, ‘load_more’ );

      function load_more() {
      //$offset = $_POST[‘offset’];
      $posttype= $_POST[‘post_type’];

      $args = array(
      //’posts_per_page’ => 10,
      ‘showposts’ => 5,
      ‘post_type’ =>$posttype
      //’offset’ => $offset
      );
      wp_reset_query();
      $ajax_query = new WP_Query($args);

      if ( $ajax_query->have_posts() ) : while ( $ajax_query->have_posts() ) : $ajax_query->the_post();
      echo  ».print_r($args,true). ».print_r($offset,true) . ».print_r($posttype,true) . »;
      get_template_part( ‘article’ );
      endwhile;
      endif;
      //get_sidebar();
      //get_footer();
      //die();
      }

  10. Bonjour,
    Chouette Tutoriel, facile à comprendre et mettre en place.
    Je voudrait utiliser cette technique pour charger de nouveaux articles. je voudrai cacher le bouton « Load more » lorsque tout les articles sont affichés. Comment passer cette information à Jquery ? Une piste ?

    Merci

    • Hello !
      Alors normalement en PHP tu peux faire un < ?php wp_count_posts( $type, $perm ); ?> pour compter la totalité. Comme toi tu as tenu un compte des articles chargés en JS tu peux le transmettre, et comparer ! J’ai plus le code exact en tête mais tu as le concept

  11. Bonjour
    Merci beaucoup pour ce tuto
    Je sèche un peu sur la manière d’informer que le résultat de la recherche n’a rien donné. J’ai essayé de mettre un else avec une chaine de caractères dans function.php mais ça ne fonctionne pas
    Est-ce que vous avez une piste ?
    merci
    Cyril

  12. Bonjour
    pour ceux que ça intéresse j’ai utilisé les outils du tuto pour aller chercher les articles par mois avec wp_get_archive
    c’est un peu du bricolage mais ça fonctionne ;) et exactement sur le même principe.
    j’ai utilisé le select dropdown et dans le fichier ajax.js je découpe l’url renvoyé avec la methode split pour ne garder que l’année et le mois (il faut adapter si on est en local ou en production) que j’injecte dans deux variables et je reprends dans mon script php dans function.php

    Je vous mets ici le code:

    le dropdown archive dans notre template:

    Archives

    ‘monthly’, ‘format’ => ‘option’, ‘show_post_count’ => 1 ) ); ?>

    notre script dans ajax.js:

    $(‘body’).on(‘change’, ‘#archive’, function(e) {
    $(‘#contenu’).html( »);
    //on decoupe l\’url pour ne retenir que le numero du mois et de l\’année
    var dateArray = $(this).val().split(« / »);

    var y = dateArray[1];
    var m = dateArray[2];

    jQuery.post(
    ajaxurl,
    {
    ‘action’: ‘archive’,
    ‘digwp_y’: y,
    ‘digwp_m’: m
    },
    function(response){
    $(‘#contenu’).fadeOut(200).html(response).fadeIn(200);
    }
    );
    });

    et notre script php dans function.php:

    add_action( ‘wp_ajax_archive’, ‘archive’ );
    add_action( ‘wp_ajax_nopriv_archive’, ‘archive’ );
    // function get archive ajax
    function archive() {

    $year = $_POST[‘digwp_y’];
    $month = $_POST[‘digwp_m’];

    $querystring = « year=$year&monthnum=$month. »;

    query_posts($querystring);
    if (have_posts()) : while (have_posts()) : the_post();
    get_template_part( ‘article’ );
    endwhile;

    endif;
    if(!is_home()){ ?>

    <a id="retour" href="/#!/ »>Retour
    <?php }

    die();
    }

  13. Bonjour et merci pour ce tuto qui m’a permis de comprendre la chose
    j’ai une question, si tu peux m’aider…
    dans une page single.php, j’ai mon article et en bas de page, une div dans laquelle je souhaiterai afficher d’office les 5 derners articles
    ta méthode fonctionne mais je ne parviens pas à afficher d’office 5 articles et faire en sorte qu’au clic sur le bouton, j’ai les 5 suivants (à la suite avec .append ou en remplacement avec .html)
    si je laisse la div vide dans ma page single, je n’ai rien au chargement
    si je fais une boucle pour en avoir 5 j’en ai 10 à la place et à chaque clic sur le bouton ca m’en rajoute 10
    saurais tu m’expliquer comment en afficher 5 d’office puis les remplacer par 5 nouveaux articles au clic???
    merci d’avance si tu peux m’éclairer…

  14. Bonjour,

    J’essaye d’utiliser votre code pour faire de l’infinite scrolling sur un thème que j’ai fait moi-même et cela ne marche pas. J’ai pour l’instant utilisé un bouton avec la classe load more mais la suite ne se charge pas et j’obtiens ces erreurs au niveau de la console :
    – Calling Element.createShadowRoot() for an element which already hosts a shadow root is deprecated. See https://www.chromestatus.com/features/4668884095336448 for more details
    – VM1263:5 Uncaught TypeError: Cannot read property ‘removeAttribute’ of null(anonymous function) @ VM1263:5(anonymous function) @ VM1263:20
    – jquery-migrate.min.js?ver=1.4.1:2 JQMIGRATE: Migrate is installed, version 1.4.1

    Sauriez-vous me dépanner ?

    Bonne journée

    • L’erreur ne doit probablement pas avoir de rapport avec ce code à priori. Dans l’inspecteur de code, onglet network, tu devrais voir partir ta requête et voir le résultat (ou s’il y a eu une erreur PHP)

    • Bonjour,

      La requête n’est pas partie, rien ne se passe (je n’ai fait que l’étape 1) et il n’y a pas d’erreur dans le PHP. Il ne se passe tout simplement rien. script.js n’est même pas dans les sources

    • Et si j’ajoute le script « à la main » je ne vois pas « coucou » dans la réponse mais tout mon code HTML

    • Revérifies alors les prérequis : si ton script n’est pas chargé c’est normal que ça ne marche pas, il faut que dans ton code source tu voies l’appel au script

  15. Bonjour !
    Alors j’ai un problème qui à l’air bête : mon fichier js déclenche une erreur 404 :O
    C’est le bon nom de fichier, je l’ai rangé dans le dossier /js à la racine de mon template enfant, j’ai copié collé le code de functions.php que tu fournis dans ton tutoriel vers la fin de mon fichier functions.php qui se trouve à la racine de mon template enfant.

    quand je cherche ajaxurl dans l’inspecteur je tombe la dessus :

    /* */

    Est ce normal que ca soit en commmentaire ?

    Sinon excellent tuto, il est très bien détaillé avec meme du troubleshooting franchement parfait :D !

    • aïe il a cru que je voulais faire une injection de balises HTML mais en gros j’ai balise ouvrante script javascript avec en commentaire var ajaxurl = …urldusiteadminajax… balise fermante

    • Tu appelles bien ton fichier Js dans enqueue_scripts du coup ? Tu peux m’envoyer une capture d’écran de ton code par mail à la limite ?

    • Yep si tu as mon adresse mail envoie moi quelque chose ou alors donne moi la tienne je n’ai que ton compte tweeter.

    • add_action( ‘wp_enqueue_scripts’, ‘add_js_script’ );
      function add_js_script() {
      wp_enqueue_script( ‘script’, get_template_directory_uri().’/js/chronopost-generation-js.js’, array(‘jquery’), ‘1.0’, true );

      // pass Ajax Url to script.js
      wp_localize_script(‘script’, ‘ajaxurl’, admin_url( ‘admin-ajax.php’ ) );
      }

      add_action( ‘wp_ajax_generate_skybill_chronopost’, ‘generate_skybill_chronopost’ );
      add_action( ‘wp_ajax_nopriv_generate_skybill_chronopost’, ‘generate_skybill_chronopost’ );

      function generate_skybill_chronopost() {

      $param = $_POST[‘param’];

      echo $param;

      die();
      }

  16. Merci pour le tuto,

    Je suis confronté à un problème avec wp_localize_script qui me retourne une mauvaise adresse :
    wp_localize_script(‘ajax-pagination’, ‘ajaxurl’, admin_url( ‘admin-ajax.php’ ) );
    mais dans ma fenetre de requete :
    POST http://wordpress.local/wp-admin/admin-ajax.php net::ERR_NAME_NOT_RESOLVED avec l’erreur

    J’ai beau mettre par exemple :
    wp_localize_script(‘ajax-pagination’, ‘ajaxurl’, ( ‘http://www.twoclickdesign.com/wp-admin/admin-ajax.php’ ) );

    il me retourne tjr http://wordpress.local/

    Je ne travail pas en local avec vous une idée d’ou pourrais provenir le problème ?

    Merci

    • Merci pour la réponse,

      Oui je viens de vérifier et tout est OK l’url est bien la bonne.

      J’ai installée WP via OVH avec leur module en 1 click c’est peut être la cause du soucis ?

      J’ai essayé aussi d’autre tuto plus ou moins complet mais tjr le même soucis.
      Un ficher .htacces peut-il poser problème ?

      Merci

    • Voilà le ficher htacces qu’OVH à ajouté à la racide de WP :

      # BEGIN WordPress

      RewriteEngine On
      RewriteBase /
      RewriteRule ^index\.php$ – [L]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /index.php [L]

      # END WordPress

    • C’est bon problème résolut.

      Par contre comment faire si nous souhaitons lancer une function avant que la requête soit complètement chargée (loader), et idem une fonction lorsque l’appel est completement finit (afficher les éléments avec des effects par exemple).

      Merci d’avance

  17. Bonjour, un grand merci pour cet tuto :)
    J’ai une petite question, j’utilise une fonction PHP pour détecter le navigateur de l’utilisateur et ensuite écrire le nom de son navigateur ainsi que le logo qui correspond.
    Elle est utilisée dans mon menu (principale) du site ainsi que dans différents blocs (texte) sur plusieurs pages.
    Mon souci c’est que je suis en train d’optimiser le chargement de mon site et j’ai installé un plugin pour faire ça ainsi que pour mettre en cache.
    Et c’est là le problème, la mise en cache des pages casses mon script php.
    On m’a dit que je devais charger le bloc qui contient mon php via une requête ajax.
    Mais je ne comprends pas comment faire pour que chacune de mes pages (ou wp) charge le menu via ajax et non de manière classique.
    Si jamais vous pouvez m’aiguiller et me dire si c’est bien possible de cette manière et comme ça qu’il faut procéder.
    Merci

    • Salut,

      en effet quand tu met en cache ce genre de truc saute. Pour ma part c’était un compteur de visite d’une page que j’avais fait main. Du coup j’ai du le faire en ajax pour qu’il continue d’être exécuté.

      en fait il faut que tu laisse l’emplacement ou tu affiche le navigateur « vide » lors de la génération de la page, et ton ajax va aller chercher l’info et injecter la réponse (le html) à cet endroit.

      D’ailleurs pour de la détection de navigateur tu peux le faire direct en JS au lieu d’aller chercher PHP, ce sera plus simple et tu évites une requête au serveur ;)

  18. J’ai fait comme pas à pas comme le tuto mais les résultats s’affiche seulement sur la console et non pas au div que j’ai attribué dans le code script.js

    • Bon la chose positive c’est que tu n’es pas loin de la vérité. A mon avis c’est juste un problème de sélecteur dans ton append / prepend à la fin de la fonction ajax qui n’injecte pas au bon endroit, selon moi .

  19. Salut ! J’ai essayé de suivre le tutoriel, qui m’a l’air très bien construit, malheureusement j’ai un problème au début. En effet, pour une raison inconnue, j’ai l’erreur suivante :
    script.js?ver=1.0:2 Uncaught ReferenceError: wp_localize_script is not defined
    at HTMLDocument. (script.js?ver=1.0:2)
    at i (jquery.js?ver=1.12.4:2)
    at Object.fireWith [as resolveWith] (jquery.js?ver=1.12.4:2)
    at Function.ready (jquery.js?ver=1.12.4:2)
    at HTMLDocument.K (jquery.js?ver=1.12.4:2)
    Est-ce que tu saurais d’ou ça vient ?
    Cordialement et merci.

    • Ah oui en effet, je sais absolument pas pourquoi je l’avais dans mon js… Merci beaucoup en tout cas !
      J’ai une autre question au passage, je souhaiterais que ce script js ne soit que dans une page précise de mon site internet, comment faire ?
      Cordialement.

c03735f8e7ca113dd05313021f182f0600000000000000000000000000000