0

How can I put a loop in my single.php that shows the posts of the current category of the single and following the code structure that I have? The question comes, because I can not find the correct code.

I have tried with this code

<?php
 $categories = get_the_category($post->ID);
 if ( $categories ) {
 $category_ids = array();
 foreach ( $categories as $individual_category ) {
    $category_ids[] = $individual_category->term_id;
 }
$args=array(
    'category__in' => $category_ids,
    'post__not_in' => array($post->ID),
    'showposts'=>3, // Number of related posts that will be shown.
    'ignore_sticky_posts'=>1
);
$my_query = new wp_query( $args );
if( $my_query->have_posts() ) {

    echo '<h3>Related Articles</h3>'; // You can edit this
    echo '<ul>';

    while ($my_query->have_posts()) {
        $my_query->the_post();
        ?>
        <!-- do stuff -->

        <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>

        <?php
    }

    echo '</ul>';

 }
}
?>

But as is obvious, this would only give me the category with ID number 3, and I need it to be the same as the single post that is being viewed.

Thanks

-EDIT-

This is my full single.php code

<div class="container">
<div id="breadcrumbs">
    <?php if (function_exists('nav_breadcrumb')) nav_breadcrumb(); ?>

</div>


<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

    <div class="single">
        <div class="columns is-centered">
            <div class="column is-two-fifths is-content">
                <?php the_post_thumbnail(); ?>
                <div class="title">
                    <?php the_title(); ?>
                </div>
            </div>
        </div>
    </div>
    <?php the_content(); ?>
<?php endwhile; endif; ?>

<hr/>

<?php
$categories = get_the_category($post->ID);
if ($categories) {
    $category_ids = array();
    foreach ($categories as $individual_category) {
        $category_ids[] = $individual_category->term_id;
    }
    $args = array(
        'category__in' => $category_ids,
        'post__not_in' => array($post->ID),
        'showposts' => 3, // Number of related posts that will be shown.
        'ignore_sticky_posts' => 1
    );
    $my_query = new wp_query($args);
    if ($my_query->have_posts()) {

        echo '<h3>Related Articles</h3>'; // You can edit this
        echo '<ul>';

        while ($my_query->have_posts()) {
            $my_query->the_post();
            ?>
            <!-- do stuff -->

            <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>

            <?php
        }

        echo '</ul>';

    }
}
?></div>
  • Can you please share full source code? – Bhupen Jul 12 at 6:53
  • for single.php? – Dario B. Jul 12 at 6:53
  • Yes, I want to check how you have implemented. Because i have tried this code and it is working at my end. – Bhupen Jul 12 at 7:00
  • @DarioB. shows the posts of the current category of the single. It was about displaying the title of posts from any category that is assigned to the currently displayed post? – nmr Jul 12 at 7:05
  • @Bhupen now is my full code in the post – Dario B. Jul 12 at 7:07
1

I suggest the following:

$categories   = get_the_category();
$category_ids = wp_list_pluck( $categories, 'term_id' );

$args = [
    'numberposts'  => 4,
    'category__in' => $category_ids,
];

$related_posts = get_posts( $args );
$related_posts = wp_list_filter( $related_posts, [ 'ID' => get_queried_oject_id() ], 'NOT' );

if ( count( $related_posts > 3 ) ) {
    array_pop( $related_posts );
}

global $post;

foreach ( $related_posts as $post ) {
    setup_postdata( $post );

    // Output posts.
}

wp_reset_postdata();

Note the following points about the code:

  1. I use wp_list_pluck() to get the category IDs in a single line.
  2. I don't use post__not_in. This has known performance issues. Instead I query for 1 more post than we need so that we can remove the current post later if it appears in the results. This will be faster than using post__not_in.
  3. I use get_posts() instead of WP_Query. This is because it has more appropriate defaults for secondary queries (such as setting ignore_sticky_posts and no_found_rows to true.
  4. Once we have results I use wp_list_filter() to remove the current post, if it appears in the results. I do this by using get_queried_oject_id() to get the ID of the current post. If it doesn't appear in the results then I use array_pop() to remove the last post to get back down to 3 posts.
-1

If you are trying to get "Related Posts" by category for custom taxonomy then see the code given below:

$categories = get_the_terms($post->ID, 'your-taxonomy-name');
if ($categories) {
$category_ids = array();
foreach ($categories as $individual_category) {
    $category_ids[] = $individual_category->term_id;
}
$args = array(
    'post_type' => 'your-post-type',
    'post__not_in' => array($post->ID),
    'showposts' => 3, // Number of related posts that will be shown.
    'ignore_sticky_posts' => 1,
    'tax_query' => array(
        array(
            'taxonomy' => 'your-taxonomy-name',
            'field' => 'id',
            'terms' => $category_ids,
            'operator'=> 'IN'
        )
    ),
);
$my_query = new wp_query($args);

Replace "your-taxonomy-name" and "your-post-type" with valid data.

  • With a large number of posts, post__not_in will kill performance. – Jacob Peattie Jul 12 at 7:28
  • But this is for single page so it will have only single post to include in post__not_in – Bhupen Jul 12 at 7:30
  • I mean a total number of posts in the database.There was a question here not that long ago where somebody's site was extremely slow because a plugin was querying related posts like this. post__not_in is very inefficient. It'd be more performant to just remove the post from the results than to query with post__not_in. – Jacob Peattie Jul 12 at 7:35
  • I do not think this is the solution, because I am forced to assign a specific category, and what I need is to see all the posts in the current category. – Dario B. Jul 12 at 7:51
  • This is not for assigning a category. You can try this and check. – Bhupen Jul 12 at 8:35

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.