90 000 avant 100 000, mais aussi avant 9 000 : voilà ce que produisait le tri « prix croissant » d’un site vitrine pour un réseau d’agences immobilières indépendantes, avant que le développeur précédent ne me transmette le dossier. Le prix de chaque bien était stocké en champ personnalisé, trié avec orderby => 'meta_value', un paramètre qui compare les valeurs comme des chaînes de caractères plutôt que comme des nombres.
Le symptôme est trompeur : le tri fonctionne, dans le sens où il classe les biens dans un certain ordre, mais cet ordre est celui de la comparaison alphabétique d’une chaîne. « 90000 » est « plus petit » que « 100000 » alphabétiquement, car le caractère « 9 » vient après « 1 » dans la comparaison caractère par caractère, mais dès le deuxième caractère la comparaison bascule différemment selon la longueur des chaînes. Le résultat paraît aléatoire à qui ne connaît pas la cause exacte.
Le tri fautif, tel qu’il apparaissait dans le thème
Voici la requête d’origine, qui illustre parfaitement le piège : elle ne produit aucune erreur, aucun avertissement, elle retourne simplement un ordre incorrect, ce qui la rend difficile à repérer sans comparer manuellement les prix affichés.
$biens = new WP_Query( array(
'post_type' => 'bien',
'meta_key' => 'prix_bien',
'orderby' => 'meta_value',
'order' => 'ASC',
'posts_per_page' => 20,
) );
La correction : meta_value_num
Le paramètre orderby accepte la valeur meta_value_num, qui indique explicitement à WordPress de convertir les valeurs en nombre avant de les comparer. C’est un changement d’un seul mot, mais qui suffit à corriger entièrement le classement.
$biens = new WP_Query( array(
'post_type' => 'bien',
'meta_key' => 'prix_bien',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'posts_per_page' => 20,
) );

Pourquoi le type de champ compte autant que le paramètre orderby
Corriger le paramètre orderby ne suffit pas si le champ lui-même contient des valeurs incohérentes : un prix enregistré une fois comme 250000 et une autre fois comme 250 000 avec un espace, ou 250000€ avec le symbole monétaire, casse le tri numérique tout autant qu’un mauvais paramètre. La discipline de saisie compte autant que la requête.
add_action( 'save_post_bien', function ( $post_id ) {
if ( isset( $_POST['prix_bien'] ) ) {
$prix = preg_replace( '/[^0-9]/', '', $_POST['prix_bien'] );
update_post_meta( $post_id, 'prix_bien', absint( $prix ) );
}
} );
Cette normalisation à l’enregistrement garantit que le champ ne contiendra jamais que des nombres entiers purs, condition indispensable pour que meta_value_num fonctionne de façon fiable sur l’ensemble du catalogue.
Comparer les deux comportements sur un cas concret
| Prix stockés | Ordre avec meta_value | Ordre avec meta_value_num |
|---|---|---|
| 9 000, 90 000, 100 000 | 100 000, 9 000, 90 000 | 9 000, 90 000, 100 000 |
| 1 200, 850, 15 000 | 1 200, 15 000, 850 | 850, 1 200, 15 000 |
Ce tableau, présenté tel quel à l’équipe du réseau d’agences, a suffi à convaincre que le problème ne venait ni du contenu des fiches ni d’un bug d’affichage, mais bien d’un choix de paramètre à corriger une fois pour toutes.
Étendre le tri numérique à d’autres champs
Une fois le principe compris, plusieurs autres champs du même site méritaient la même correction, chacun avec sa propre logique de tri :
- La surface habitable, souvent triée par erreur comme du texte pour les mêmes raisons que le prix.
- Le nombre de pièces, un champ court où l’erreur passe presque inaperçue tant que le catalogue reste petit, mais qui devient visible dès qu’il dépasse neuf pièces.
- La date de disponibilité du bien, qui nécessite en revanche
orderby => 'meta_value'avec un formatYmd, car un tri numérique sur une date écrite autrement produirait un résultat tout aussi faux.
Un tri qui ne renvoie jamais d’erreur mérite d’être vérifié aussi souvent qu’un tri qui plante : l’absence de message ne garantit jamais l’exactitude du résultat.
Notre verdict
Le paramètre meta_value_num de WP_Query existe depuis les premières versions de l’API des requêtes personnalisées et ne nécessite strictement aucune extension tierce. Le vrai travail consiste à garantir que les données stockées restent des nombres purs, faute de quoi même le bon paramètre de tri ne produira pas le résultat attendu. Ce dossier ne traite volontairement pas la pagination du listing, qui repose sur une logique distincte, à combiner avec ce tri une fois celui-ci corrigé.