Home » Blog » Ajouter des filtres dans les articles de wordpress

Ajouter des filtres dans les articles de wordpress

Une demande à laquelle je fais souvent face concerne les utilisateurs et leur capacité à filtrer, ou trier, les posts sur leurs propres pages web.

Peut-être que les utilisateurs veulent voir les articles par ordre alphabétiques, ou peut être juste voir les posts affichant une vignette ? Il est pertinent de faire ça pour les articles normaux mais cela peut l’être encore plus pour des produits, des photos ou d’autres types de contenu.

Dans le projet WordPress de ce weekend, je vais vous donner des conseils rapides sur comment mettre en place ce genre de chose avec le thème 2015. C’est parti !

Créer un thème enfant

Comme d’habitude, vous avez besoin d’un thème enfant. Vous trouverez un guide pour les thèmes enfants sur WPMU DEV, je vous recommande d’y jeter un œil si vous n’êtes pas familiers avec les thèmes enfants.

Créer les contrôles

Ajoutons trois contrôles : un pour trier les posts, un pour régler le sens du tri et un pour ne montrer que les articles avec une vignette.

Le premier pas est de copier le thème parent index.php dans le thème enfant.

Ouvrez le dossier index.php dans votre thème enfant et collez le HTML qui suit dans le conteneur principal (qui devrait être à la ligne 20) :

<div class='post-filters'>
<select name="orderby">
<option value='post_date'>Order By Date</option>
<option value='post_title'>Order By Title</option>
<option value='rand'>Random Order</option>
</select>
<select name="order">
<option value='DESC'>Descending</option>
<option value='ASC'>Ascending</option>
</select>
<select name="thumbnail">
<option value='all'>All Posts</option>
<option value='only_thumbnailed'>Posts With Thumbnails</option>
</select>
</div>

Voici à quoi cela ressemble sur la page.

Ajouter un filtre de postes dans wordpress

Comme vous pouvez le constater, cela manque de style. Résolvons ce problème en en y ajoutant à la feuille de style :

.post-filters {
margin: 0 8.3333% 8.3333% 8.3333%;
box-shadow: 0 0 1px rgba(0, 0, 0, 0.15);
padding:22px;
background: #fff;
}

Filtre avec feulle de style

Une réaction que j’entends souvent de la part des nouveaux en programmation est la suivante: « comment savait-il que c’est le style qui correspond au thème ? »

La solution est très simple : je triche. J’utilise les outils de développement dans Chrome pour inspecter les éléments normaux de l’article. Dans ce cas précis, il me laisse voir comment sont les ombres et les marges dans les éléments et j’applique tout simplement ces règles à mes propres éléments.

Modifier la requête

Sélectionnons « trier par titre », « ascendant » et « posts avec vignettes » et soumettons la formule. Vous devriez voir un changement, sans rien faire au niveau du code.

Pour comprendre pourquoi, inspectons l’URL. Il devrait être comme ça :

http://votresite.com/?orderby=post_title&order=DESC&thumbnail=only_thumbnailed

La bribe d’information peut être récupérée dans notre script PHP en utilisant la variable $_GET. WordPress sait déjà ce qui est trié et ce que signifient les paramètres de tri, et il les utilise dans la requête par défaut. Ainsi, si nous n’avons besoin que de trier et du sens du tri, le travail est déjà fini.

Tout ça est très bien mais, comment je savais ça ? J’aurai pu utiliser « order_by » comme paramètre au lieu de « orderby ». Dans ce cas, WordPress ne comprends pas nos intentions. J’ai jeté un œil à la documentation sur WP_Query dans le Codex WordPress où il y a un paquet de paramètres, et dont plusieurs peuvent être utilisés dans les URL.

Maintenant, mettons en place notre paramètre vignette. Un post a une vignette s’il a des métadonnées avec la clé _thumbnail_id qui lui sont associés. Nous allons devoir modifier notre requête pour être certain que ce soit pris en compte. Faisons le maintenant avec quety_posts().

Collez le code suivant au-dessus de la fonction get_header() en haut du fichier :

global $wp_query;
$modifications = array();
if( !empty( $_GET['catname'] ) && $_GET['thumbail'] == 'only_thumbnailed' ) {
 $modifications['meta_query'][] = array(
 'key' => '_thumbnail_id',
 'value' => '',
 'compare' => '!='
 );
}
$args = array_merge( 
 $wp_query->query_vars, 
 $modifications 
);
query_posts( $args );

Nous associons les paramètres de la requête originelle avec notre nouveau paramètre, ce qui résulte en différents lot d’articles. Notre formule fonctionne mais il ne se souvient pas de notre sélection. Résolvons ça en réécrivant notre formule et en utilisant un peu de PHP.

Formules plus futées

En plus de lister toutes les options de tri via le sélectionneur, nous devons trouver un moyen d’indiquer lequel est sélectionné. Si nous devions faire cela sans boucle, ça donnerai quelque chose comme ça :

