0

What I'm able to do :

When there is a sticky post in the current category, I'm already able to display it. The problem occurs when there is no sticky post : it doesn't display the latest post as it should do (actually id doesn't display anything).

It works like a charm on the Home page : when there is a sticky post, it displays it, and where there is no sticky post, it displays the latest post.

Here is my code :

<?php
$current_object = get_queried_object_id(); // Get the category ID and store it in a variable

    // Display sticky post or latest post :
    $args = array(
      'posts_per_page'      => 1,
      'post__in'            => get_option( 'sticky_posts' ),
      'cat'                 => $current_object, // Current category ID 
      'ignore_sticky_posts' => true,
    );
    $featured_query = new WP_query( $args );

    if ( $featured_query->have_posts() ) : ?>

      <div class="featured-post">

        <?php
        while ( $featured_query->have_posts() ) :
          $featured_query->the_post();

          the_title('<h2>', '</h2>');
          the_excerpt();

        endwhile;
        wp_reset_postdata();
        ?>

      </div>

    <?php endif; ?>

What I want to achieve :

I want my category page to display the sticky post that belongs to this category if it exists, and if not, I want that the category page displays the latest post published in this category.

What am I missing ?

6
  • Why do you use both post__in and ignore_sticky_posts?
    – kero
    Jan 31, 2022 at 12:36
  • Yeah I know, it can seems counter-intuitive, but if I'm not misunderstanding it, it's not. It's only a way to make the query lighter : as I'm asking to WordPress in this query to display only the sticky post (and that's what this setting : 'post__in' => get_option( 'sticky_posts' ) is doing), I don't need the behavior of putting in top of the results the sticky post, and that's what ignore_sticky_posts does by default (the setting is set to false), even if we wrongly think that ignore_sticky_posts excludes the sticky post. I hope I'm clear.
    – PhpDoe
    Jan 31, 2022 at 12:51
  • 1
    It might be "a way to make the query lighter" but it breaks the functionality - as you just realized. Basically your code is saying "give me the top 1 sticky post (of this category)". Now if there is none, you get none - exactly what is supposed to happend. So either create another query, or revert back to the old format. You can't have the benefit of light query combined with complex functionality in this case.
    – kero
    Jan 31, 2022 at 12:57
  • @PhpDoe just a note that if you want to change the main WordPress query, use a hook like pre_get_posts and then simply use The Loop (while ( have_posts() )) to display the posts already fetched by the main query. You don't need to make secondary query (new WP_query) and loop (while ( $featured_query->have_posts() )). ✌ If you're just adding an additional posts section on the page, then secondary query/loop is fine.
    – Sally CJ
    Feb 1, 2022 at 2:39
  • @kero : I think I'm missing the point. What should I do ? If I remove 'post__in' => get_option( 'sticky_posts' ), I get the latest post when there is no sticky post, but I don't get the sticky post where there is one. If I remove 'ignore_sticky_posts' => true, I get the sticky post when there is one, but I don't get the latest post when there is no sticky post. My code is perfectly working on the Home Page (home.php), that's what I can't understand : I have the sticky post when there is one, and the latest when there is no sticky post…
    – PhpDoe
    Feb 1, 2022 at 11:15

1 Answer 1

1

This code is certainly not perfect but it actually does the job :

<?php
// Store the current category ID :
$current_object = get_queried_object_id();

// Get sticky post :
$args = array(
  'posts_per_page'      => 1,
  'post__in'            => get_option( 'sticky_posts' ),
  'cat'                 => $current_object,
  'ignore_sticky_posts' => true,
);
$sticky_query = new WP_query( $args );

// Get latest post :
$args = array(
  'posts_per_page'      => 1,
  'cat'                 => $current_object,
  'ignore_sticky_posts' => true,
);
$latest_query = new WP_query( $args );

// If there is a sticky post in the current category :
if ( $sticky_query->have_posts() ) : ?>

  <div class="sticky-post">

    <?php
    while ( $sticky_query->have_posts() ) :
      $sticky_query->the_post();

      the_title();

    endwhile;
    wp_reset_postdata();
    ?>

  </div>

<?php
// If there is no sticky post, display the latest published post :
elseif ( $latest_query->have_posts() ) : ?>

  <div class="latest-post">

    <?php
    while ( $latest_query->have_posts() ) :
      $latest_query->the_post();
      
      the_title();

    endwhile;
    wp_reset_postdata();
    ?>

  </div>

<?php endif; ?>

There is two queries here. The first one to get and display the sticky post that belongs to the current category, the second one to get and display the latest post in the same category (if there is no sticky post to display).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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