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étique, 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 par défaut de WordPress. C’est parti !
Liste de contenu
1. 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 Kinsta, je vous recommande d’y jeter un œil si vous n’êtes pas familiers avec les thèmes enfants.
2. 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 montrer uniquement 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.
Comme vous pouvez le constater, cela manque de style. Résolvons ce problème 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;
}
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.
3. Modifier la requête
Sélectionnons « trier par titre », « ascendant » et « posts avec vignettes » et soumettons la formule. Vous devriez constater un changement, sans rien faire au niveau du code.
Pour comprendre pourquoi, inspectons l’URL. Il devrait être de cette façon :
https://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 comprend pas nos intentions. Ainsi, 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 considéré. Faisons-le à présent 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 lots 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.
4. 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 donnerait 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 que l’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.
5. 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 : https://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 rencontrons une difficulté :
Si “pretty permalink” est activé (ce qui devrait être le cas), la page a été redirigée vers un nouvel URL, surement celui-là 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ée là-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.
Si vous avez des questions à propos de ce projet, posez-les dans les commentaires.
Webmaster depuis plus de 18 ans. J’ai pu développer plusieurs expertises dans le domaine de la création et l’hébergement de site Web.
Je me suis intéressé aussi au référencement de site Web « SEO ». Il s’agit d’un domaine plein de défi dans lequel tout le monde essais de suivre les recommandations infinies de Google.