<option value='post_date' <?php if( ( !empty( $_GET['orderby'] ) && $_GET['orderby'] == 'post_date' ) || empty( $_GET['orderby'] ) ) echo "selected='selected'" ?>>Order By Date</option>
<option value='post_title' <?php if( ( !empty( $_GET['orderby'] ) && $_GET['orderby'] == 'post_title' ) ) echo "selected='selected'" ?>>Order By Title</option>
<option value='rand' <?php if( ( !empty( $_GET['orderby'] ) && $_GET['orderby'] == 'rand' ) ) echo "selected='selected'" ?>>Random Order</option>

Vous y comprenez quelque chose ? Moi non plus! Enfin si, mais je ne vous en veux pas. Pour chaque option, nous vérifions si la valeur sélectionnée est égale à la valeur de l’option. Si oui, on en extrait la propriété sélectionnée. Rendons ça plus propre avec une boucle :

<select name="orderby">
 <?php
 $orderby_options = array(
 'post_date' => 'Order By Date',
 'post_title' => 'Order By Title',
 'rand' => 'Random Order',
 );
 foreach( $orderby_options as $value => $label ) {
 echo "<option ".selected( $_GET['orderby'], $value )." value='$value'>$label</option>";
 }
 ?>
</select>

C’est un peu plus long mais simplement parce qu’on a trois options. C’est un bien meilleur format pour gérer toute sorte de sélection. Étendons-le à l’ensemble de la formule :

<form class='post-filters'>
 <select name="orderby">
 <?php
 $orderby_options = array(
 'post_date' => 'Order By Date',
 'post_title' => 'Order By Title',
 'rand' => 'Random Order',
 );
foreach( $orderby_options as $value => $label ) {
 echo "<option ".selected( $_GET['orderby'], $value )." value='$value'>$label</option>";
 }
 ?>
 </select>
 <select name="order">
 <?php
 $order_options = array(
 'DESC' => 'Descending',
 'ASC' => 'Ascending',
 );
 foreach( $order_options as $value => $label ) {
 echo "<option ".selected( $_GET['order'], $value )." value='$value'>$label</option>";
 }
 ?>
 </select>
 <select name="thumbnail">
 <?php
 $order_options = array(
 'all' => 'All Posts',
 'only_thumbnailed' => 'Posts With Thumbnails',
 );
 foreach( $order_options as $value => $label ) {
 echo "<option ".selected( $_GET['thumbnail'], $value )." value='$value'>$label</option>";
 }
 ?>
 </select>
 <input type='submit' value='Filter!'>
</form>

Voilà. La formule devrait maintenant se souvenir de nos sélections basées sur les variables $_GET dans l’URL.

Comportement de WordPress

Vous vous souvenez lorsque j’ai mentionné que je savais qu’il fallait utiliser « trier » et « trier par » parce que j’avais regardé dans la documentation WP_Query ? C’est un bon entrainement mais cela peut mener à des résultats inattendus. Trouvez le lien de l’une de vos catégories, et disons que cette catégorie est « wordpress ». Maintenant, utilisez l’URL suivant : http://votresite.com/?category_name=wordpress. Vous devriez voir vos archives de cette catégorie, listant tous vos articles WordPress. C’est très bien, mais nous avons un problème :

Si pretty permalink est activé (ce qui devrait être le cas), la page a été redirigée vers une nouvel URL, surement celui la https://votresite.com/category/wordpress. Notre filtre ne sera pas visible parce que c’est le fichier archive.php qui gère ceci, et non pas index.php. En outre, le nom de notre catégorie n’est pas passé comme un paramètre URL donc on va devoir utiliser un tour de passe-passe pour que notre filtre marche.

Une manière rapide pour que ça marche est de délibérément ne pas utiliser le même paramètre que WordPress utilise. Vous pouvez faire passer le nom de la catégorie en utilisant le paramètre catname dans l’URL car WordPress ne va pas le remarquer. Vous pouvez ensuite intégrer ça dans votre requête, en utilisant le nom correct du paramètre. Quelque chose comme ça :

global $wp_query;
$modifications = array();
if( !empty( $_GET['catname'] ) ) {
$modifications['category_name'] = $_GET['catname']; 
$args = array_merge(
$wp_query->query_vars, 
$modifications
); 
query_posts( $args );

 

L’alternative serait d’utiliser une fonction au lieu de délivrer notre formule dans index.php. Vous aurez besoin de trouver la catégorie de la requête WordPress elle-même et d’afficher la sélection actuelle basé la dessus.

Conclusion

Ajouter vos propres filtres n’est pas si difficile mais demande un peu de magouille. Dans notre cas, vous voulez peut être faire en sorte que la pagination soit enlevée lorsque l’ordre est réglé sur aléatoire. Cela pourrait être remplacé par un bouton « encore plus d’aléatoire », qui chargerait simplement la page une fois de plus.

J’espère que cet article vous a donné les bases pour que vous puissiez faire cela vous-même et pour que vous soyez capable de construire vos propres filtres en fonction de vos besoins.

Article original de: Daniel Pataki

Si vous avez des questions à propos de ce projet, n’hésitez pas à les poser dans les commentaires.

Check Also

Quand utiliser Ajax et quand ne pas le faire

On n’a jamais été un grand fan de JavaScript mais on a toujours été ravi …