You can set the orderby to post__in
. Here is a superior post loop:
$args = [
'post__in' => [ 1, 2, 3, 4 ],
'orderby' => 'post__in',
];
$q = new \WP_Query( $args );
if ( $q->have_posts() ) {
while ( $q->have_posts() ) {
$q->the_post();
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php the_title(); ?>
</article>
<?php
}
wp_reset_postdata();
} else {
echo '<p>No posts found</p>';
}
Important changes:
get_posts
does not fire all the loop lifecycle filters, bypasses caches by default (suppress_filters
is set to true inget_posts
), and doesn’t set the current post for you. It also usesWP_Query
internally, so I cut out the middleman and usedWP_Query
directly. This loop is both faster, more expandable, and more compatible- I removed
numberposts
andpost_type
, these are unnecessary and would actually slow down the query if WP used them. WP knows which posts you want viapost__in
so it’ll just fetch those orderby
is set topost__in
so posts will appear in the same order they’re requested- I used a PHP array instead of using
explode
on a string ( which gives the same result so why do the extra work? ) - I used
the_ID
andpost_class
so the inner loops tags would have the appropriate classes
I strongly recommend you read through this document: https://developer.wordpress.org/reference/classes/wp_query/ it will save a lot of time in the future and has a lot of examples.