To sort posts by a numeric custom field in descending order using the pre_get_posts
hook, you need to modify the WP_Query
parameters. Here’s an example:
add_action('pre_get_posts', 'custom_sort_posts_by_meta_field');
function custom_sort_posts_by_meta_field($query) {
// Check if this is the main query and, for example, an archive page
if (!is_admin() && $query->is_main_query() && $query->is_archive()) {
$meta_key = 'your_meta_key'; // Replace with your meta field key
$query->set('meta_key', $meta_key);
$query->set('orderby', 'meta_value_num'); // Specify the field is numeric
$query->set('order', 'DESC'); // Sort from highest to lowest
}
}
Explanation:
is_admin()
andis_main_query()
:- These ensure the hook runs only for frontend queries and for the main query (not for secondary queries).
$query->is_archive()
:- This condition checks if the query is for an archive page. You can replace it with other conditions like
is_home()
,is_category()
, or remove it entirely if you want to apply this logic to all frontend queries.
- This condition checks if the query is for an archive page. You can replace it with other conditions like
meta_key
:- Replace
your_meta_key
with the key of the custom field you want to sort by. This is the meta field key you use when saving data withupdate_post_meta
.
- Replace
meta_value_num
:- This tells WordPress to treat the meta field values as numbers rather than strings.
order
:- Specifies the sorting order:
DESC
for descending orASC
for ascending.
- Specifies the sorting order:
Example Use Case:
Suppose you have a custom field price
storing product prices, and you want to sort products by price from highest to lowest. Replace your_meta_key
with price
.
If you need additional conditions (e.g., sorting only for a specific post type), you can add them to the check. For example:
if (!is_admin() && $query->is_main_query() && $query->is_post_type_archive('product')) {
// Sorting code here
}
This will apply sorting only to archive pages for the product
post type.