Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Creating a list of posts for the current category in a sidebar WordPress

  • SOLVED

My question is about I problem I having in a project that is more like a CMS than a blog.

I want a list of posts for the current category in a sidebar to use as a menu. Some of the posts are included in more than one category. Let us say I have the following posts and categories:

Category 1
-post 1
-post 2
-post 3
-post 4

Category 2
-post 5
-post 6
-post 7
-post 8

Sale
-post 3
-post 6

New
-post 4
-post 5

So when in Category 1, I want a menu like this:
-post 1
-post 2
-post 3
-post 4

Or when in Sale I, want a menu like this:
-post 3
-post 6

This will probably only be used in single.php and since it is in a sidebar it outside of the loop.

The main problem, as I see it, is that there is no obvious way to find the current category if a post is in more than one category.

I always set permalinks to make pretty url's using "/%category%/%postname%" so each single post will have a url including the category slug. My solution, as you can see in the code below, is to match the slug in the url with the slug in the categories array. This seems very very hinky to me. I want to know if there is a better solution using more appropriate Wordpress resources. Wordpress offers simple solutions to so many common website needs that I would expect this to be easy as well. Possibly I am missing something. Thanks.


<ul>
<?php
$permalink = get_permalink( $id ); //get the url for the post
$categories = get_the_category();
foreach ($categories as $category) { //loop through the categories for this post
$this_slug = $category->slug; //find the slug
$pattern = '/' . $this_slug. '/';
preg_match($pattern, $permalink, $matches);
if ($matches[0]){ //if the slug matches a portion of the url then we know the current category
$dw_slug = $matches[0];
}
}

global $post;
$myposts = get_posts('category_name=' . $dw_slug . '&numberposts=-1'); //we get the posts for the current category and print them below.
foreach($myposts as $post) :
setup_postdata($post);
?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>


[Edit]
I had tried the solution suggested by WP Divas in my search for an answer to my question. If a post is in 2 categories (for example) it loops through both categories and prints out all the post for both categories. Thanks for you answer.

Answers (5)

2010-01-05

Max answers:

Hi, according to the documentation:

<blockquote>When you assign multiple categories to a post, only one can show up in the permalink. This will be the lowest numbered category</blockquote>

With this in mind the code is very simple:


$categories = wp_get_post_categories(get_the_ID());
$your_category = $categories[0];


After this your_category will contain the ID of the category in the slug of the current post.

The categories are sorted in ascend order by default, so you need just two line of code.

2010-01-07

Japh answers:

Here's another alternative:
<?php
$categories = get_the_category();
echo '<ul><li>';
foreach ($categories as $c) {
if (strpos(get_permalink($post->ID), $c->slug) !== false) {
echo '<a href="/' . $c->slug . '/">' . $c->name . '</a>';
$current_cat = $c->cat_ID;
}
}

$posts = get_posts(array('cat' => $current_cat));
if (!empty($posts)) {
echo '<ul>';
foreach ($posts as $p) {
echo '<li><a href="' . get_permalink($p->ID) . '">' . $p->post_title . '</a></li>';
}
echo '</ul>';
}
echo '</li></ul>';
?>

2010-01-07

kjll kll answers:

Am I missing something?

You want to use the code inside the single.php and you are talking about "that there is no obvious way to find the current category if a post is in more than one category".

If you are looking at a WordPress post (single.php) there is no current category. Normally you are leaving a category view or archive when you jump to a posts single view.

So, there will always some problems, if a postings has more than one category!

2010-01-05

WP Divas answers:

This is the code I use. It grabs all of the related posts to the category that post is in and the code goes right into the sidebar, so outside the loop:

<?php
if ( is_single() ) :
global $post;
$categories = get_the_category();
foreach ($categories as $category) :
$posts = get_posts('numberposts=4&exclude=' . $GLOBALS['current_id'] . '&category='. $category->term_id);
//To change the number of posts, edit the 'numberposts' parameter above
if(count($posts) > 1) {
?>


<div class="widget more-category">
<h3 class="widgettitle">More in <?php echo $category->name; ?></h3>
<ul>
<?php foreach($posts as $post) : ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>
</div>

<?php } ?>


Hope this helps! :)

2010-01-05

WP Divas answers:

Oh, I see... so you want this code to do this based on the whole category? Then replace is_single with is_category.

So:

<?php
if ( is_category() ) :
global $post;
$categories = get_the_category();
foreach ($categories as $category) :
$posts = get_posts('numberposts=4&exclude=' . $GLOBALS['current_id'] . '&category='. $category->term_id);
//To change the number of posts, edit the 'numberposts' parameter above
if(count($posts) > 1) {
?>


<div class="widget more-category">
<h3 class="widgettitle">More in <?php echo $category->name; ?></h3>
<ul>
<?php foreach($posts as $post) : ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>
</div>

<?php } ?>