-1

I'm stuck with the related posts querying. I need the related posts to be displayed with any depth from the main parent. I have the following structure categories on my website:

- Category level 1
-- Category level 2
--- Category level 3
*---- Post in level 3*
--- Category level 3
*--- Post in level 3*
-- Category level 2
-- Category level 2

When we looking at the *---- Post in level 3* we must see any post from the *-- Category level 2* ie all the posts that contain this level including child.

Here is my code:

<div class="related_goods">
<span>Related posts:</span>
    <?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,
    'orderby'=>title,
    'post_parent'=> array(),
    'caller_get_posts'=>1);
    $my_query = new wp_query($args);
    if( $my_query->have_posts() ) {

    while ($my_query->have_posts()) {
    $my_query->the_post();
    ?>
    <div class="block-related-item">
        <div class="preview-wrap">
            <div class="preview">
                <? $thumb_url = wp_get_attachment_url(get_post_thumbnail_id($post->ID)); ?>
                <a href="<?php the_permalink() ?>"><? the_post_thumbnail('category_thumbs'); ?>
                </a>
            </div>
            <a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a>
        </div>          
    </div>
    <?php
    }
    }
    wp_reset_query();
    }
    ?>
</div>

How can I modify it to obtain the above effect? Thanks a lot in advance!

7
  • With the code above, what's the issue you're having? What's it outputting that isn't what you're expecting?
    – Howdy_McGee
    Jul 2, 2015 at 21:55
  • I'm getting posts from the same level category. But I need some of all 2nd level category posts.
    – Alex P.
    Jul 2, 2015 at 21:58
  • Not sure what exactly you want, but post_parent should be an integer - 0 or 1. Are you sure you're not looking for post_parent__in?
    – lucian
    Jul 2, 2015 at 22:18
  • Lucian, my mistake and experiments with post_parent. If it's 1 — output nothing, when it's 0 — there are posts from the sam deep category.
    – Alex P.
    Jul 3, 2015 at 5:06
  • post_parent__in — good idea, but I m using one template to all categories.
    – Alex P.
    Jul 3, 2015 at 5:19

1 Answer 1

2

parent is your answer here. Every term have a parent value set in its parent property. This value is an integer value, and represent the term id of its parent term. All top level terms have a value of 0 which just simply means it is a top level term

First we need to build an array with parent terms and the specific terms from get_the_category. We will skip 0 values. Once we have our array of ids, we will get all unique values and pass the array of ids to a tax_query in order to save on multiple queries

(The following code is untested and require PHP 5.4+)

function get_related_category_posts()
{
    // Check if we are on a single page, if not, return false
    if ( !is_single() )
        return false;

    // Get the current post id
    $post_id = get_queried_object_id();

    // Get the post categories
    $categories = get_the_category( $post_id );

    // Lets build our array
    // If we don't have categories, bail
    if ( !$categories )
        return false;

    foreach ( $categories as $category ) {
        if ( $category->parent == 0 ) {
            $term_ids[] = $category->term_id;
        } else {
            $term_ids[] = $category->parent;
            $term_ids[] = $category->term_id;
        }
    }

    // Remove duplicate values from the array
    $unique_array = array_unique( $term_ids );

    // Lets build our query
    $args = [
        'post__not_in' => [$post_id],
        'posts_per_page' => 3, // Note: showposts is depreciated in favor of posts_per_page
        'ignore_sticky_posts' => 1, // Note: caller_get_posts is depreciated
        'orderby' => 'title',
        'no_found_rows' => true, // Skip pagination, makes the query faster
        'tax_query' => [
            [
                'taxonomy' => 'category',
                'terms' => $unique_array,
                'include_children' => false,
            ],
        ],
    ];
    $q = new WP_Query( $args );
    return $q;
}

You can then use the code as follows in your single post page

$q = get_related_category_posts();
if ( $q->have_posts() ) {
    while ( $q->have_posts() ) {
    $q->the_post();

        // Your loop

    }
    wp_reset_postdata();
}
3
  • I think this code needs testing. Jul 3, 2015 at 16:01
  • @BradDalton jip, I know. Had a really rough week, so I could really not test everything I have posted. Thanks for the edit though Jul 3, 2015 at 16:38
  • No problem. Good code that i'll find useful. Jul 3, 2015 at 16:42

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.