If you need to:
-
page the query
-
retain 12 posts per page instead of “sticking” the desired posts on top of the required 12
-
only need to show those posts on the first page
you can try the following
$ids_args = [
'post_type' => 'products'
'posts_per_page' => -1,
'orderby' => 'meta_value_num',
'meta_key' => '_price',
'order' => 'ASC',
'fields' => 'ids'
];
$all_posts_ids = get_posts( $ids_args );
// Make sure we have posts before continuing
if ( $all_posts_ids ) {
// Set all our posts that should move to the front
$move_to_front = [12,13,14,34];
// Add the array of posts to the front of our $all_posts_ids array
$post_ids_merged = array_merge( $move_to_front, $all_posts_ids );
// Make sure that we remove the ID's from their original positions
$reordered_ids = array_unique( $post_ids_merged );
// Now we can run our normal query to display 12 posts per page
$args = [
'post_type' => 'products'
'posts_per_page' => 12,
'post__in' => $reordered_ids,
'orderby' => 'post__in',
'order' => 'ASC',
'paged' => get_query_var( 'paged', 1 ),
];
$loop = new WP_Query( $args );
while( $loop->have_posts() ) {
$loop->the_post();
the_content();
}
wp_reset_postdata();
}
If you need these posts
-
to stick on top of the 12 posts on every page
-
in a paged query
you can run two queries as follow
// Set an array of id's to display in front
$move_to_front = [12,13,14,34];
// Run the query to display the posts you need in front
$args_front = [
'post_type' => 'products'
'posts_per_page' => count( $move_to_front ),
'post__in' => $move_to_front,
'orderby' => 'meta_value_num',
'meta_key' => '_price',
'order' => 'ASC',
];
$loop_front = new WP_Query( $args_front );
if( $loop_front->have_posts() ) {
while( $loop_front->have_posts() ) {
$loop_front->the_post();
the_content();
}
wp_reset_postdata();
}
// Now we can run our major loop to display the other posts
$args = [
'post_type' => 'products'
'posts_per_page' => 12,
'post__not_in' => $move_to_front,
'orderby' => 'meta_value_num',
'meta_key' => '_price',
'order' => 'ASC',
'paged' => get_query_var( 'paged', 1 ),
];
$loop = new WP_Query( $args );
if( $loop->have_posts() ) {
while( $loop->have_posts() ) {
$loop->the_post();
the_content();
}
wp_reset_postdata();
}
If you only need one page with those posts in front, then the solution by @birgire will do the job just fine