I am using this code to fetch my posts:
<?php
if ( get_query_var( 'paged' ) ) {
$paged = absint( get_query_var( 'paged' ) );
} elseif ( get_query_var( 'page' ) ) {
$paged = absint( get_query_var( 'page' ) );
} else {
$paged = 1;
}
$default_posts_per_page = get_option( 'posts_per_page' );
$args = array(
'post_type' => 'post',
'posts_per_page' => $default_posts_per_page,
'paged' => $paged,
);
$postslist = get_posts( $args );
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query( $args );
$count = $wp_query->post_count;
?>
<?php foreach( $postslist as $post ) : setup_postdata( $post ); ?>
<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<?php get_template_part( 'template-parts/content', 'three-columns' ); ?>
<?php endforeach; ?>
<?php if ( 0 === $count ) {
get_template_part( 'template-parts/content', 'none' );
} ?>
<?php
wp_reset_postdata(); ?>
<?php
$wp_query = null;
$wp_query = $temp;
?>
It gets my posts without a problem and displays them, but there is just one little thing to take care of...
My sticky posts are nowhere to be found! (they are not displayed on front page).
So my question: Is there a Wordpressy ( non-hacky way ) to get all the posts including the sticky ones?
Basically I want to make this code to behave like a normal loop ( sticky posts on front followed by normal posts and then display sticky post again in their chronologically correct position in time ).
So to make my code behave like normal loop I am using this hacky workaround:
<?php
if ( get_query_var( 'paged' ) ) {
$paged = absint( get_query_var( 'paged' ) );
} elseif ( get_query_var( 'page' ) ) {
$paged = absint( get_query_var( 'page' ) );
} else {
$paged = 1;
}
$default_posts_per_page = get_option( 'posts_per_page' );
$args = array(
'post_type' => 'post',
'posts_per_page' => $default_posts_per_page,
'include' => implode(',', get_option('sticky_posts')),
'paged' => $paged,
);
$args2 = array(
'post_type' => 'post',
'posts_per_page' => $default_posts_per_page,
'paged' => $paged,
);
$postslist = get_posts( $args );
$postslist2 = get_posts( $args2 );
$postslist = array_merge( $postslist, $postslist2 );
$postslist = array_map("unserialize", array_unique(array_map("serialize", $postslist)));
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query( $args );
$count = $wp_query->post_count;
?>
<?php foreach( $postslist as $post ) : setup_postdata( $post ); ?>
<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<?php get_template_part( 'template-parts/content', 'three-columns' ); ?>
<?php endforeach; ?>
<?php if ( 0 === $count ) {
get_template_part( 'template-parts/content', 'none' );
} ?>
<?php
wp_reset_postdata(); ?>
<?php
$wp_query = null;
$wp_query = $temp;
?>
This code now behaves like a normal loop but it feels hacky because as you can see I am using get_posts()
two times ( definitely redundant ) then I am using array_merge()
to merge two get_posts()
into one array
and finally I am removing duplicated posts via array_map()
and array_unique()
.
So I will repeat the question: Is there a better ( Wordpressy/non-hacky ) way to get all the posts including the sticky ones with foreach loop?
Thanks guys!!
I am using this code to fetch my posts:
<?php
if ( get_query_var( 'paged' ) ) {
$paged = absint( get_query_var( 'paged' ) );
} elseif ( get_query_var( 'page' ) ) {
$paged = absint( get_query_var( 'page' ) );
} else {
$paged = 1;
}
$default_posts_per_page = get_option( 'posts_per_page' );
$args = array(
'post_type' => 'post',
'posts_per_page' => $default_posts_per_page,
'paged' => $paged,
);
$postslist = get_posts( $args );
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query( $args );
$count = $wp_query->post_count;
?>
<?php foreach( $postslist as $post ) : setup_postdata( $post ); ?>
<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<?php get_template_part( 'template-parts/content', 'three-columns' ); ?>
<?php endforeach; ?>
<?php if ( 0 === $count ) {
get_template_part( 'template-parts/content', 'none' );
} ?>
<?php
wp_reset_postdata(); ?>
<?php
$wp_query = null;
$wp_query = $temp;
?>
It gets my posts without a problem and displays them, but there is just one little thing to take care of...
My sticky posts are nowhere to be found! (they are not displayed on front page).
So my question: Is there a Wordpressy ( non-hacky way ) to get all the posts including the sticky ones?
Basically I want to make this code to behave like a normal loop ( sticky posts on front followed by normal posts and then display sticky post again in their chronologically correct position in time ).
So to make my code behave like normal loop I am using this hacky workaround:
<?php
if ( get_query_var( 'paged' ) ) {
$paged = absint( get_query_var( 'paged' ) );
} elseif ( get_query_var( 'page' ) ) {
$paged = absint( get_query_var( 'page' ) );
} else {
$paged = 1;
}
$default_posts_per_page = get_option( 'posts_per_page' );
$args = array(
'post_type' => 'post',
'posts_per_page' => $default_posts_per_page,
'include' => implode(',', get_option('sticky_posts')),
'paged' => $paged,
);
$args2 = array(
'post_type' => 'post',
'posts_per_page' => $default_posts_per_page,
'paged' => $paged,
);
$postslist = get_posts( $args );
$postslist2 = get_posts( $args2 );
$postslist = array_merge( $postslist, $postslist2 );
$postslist = array_map("unserialize", array_unique(array_map("serialize", $postslist)));
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query( $args );
$count = $wp_query->post_count;
?>
<?php foreach( $postslist as $post ) : setup_postdata( $post ); ?>
<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<?php get_template_part( 'template-parts/content', 'three-columns' ); ?>
<?php endforeach; ?>
<?php if ( 0 === $count ) {
get_template_part( 'template-parts/content', 'none' );
} ?>
<?php
wp_reset_postdata(); ?>
<?php
$wp_query = null;
$wp_query = $temp;
?>
This code now behaves like a normal loop but it feels hacky because as you can see I am using get_posts()
two times ( definitely redundant ) then I am using array_merge()
to merge two get_posts()
into one array
and finally I am removing duplicated posts via array_map()
and array_unique()
.
So I will repeat the question: Is there a better ( Wordpressy/non-hacky ) way to get all the posts including the sticky ones with foreach loop?
Thanks guys!!
Updated answer:
The default behavior of WP is exactly what you want. The problem is that you are using get_posts()
which completely ignores the sticky post behavior by forcing ignore_sticky_posts = true
(check the source). So you need only one query, just use WP_Query():
$postsList = new WP_Query([
'post_type' => 'post',
'posts_per_page' => $default_posts_per_page,
'paged' => $paged
]);
The sticky posts will be at the top and - if paginated - will be repeated again on pages ordered by their date (default ordering).
To avoid posts' stickiness use 'ignore_sticky_posts' => true
in your query. It does not exclude the sticky posts just removes the 'sticky behavior' so the posts will be ordered by date (default ordering).
new WP_Query([
'post_type' => 'post',
'posts_per_page' => $default_posts_per_page,
'paged' => $paged,
'ignore_sticky_posts' => true
]);
Codex link: https://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters