Appeler une liste d’articles en Ajax

Ce post fait référence à l’article de geekpress sur l’utilisation de l’ajax pour afficher ses articles.Je vous invite à lire l’article, très bien expliqué, et qui pourra clarifier les points obscurs.

Ici le code est une adaptation bien particulière du code, et le but est d’afficher dans le bas d’une page single, et non une page d’archive, une liste d’articles « recommandés » ou  » à la une » qui se recharge en ajax.

Une image pour mieux comprendre: Je suis sur une page d’article, et tout en bas j’ai un bloc contenant 6 articles « A la une ».

ajax posts

Tout à la fin de cette liste, j’ai un bouton « afficher davantage de recommandations » qui me permet de recharger 6 nouveaux articles, en Ajax, donc sans rechargement de la page.

Le fichier functions.php

Voici le code à placer dans le fichier functions.php

function add_js_scripts() {
wp_enqueue_script( 'scripts', get_template_directory_uri().'/js/scripts.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');

add_action( 'wp_ajax_load_more', 'load_more' );
add_action( 'wp_ajax_nopriv_load_more', 'load_more' );
function load_more() {
global $post;
$sticky = count(get_option('sticky_posts'));
$offset = $_POST['offset'];

$args = array(
'post_type' =>'post',
'posts_per_page'=> $sticky - 6,
'offset' => $offset,
'post__not_in' => array($post->ID),
'meta_query' => array(
array(
'key' => 'recommandations-checkbox',
'value' => 'yes'
)
)
);

$ajax_query = new WP_Query($args);
if ( $ajax_query->have_posts() ) : while ( $ajax_query->have_posts() ) : $ajax_query->the_post();
include(locate_template('additional-posts.php'));
endwhile;
endif;

$posts_count = $ajax_query->found_posts;
if ($posts_count - ($offset + 3) <= 0) { ?>
<script>
function hideLoadMore(){
jQuery(".load-more").text("Il n\'y a plus de recommandations");
}
</script>
<?php }
die();
}

Plusieur choses intéressantes sont à voir ici

Déjà le code en lui même pour faire fonctionner l’ajax, avec l’appel au fichier admin-ajax.php dans notre première fonction add_js_scripts()

Dans la fonction load_more()  on utilise un offset pour connaitre le nombre de post  à recharger.Un offset qu’on reprendra dans chaque boucle créee pour l’occasion

Ensuite on crée la boucle pour ramener les articles.Mes arguments ici sont les suivants:

'posts_per_page'=>  $sticky - 6, 

pour dire ramène moi toujours 6 articles, en outrepassant l’existence ou non d’articles « mis en avant » (quand l’utilisateur utilise la fonction par défaut de « mise en avant » de wordpress, via l’édition rapide dans la page de tous les articles en backoffice).
Cet argument fait appel à  la fonction ‘count()’ juste au dessus, qui me permet de comptabiliser le nombre d’article « mis en avant » par l’utilisateur et ainsi de les soustraire à l’affichage, sinon il vont s’ajouter aux 6 articles..ce que je ne veux pas ici..

$sticky = count(get_option('sticky_posts')); 

Et – 6 car je veux ramener ici quoiqu’il arrive 6 articles.

Dans mon cas particulier, j’applique une boucle en me basant sur une meta box, une case à cocher qui permet à l’utilisateur de classer un article en recommandation.
‘meta_query’=>array() .On peut bien sûr créer une boucle tout à fait classique

Un fichier additionnel pour l’article à afficher

Dans la boucle, on fait appel à un fichier tiers
include(locate_template(‘additional-posts.php’));  que j’ai crée et qui ne contient que le code de la boucle, rien d’autre: le titre l’extrait, l’image à la une (voir image ci dessus), pas de get_header() ou get_foote().

Un message pour prévenir l’utilisateur

Enfin la dernière fonction me permet d’afficher un message de fin s’il n’y a plus d’articles correspondants à mes arguments

 $posts_count = $ajax_query->found_posts; 
if ($posts_count - ($offset + 3) <= 0) { ?>
<script>
function hideLoadMore(){
jQuery(".load-more").text("Il n\'y a plus de recommandations");
}
</script>

Le fichier js

Voici mon fichier scripts.js qui permet le rechargement d’article au clic sur le bouton.

jQuery(document).ready(function($){
var offset = 6;
$('body').on('click', '.load-more', function() {
jQuery.post(
ajaxurl,
{
'action': 'load_more',
'offset': offset
},
function(response){
offset = offset + 6;
$('#postContainer').append(response);
if(hideLoadMore) {
hideLoadMore();
}
}
);
});
});

Ici je rappelle la fonction js créee dans functions.php : load_more() pour charge plus d’articles et hideLoadmore() pour afficher le message de fin au clic, si jamais il n’y a plus d’article

Comme ici on veut afficher la liste dans un fichier single.php,et non une page d’archive, il va falloir recréer un boucle dans single.php

	<?php 

$sticky = count(get_option('sticky_posts'));

$args = array(
'post_type' =>'post',

'posts_per_page'=> $sticky - 6,
'post__not_in' => array($post->ID),
'meta_query' => array(
array(
'key' => 'recommandations-checkbox',
'value' => 'yes'
)
)
);

$featured_query = new WP_Query($args);

while ($featured_query->have_posts()) : $featured_query->the_post();
include(locate_template('additional-posts.php')); ?>

<?php
endwhile;
wp_reset_postdata();
?>
</div>
<div class="load-more col-lg-7 col-md-9 col-sm-12 col-xs-12">Afficher davantage de recommandations...<img src="http://site.com/wp-content/themes/site/images/picto.png" alt="picto"></div>

Je reprend ici la même boucle avec les même arguments, autrement en arrivant sur la page single.php la liste des articles serait vide.En doublant le code, on s’assure qu’il y ait toujours 6 articles affichés.Je n’ai pas trouvé ici d’autres alternatives pour simplifier ou minimiser le code

 

Voila, il ne reste plus qu’à stlyliser le tout, mais les fonctions sont là, et le rechargement des articles en ajax fonctionne!!

Petite astuce, pour remplacer les articles par d’autres articles, et non les rajouter, il suffit dans la fonction « function(response){} » du fichier js de remplacer .append(), par une autre fonction  comme .html() par exemple