How to get the category on single.php to use in a query to pull in similar posts
-
I want to pull in the recent posts by category when on a single post page. I am still a little hazy on how to use $post but I tried the following which did not work:
$post = get_post(); if ( $post ) { $categories = get_the_category( $post->ID ); }
I got that off of the developer’s page for get_the_category. Then inside the loop, I tried
$query = new WP_Query( [ 'post__not_in' => get_option( 'sticky_posts'), 'post_type' => 'post', 'category_name' => $categories, 'posts_per_page' => 3, ] );
…plus the rest of the code. All I got was the 3 most recent posts. I assume I have to store in a variable the category of the current post and somehow use it as a parameter in WP_Query. A link to a blog post or some other page would be appreciated.
-
Once again, you are trying to do plugin stuff in the theme, although many themes contain code to show related posts at the bottom of the single post page.
You can use a plugin which does this regardless of theme, or you can look at themes that do it and copy the code. But it should not be in the standard loop.The main query is handled by the theme in the standard loop. Anything else either calls functions that are passed the post ID or they make a new loop with a reset_post_data at the end. The pagination, sidebars, and footer areas can contain things that rely on the main query, so it has to be maintained.
If you reread https://developer.www.ads-software.com/reference/functions/get_the_category/ you will see that it returns an array of objects, so you can’t just pass the whole thing into ‘category_name’.
You might want to use https://developer.www.ads-software.com/reference/functions/wp_get_recent_posts/
or https://developer.www.ads-software.com/reference/functions/get_posts instead.Let me check out those links. I’ll put all these things into a plugin once I learn how to create plugins for them, but I don’t have time for that right now. This is pretty much the last feature I want then I can get back to creating content and working on the overall design.
About $post — it depends on the variable’s scope. You could use $post locally in a custom function for whatever you want. But if you declare it global, it should contain the current post’s WP_Post object. What is current depends on the context. It’s normally set in the standard main loop when
the_post()
is called, along with several other post related globals. If you’re running a secondary foreach loop, you can set equivalent variables withsetup_postdata()
. If you do that, also callwp_reset_postdata()
when you’re done looping to restore the original state.
https://developer.www.ads-software.com/reference/functions/setup_postdata/
Note the last paragraph under More Information. The main reason to setup post data is so typical template tags like the_title() or the_content() work correctly in secondary loops.I have wp_reset_postdata at the end. I looked at a lot of links and I didn’t really see how to grab the category of the single post that I’m on and then use that to pull recent posts in that category. I’ll have to go through the 100;s of pages in my notes because I know I saw it done at some point.
Appearing to be knowledgeable is largely a matter of knowing where to find the answers ??
I’ve done something like this before:$cats = wp_get_post_categories( get_the_ID(), ['fields'=>'ids',]); $related = get_posts( [ 'numberposts'=> 3, 'category'=> implode(',', $cats), 'post__not_in'=> [get_the_ID(),], ]); global $post; echo "<h3>Related Posts</h3>\n"; if ( $related ) { foreach ( $related as $post ) { setup_postdata( $post ); the_title(); echo "<br>\n"; } wp_reset_postdata(); } else { echo "Nothing related was found<br>\n"; }
Lists the 3 most recent posts having any of the categories assigned to the current post. I leave making the title into a proper link for you to do.
So you prefer to use get_posts over WP_Query even though get_post uses or calls (or whatever the correct phrase is) WP_Query? I thought for that reason it would be best to get out the middle man so to speak and use wp_query.
I was able to print_r the category for the post and I thought I could set that equal to a variable and just use ‘category_name’ => $currcat but that didn’t work though it made sense to me.
I never in the nearly 200 blog posts ever used more than one category per post. But the sample data I pulled into the database has a lot of posts that use multiple cats.
Why are you using posts_not__in with get_the_ID? I’ll have to figure that out since there are a few new things there that are new to me – it worked so thanks a lot!
I would like to figure out how to enqueue the Google analytics script then upload my theme onto my other two sites and see how they do with Eklementor, Woocommerce, and Gutenberg.
I may not be the best at class names but here is what I have – should probably make the thumbnail a link as well but that seems redundant:
<aside class="bgcolor4"> <div class="container"> <h3 class="custom-title"><?php esc_html_e('Similar articles you may like... ', 'tower') ?></h3> <div class="row"> <?php $cats = wp_get_post_categories( get_the_ID(), ['fields'=>'ids',]); $posts = get_posts( [ 'numberposts'=> 3, 'category'=> implode(',', $cats), 'post__not_in'=> [get_the_ID(),], ]); global $post; foreach ($posts as $post) { setup_postdata($post); ?> <div class="single-recent-row"> <?php the_post_thumbnail() ?> <a class="single-recent-posts-link" href="<?php the_permalink(); ?>" rel="bookmark"><h4 class="single-recent-row-title"><?php the_title(); ?></h4></a> <?php get_template_part( 'template-parts/content', 'author' ); ?> </div> <?php wp_reset_postdata(); } ?> </div> </div> </aside>
- This reply was modified 3 years, 9 months ago by Jim.
So you prefer to use get_posts over WP_Query
Yes, it is good for getting small amounts of data. For your use case, you could use WP_Query since you are making a loop.
I was able to print_r the category for the post and I thought I could set that equal to a variable and just use ‘category_name’ => $currcat but that didn’t work
Was it a slug? That’s what ‘category_name’ is. See https://developer.www.ads-software.com/reference/classes/wp_query/#category-parameters
Why are you using posts_not__in with get_the_ID?
Because you want related posts, not the same post.
here is what I have – should probably make the thumbnail a link as well but that seems redundant
I was going to say that the image should be part of the link. It’s easier to click on. Also, move the reset so it only happens if you have some results and is outside the loop.
And does this work okay when there is no thumbnail?For print_r, I took it out but I think I did $cat = the_category; print_r; I just did that to see if it would return the cat of the present post which it did, then I thought I could somehow work that in which I couldn’t.
I thought get_the_ID was for to get the category but I have to study that code before I can write something like that myself.
Move reset to after endwhile? Got it and thanks for that. I tested it out on posts with different cats and some of the posts did not have thumbnails and it still worked. It also grabbed the content for posts that did not have an excerpt. I remember a trim function from a class I took that had this:
<?php if (has_excerpt()) { echo get_the_excerpt(); } else { echo wp_trim_words(get_the_content(), 18); } ?>
I used that to trim the excerpt since the ‘cards’ on my home page were a little big. I’m going to add a comment to add if checks like if has_thumbnail, if has_excerpt, etc. I suppose that would be the best thing to do or at least to get in the habit of doing.
For print_r, I took it out but I think I did $cat = the_category; print_r;
The functions that start with
the_
echo their results, so I doubt that that’s the code.I thought get_the_ID was for to get the category
You can look up functions in the Code Reference, you know. Here’s the function https://developer.www.ads-software.com/reference/functions/get_the_id/
It also grabbed the content for posts that did not have an excerpt.
That seems like a bit much for Related Posts. Be careful about duplicate content. You don’t have to check for an excerpt, because one will be generated if a manual excerpt is not written. But the excerpt will be the entire manually written excerpt or the standard length for the generated one (which you can filter). But it would be better for Related Posts to just have title and thumbnail. Have you ever looked at aljazeera.com news site?
More stuff for me to look into – actually, the excerpt was for the 3 recent posts on the home page, for the posts page it’s just thumbnail and title and a little meta though I’ll probably lose the meat
I meant to ask earlier and I forgot until now – how can I learn to write the code that pulled in the recent posts by category? I always look at the developers’ pages and I don’t see that code – and I don’t understand all of it. I’ll analyze that code above but it would be good to compare & contrast with similar code blocks. Do you know of any websites, pages, or blog posts that have examples?
There are two huge repositories of open source code, right here at www.ads-software.com: themes and plugins. There is the Theme Developer Handbook and the Plugin Developer Handbook.
See https://developer.www.ads-software.com/
I’m sure there are lots of tutorials out there, but only you know what level you are. Search first.- This reply was modified 3 years, 9 months ago by Joy. Reason: fix link
- The topic ‘How to get the category on single.php to use in a query to pull in similar posts’ is closed to new replies.