What I want
If a 'category' is added to the menu using the 'menus' tool in WordPress, I want my theme to automatically add a submenu containing links to all of the posts in that category.
<ul>
<li><a href="link">Page 1</a></li>
<li><a href="link">Page 2</a></li>
<li><a href="link">Category X</a>
//Automatically insert list of links to all posts in Category X
<ul>
<li><a href="link">Post 1</a></li>
<li><a href="link">Post 2</a></li>
</ul>
</li>
<li><a href="link">Category Y</a>
//Automatically insert list of links to all posts in Category Y
<ul>
<li><a href="link">Post 1</a></li>
<li><a href="link">Post 2</a></li>
<li><a href="link">Post 3</a></li>
<li><a href="link">Post 4</a></li>
</ul>
</li>
</ul>
What I've tried
In my functions.php
file I have created a function and hooked it to walker_nav_menu_start_el
action. By passing the $item
variable into the function I am able to identify if the current menu item is a category and what category it is. But I'm having trouble creating the list of links with post titles for all posts in that category.
At first I thought I could use the get_posts
function and a foreach loop, but because I'm not outputting, I'm just building an output variable to be passed back to the walker_nav_menu_start_el
action, it's merely outputting the details of the current post instead of the details for each post it loops through. This is the code I tried:
function hw_submenu( $output, $item ) {
if( $item->object == 'category' ) {
$hw_output = '<ul>';
$subposts = get_posts( array(
'posts_per_page' => -1,
'category' => $item->object_id
) );
if ( $subposts ) {
foreach ( $subposts as $post ) :
setup_postdata( $post );
$hw_output .= "<li><a href='" . the_permalink() . "''>" . the_title('', '', false) . "</a></li>";
endforeach;
wp_reset_postdata();
}
$output .= $hw_output . "</ul>";
}
return $output;
}
add_action( 'walker_nav_menu_start_el', 'hw_submenu', 10, 2);
And this is an example menu output:
<ul>
<li><a href="link">Page 1</a></li>
<li><a href="link">Page 2</a></li>
<li><a href="link">Category X</a>
//Automatically inserts list of links to the post I'm currently viewing
<ul>
<li><a href="link">Post I'm currently viewing</a></li>
<li><a href="link">Post I'm currently viewing</a></li>
</ul>
</li>
<li><a href="link">Category Y</a>
//Automatically inserts list of links to the post I'm currently viewing
<ul>
<li><a href="link">Post I'm currently viewing</a></li>
<li><a href="link">Post I'm currently viewing</a></li>
<li><a href="link">Post I'm currently viewing</a></li>
<li><a href="link">Post I'm currently viewing</a></li>
</ul>
</li>
</ul>
How can I get each category to list its posts in the menu? Can I do it with this action hook? Or should I be looking at a custom walker?
the_title()
andthe_permalink()
are taking their cue from the global$post
variable. I'd try changing$post
in your loop to$subpost
and setsetup_postdata( $subpost )
to avoid namespace problems.