WordPress is primarily a blog platform. Not infrequently it is used as a CMS. But not just static pages play a role, but also posts, because they are giving more opportunities, having better performance and be published in feeds. Therefore, I prefer to use, in the context of WP as a CMS, posts more than the static pages. From time to time are the wishes of a navigation layout very extra odinary. And so was it in my recent project, the requirement to list the posts from each category in the navigation.
This is unusual as in the long run, you will have many posts, and the navigation will be very confusing – still, in this project it made sense, since we won’t have many posts.
The small function lists the category and below the posts. There is a parameter that restricts the output of the posts, so that in extreme cases, not too many will be listed, only the last posts – $mylimit
. The value -1
for this parameter provides all posts. The function itself belongs to the functions.php
of the theme or in a Plugin. An exemplary use can be found below the function.
function fb_posts_by_category() {
global $wpdb, $post;
$mylimit = '-1'; // limit for posts, -1 for all
$sort_code = 'ORDER BY name ASC, post_date DESC';
$the_output = '';
$last_posts = (array)$wpdb->get_results("
SELECT $wpdb->terms.name, $wpdb->terms.term_id
FROM $wpdb->terms, $wpdb->term_taxonomy
WHERE $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id
AND $wpdb->term_taxonomy.taxonomy = 'category'
{$hide_check}
");
if ( empty($last_posts) )
return NULL;
$used_cats = array();
$i = 0;
foreach ($last_posts as $posts) {
if ( in_array($posts->name, $used_cats) ) {
unset($last_posts[$i]);
} else {
$used_cats[] = $posts->name;
}
$i++;
}
$last_posts = array_values($last_posts);
//$the_output .= '
- ';
foreach ($last_posts as $posts) {
$class = 'cat-item cat-item-' . $posts->term_id;
$catsy = get_the_category();
$current_category = $catsy[0]->cat_ID;
if ( isset($current_category) && $current_category && ($posts->term_id == $current_category) )
$class .= ' current-cat';
elseif ( isset($_current_category) && $_current_category && ($posts->term_id == $_current_category->parent) )
$class .= ' current-cat-parent';
$the_output .= '
- ' . apply_filters('list_cats', $posts->name, $posts) . '';
$where = apply_filters('getarchives_where', "WHERE post_type = 'post' AND post_status = 'publish'" , $r );
if ('-1' !== $mylimit)
$limit = ' LIMIT ' . (int) $mylimit;
else
$limit = '';
$arcresults = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' AND ID IN (Select object_id FROM $wpdb->term_relationships, $wpdb->terms WHERE $wpdb->term_relationships.term_taxonomy_id =" . $posts->term_id . ") ORDER BY post_date DESC$limit");
if (isset($arcresults) && $arcresults) {
$the_output .= '
- ';
foreach ( $arcresults as $arcresult ) {
$class = 'post-item post-item-' . $arcresult->ID;
$current_post = get_the_ID();
if ( isset($current_post) && $current_post && is_singular() && ($arcresult->ID == $current_post) )
$class .= ' current-post';
$the_output .= '
- ' . apply_filters('the_title', $arcresult->post_title) . ' '; } $the_output .= '
';
}
//$the_output .= '
Here an example in a sidebar.php
, which only uses Markup HTML5.
Comments
18 responses to “List Posts by Category In Navigation”
You sure there’s no better way of doing this?
I really don’t like to mess with SQL statements in WP, since there usually is always a function giving me what I need.
This would be good as a sidebar widget, perhaps to list the first 5 or so posts from the categories that the admin specifies.
Thank you for this! I immediately got use for it in my current project.
I think the row
“$limit = ‘ LIMIT ‘ . (int) $limit;”
should be
“$limit = ‘ LIMIT ‘ . (int) $mylimit;”
no?
and the line “$where = apply_filters(‘getarchives_where’, “WHERE post_type = ‘post’ AND post_status = ‘publish’” , $r );”
isn’t used in the posts query?
also, when a post is active, the category is also active, which leads to theming issues.
very nice.
I’ll have to try this out .. perhaps integrate some sort of javascript accordion menu.
Is it possible to exclude a category ?
[…] List Posts by Category In Navigation […]
That´s what I was looking for! Thank you so much!
@Konstantin: yes, it is evry good, when you use a function of WP. A SQL statepmant in in other sites faster and i dont find a function for this small request.
@Erik: correctly – i had change this
@Dave: yes, you can use a js for this, i make it with jquery and and a small script; example:
@sebastian: yes, you can add a sql statemant to the code for exclude a id of category or use the conditional tag is_category() and exclude the id.
Hi Frank
Nice function – works well.
Could you just give an example of excluding a category. I can’t seem to get it to work.
Thanks
@Josif:
add this to the sql-query and inlcude all categories, do you will include this function:
AND $wpdb->term_taxonomy.term_id IN (3,8,9)
or use
NOT IN
for exclude a ID of a category.Hello Frank!
Great Function! Good job! Work well! Thanx!
This is great!
Exactly what I was looking for.
I do have one question though. Is there a way to add a class, like the slug of the cat in the first level of li?
Thank you soo much!
I’m running wordpress 3.0. This fix almost works like a dream, my live site looks great, but I get the following error (only in the admin section thus far) when posting new posts or editing posts…
Warning: Cannot modify header information – headers already sent by (output started at /wp-content/themes/vidley/functions.php:268) in /wp-includes/pluggable.php on line 890
Its certainly this fix as when I delete it then the problem is resolved. Any idea how to resolve this??
ok problem resolved…. white space before the php tags …. grrrr… silly php. Anyhow, thanks for the AWESOME fix.
I just added the name of the category inside the css class so that I can have a different bg depending on the category. This is great.
I have another question concerning the order of the category. I use the plugin My category order and I’d like to know how to apply it on that script.
Thanks for your help!!!
I really thank you for sharing your work with those of us in the field. This is very elegant.
My hope was that it would permit me to show all of the posts in one category. The display is a horizontal navigation and I want the posts to drop down within that one category.
I succefully got the SQL to work and extract the single category that I want. I then added the function to the navigation list but the dropdowns are not working. What am I missing?
Would it be possible to show the post thumbnails instead of titles?
How can I use this function to list only the children of category id = 1, and it’s child categories?