Modifier la boucle WordPress

Modifier la boucle principale de WordPress

La boucle principale de WordPress permet d’afficher les articles correspondant à l’adresse web utilisée par le visiteur du site. Il est possible de la modifier en utilisant le crochet « pre_get_posts » ou la fonction query_posts (déconseillé).

Le crochet pre_get_posts

Le crochet pre_get_posts permet de modifier la boucle principale avant qu’elle ne soit exécutée. Le codex décrit le fonctionnement de pre_get_posts (en anglais).

Nous allons voir quelques exemples de modification de la boucle principale.

Afficher un seul article en fonction de son identifiant (slug)

Code à insérer dans le fichier functions.php du thème actif :

add_action( 'pre_get_posts', 'wpdf_demo_pregetposts', 1 );

function wpdf_demo_pregetposts( $query ) {
    $query->set( 'name', 'article-5' );
}
Modifier la boucle - sélection sur l'identifiant d'un article

Voici ce qui s’affiche lorsqu’on demande la page d’accueil :

Modifier la boucle - sélection d'un article
Modifier la boucle – sélection d’un article

Conformément au paramétrage défini dans la fonction associée au crochet ‘pre_get_ posts’ ($query->set( ‘name’, ‘article-5’ ), la boucle principale n’affiche que l’article dont l’identifiant est ‘article-5’.

Demandons l’affichage d’une catégorie d’articles. Voici ce qui s’affiche :

Modifier la boucle - catégorie + article
Modifier la boucle – catégorie + article

WordPress doit gérer deux conditions :

  • la catégorie demandée dans l’adresse web,
  • l’article 5 sélectionné par le crochet pre_get_posts.

Si l’article 5 ne fait pas partie de la catégorie demandée, WordPress ne trouve aucun article répondant simultanément aux deux conditions posées.

Voici, en partie, l’objet $query qui est passé en paramètre dans la fonction associée au crochet ‘pre_get_posts’ :

object(WP_Query)[1738]
public ‘query’ =>
array (size=1)
‘category_name’ => string ‘installation-wordpress’ (length=22)
public ‘query_vars’ =>
array (size=50)
‘category_name’ => string ‘installation-wordpress’ (length=22)
‘error’ => string  » (length=0)
‘m’ => string  » (length=0)
‘p’ => int 0
‘post_parent’ => string  » (length=0)
‘subpost’ => string  » (length=0)
‘subpost_id’ => string  » (length=0)
‘attachment’ => string  » (length=0)
‘attachment_id’ => int 0
‘name’ => string ‘article-5’ (length=9)

Pour éviter que le paramétrage soit pris en compte là où cela n’est pas souhaité, il est indispensable de compléter la fonction associée au crochet pre_get_posts :

add_action( 'pre_get_posts', 'wpdf_demo_pregetposts', 1 );

function wpdf_demo_pregetposts( $query ) {
	if ( ! is_admin() && $query->is_main_query() && is_home()){	
		$query->set( 'name', 'article-5' );
    }
}
Modifier la boucle - contrôler le contexte d'utilisation

La boucle principale n’est désormais modifiée que si trois conditions sont réunies : ne pas être dans l’administration [! is_admin()], être dans la boucle principale [is_main_query()] et demander l’affichage de la page d’accueil [is_home()]. Grâce à ces trois conditions, la page d’accueil affiche toujours le seul article 5, mais les autres pages ne sont plus impactées.

IMPORTANT :  les paramètres s’écrivent en minuscule. Par exemple, « NAME » est un paramètre inconnu de WordPress et lui affecter une valeur n’aura aucun effet sur le fonctionnement de la boucle.

Afficher les articles de certaines catégories et modifier l’ordre

Code à insérer dans le fichier functions.php du thème actif :

add_action( 'pre_get_posts', 'wpdf_demo_pregetposts', 1 );

function wpdf_demo_pregetposts( $query ) {
	if ( ! is_admin() && $query->is_main_query() && is_home()){	
		$query->set( 'cat', '3, 15, 18, 21' );
		$query->set( 'order', 'ASC' );
    }
}
Modifier la boucle - sélection de catégories

Voici l’affichage correspondant de la page d’accueil :

Modifier la boucle - afficher plusieurs catégories
Modifier la boucle – afficher plusieurs catégories
  • les articles affichés appartiennent aux catégories dont l’identifiant a été indiqué dans le crochet pre_get_posts : $query->set( ‘cat’, ‘3, 15, 18, 21’ )
  • les articles sont affichés en commençant par les plus anciens : $query->set( ‘order’, ‘ASC’ )

En regardant l’objet $query, on constate que deux paramètres ont été modifiés :

cat’ => string ‘3, 15, 18, 21’ (length=13)
‘order’ => string ‘ASC’ (length=3)

Astuce : comment identifier le numéro d’une catégorie ?
Voici comment procéder :

  • se rendre sur la page de gestion des catégories dans l’administration,
  • survoler avec la souris l’option de modification de la catégorie,
  • regarder la valeur de « tag_id » dans l’url qui apparaît.
Modifier la boucle - identifier la catégorie d'article
Modifier la boucle – identifier la catégorie d’article

Ce principe (faire apparaître l’identifiant dans l’url en survolant une option de modification) fonctionne pour d’autres identifiants : étiquette, média…

Afficher tous les articles associés à une étiquette avec tri sur le titre

Code à insérer dans le fichier functions.php du thème actif :

add_action( 'pre_get_posts', 'wpdf_demo_pregetposts', 1 );

function wpdf_demo_pregetposts( $query ) {
	if ( ! is_admin() && $query->is_main_query() && is_home()){	
		$query->set( 'posts_per_page', '-1' );
		$query->set( 'tag_id', '8' );
		$query->set( 'orderby', 'title' );
		$query->set( 'order', 'ASC' );
    }
}
Modifier la boucle - étiquette + nombre d'articles + ordonné sur le titre

Voici l’affichage obtenu :

Modifier la boucle - étiquette, nombre d'articles et tri sur le titre
Modifier la boucle – étiquette, nombre d’articles et tri sur le titre

Paramètres modifiés dans l’objer $query :

‘tag_id’ => string ‘8’ (length=1)
‘posts_per_page’ => string ‘-1’ (length=2)
‘orderby’ => string ‘title’ (length=5)
‘order’ => string ‘ASC’ (length=3)

Il est important de noter la complémentarité des paramètres :

  • order : qui permet de spécifier le sens ascendant ou descendant,
  • orderby : qui permet de spécifier la valeur sur laquelle le tri va s’effectuer.

Par défaut, l’ordre est descendant et s’applique sur la date de publication.

Afficher les articles dans un ordre dépendant d’un champ personnalisé

Commençons par associer un champ personnalisé nommé « ordre » aux articles de la catégorie de démonstration avec pour valeur du champ personnalisé :

  • pour les champs impairs : leur numéro d’article (1 pour l’article 1, 3 pour l’article 3…),
  • pour les articles pairs :  10 plus leur numéro d’article (12 pour l’article 2, 14 pour l’article 4…).

Vérifier que la gestion des champs personnalisés soit bien activée dans les options de l’écran lors de la saisie des articles :

Modifier la boucle - permettre l'affichage des champs personnalisés
Modifier la boucle – permettre l’affichage des champs personnalisés

Créer un champ personnalisé pour chaque article et lui affecter la valeur prévue (exemple de l’article 2) :

Modifier la boucle - saisir un champ personnalisé
Modifier la boucle – saisir un champ personnalisé

Code à insérer dans le fichier functions.php du thème actif :

add_action( 'pre_get_posts', 'wpdf_demo_pregetposts', 1 );

function wpdf_demo_pregetposts( $query ) {
	if ( ! is_admin() && $query->is_main_query() && is_category('21')){	
		$query->set( 'posts_per_page', '4' );
		$query->set( 'orderby', 'meta_value_num' );
		$query->set( 'meta_key', 'ordre' );
    }
}
Modifier la boucle - code pour afficher en fonction d'un champ personnalisé

Remarques :

  • la modification de la boucle n’impacte que la catégorie d’identifiant 21 : is_category(’21’),
  • le nombre d’articles par page est limité à 4 : set( ‘posts_per_page’, ‘4’ ),
  • le tri s’effectue sur le champ personnalisé (meta data) « ordre » : set( ‘meta_key’, ‘ordre’ ),
  • le tri s’effectue sur la valeur numérique : set( ‘orderby’, ‘meta_value_num’ ). Il faut utiliser orderby / meta_value pour un tri alphanumérique.

Voici l’affichage obtenu (les articles pairs apparaissent avant les articles impairs, il n’y a que quatre articles sur la première page et l’ordre, non précisé, est descendant par défaut) :

Modifier la boucle - affichage trié suivant un champ personnalisé
Modifier la boucle – affichage trié suivant un champ personnalisé

Le codex décrit les nombreux paramètres de pre_get_posts. Les exemples qui y sont proposés correspondent à l’utilisation de la classe WP_Query, mais les paramètres disponibles sont identiques, seule la façon de coder est différente.

Haut de page

Query_posts()

La fonction query_posts() permet de modifier la boucle principale.  Elle n’est pas recommandée pour des questions de performance et d’effets de bord qu’il convient de maîtriser (notamment dans la gestion des pages). Il est préférable d’utiliser le crochet pre_get_posts pour modifier la boucle principale.

Voici un code permettant de n’afficher que 2 articles par page :

add_action( 'template_redirect', 'wpdf_demo_queryposts', 1 );

function wpdf_demo_queryposts( ) {
	if ( ! is_admin() && is_main_query() && is_home()){	
		query_posts( 'posts_per_page=2' );
    }
}
Modifier la boucle - query_posts dans un crochet

La page d’accueil n’affiche plus que deux articles du fait de « query_posts( ‘posts_per_page=2’ ) » :

Modifier la boucle - query_posts avec un crochet
Modifier la boucle – query_posts avec un crochet

Remarques :

  • les paramètres disponibles sont les mêmes que pour pre_get_posts,
  • query_posts() déclenche une nouvelle requête dans la base de données alors que pre_get_posts modifie la requête principale avant qu’elle ne soit exécutée, d’où un site plus lent à s’afficher avec query_posts().

Il est possible d’utiliser query_posts() indépendamment d’un crochet, l’essentiel étant de l’insérer avant l’affichage de la boucle principale. Voici un exemple de modification du fichier index.php :

query_posts( 'posts_per_page=3&order=ASC' );
if ( have_posts() ) :
	while ( have_posts() ) : the_post();
		echo("=> ");the_title();echo ('<br/>');
	endwhile;
	wp_reset_query();
endif;
if ( have_posts() ) :
	// Start the Loop.
	while ( have_posts() ) : the_post();
		get_template_part( 'content', get_post_format() );
	endwhile;
Modifier la boucle - utiisation de query_posts

Important : noter l’utilisation de la fonction wp_reset_query() qui permet de repositionner la boucle principale dans son état initial. De ce fait, query_posts() n’affecte que la première boucle.

Voici l’affichage obtenu :

  • d’abord les titres des 3 plus anciens articles : ‘posts_per_page=3&order=ASC‘,
  • puis l’affichage des articles les plus récents  correspondant à l’affichage habituel de la boucle standard.
Modifier la boucle - la fonction query_posts
Modifier la boucle – la fonction query_posts

Astuce : deux écritures sont possibles pour passer les paramètres.

Les deux appels de fonction suivants sont équivalents :

  • query_posts( ‘posts_per_page=3&order=ASC’ );
  • query_posts( array( ‘posts_per_page’ => 3, ‘order’ => ‘ASC’ ) );

La deuxième écriture permet de passer aisément des paramètres dans des tableaux, comme dans l’exemple ci-dessous où on ne retient que les articles appartenant à la fois aux catégories 1 et 3 :

query_posts( array( ‘category__and’ => array(1,3), ‘posts_per_page’ => 2, ‘orderby’ => ‘title’, ‘order’ => ‘DESC’ ) );

Utiliser la query_string

La query_string est la partie de l’adresse web au delà de l’adresse du site qui définit ce que le visiteur souhaite afficher.

Code à insérer dans le fichier category.php du thème actif :

global $query_string;
query_posts( $query_string . '&order=DESC&cat=15' );
Modifier la boucle - utiliser la query_string avec query_posts

Demander l’affichage des articles d’une catégorie aura pour effet de n’afficher que les articles qui sont associés à la fois à cette catégorie et à la catégorie 15 du fait du paramètre « cat=15 » dans query_posts().

Par exemple, voici une url et la query_string correspondante pour l’affichage d’une catégorie :

  • url : http://localhost/demo/sujet/categ_demo/
  • query_string : string ‘category_name=categ_demo’ (length=24)

 Utiliser le tableau query_vars

Les paramètres de requête sont stockés dans le tableau query_vars de l’objet $wp_query.

Code à insérer dans le fichier category.php du thème actif :

global $wp_query;
$args = array_merge( $wp_query->query_vars, array( 'cat' => '15', 'order' => 'DESC') );
Modifier la boucle - modifier query_vars

Ce code a le même effet que le précédant avec la query_string.

Voici les contenus impactés dans l’objet wp_query :

  • issu de l’url : ‘category_name’ => string ‘categ_demo’ (length=10)
  • modifié par le code ci-dessus :
    • ‘cat’ => string ’15’ (length=2)
    • ‘order’ => string ‘DESC’ (length=4)
Haut de page

Laisser un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.