0

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!!

0

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

  • I want to get all the posts including the sticky ones (behave like a "normal" loop) i do not want to exlude them...please read the question – Dejo Dekic Jan 16 '17 at 16:12
  • Please read the answer ;) It does not exlude the sticky posts just removes the 'sticky behavior' of the sticky posts so the posts will be ordered by date (by default). – rocknrollcanneverdie Jan 16 '17 at 16:18
  • Edited the answer; WordPress' function/variable names can be really confusing. – rocknrollcanneverdie Jan 16 '17 at 16:22
  • LoL this is exactly the problem I do not want to remove the 'sticky behavior' I want to keep it... So when the post is "sticky" it must be on the front page followed by normal posts and then it must be shown in chronologically correct position in time...the second code does that albeit hacky... – Dejo Dekic Jan 16 '17 at 16:24
  • Do you want to show all the sticky posts on the front page or what should happen when the number of the sticky posts > $default_posts_per_page? – rocknrollcanneverdie Jan 16 '17 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.