Display Posts or Pages Based on a Navigation Menu

For a site I’ve been working on there’s a section of “featured content” near the bottom of the home page. I was using a simple WP_Query to generate the markup, but after the third time updating the post IDs (because different content needed to be featured), I decided this needed to be managed somehow through the dashboard.

selections

The most common way to do something like this is generally to have a WP_Query that pulls from a specific taxonomy term (like a “featured” tag), however this doesn’t give you any control over the order of the posts. Also, in my case, I needed to display pages and a custom post type “guide” in addition to standard posts.

Thankfully, the WordPress Navigation Menus provide an easy built in interface that can be used to select content. So, I swapped my hardcoded query to pull Post IDs from a navigation menu instead. I thought it would be worth sharing the solution since this could be used in many types of situations: sliders, setting featured products for a specific template, or featuring content in a sidebar or footer.

menus

Here’s how it works:

<?php
$menu = 'featured-content'; // Replace with your menu name
if ( has_nav_menu( $menu ) ) :
// Get post ids of items in the menu
$items = wp_get_nav_menu_items( $menu );
foreach ( $items as $item ) {
$ids[] = get_post_meta( $item->ID, '_menu_item_object_id', true );
}
// var_dump( $ids );
if ( isset( $ids ) ) :
$args = array(
'posts_per_page' => 6, // # of posts to appear
'post_type' => array( 'post', 'page', 'guide' ), // Post types
'post__in' => $ids,
'orderby' => 'post__in'
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while ( $query->have_posts() ) : $query->the_post(); ?>
<div class="article">
<a href="<?php the_permalink(); ?>">
<div class="image">
<?php the_post_thumbnail(); ?>
</div>
<h3><?php the_title(); ?></h3>
</a>
</div>
<?php endwhile;
endif;
wp_reset_query();
endif;
endif;

About Devin

I'm a WordPress developer based in Austin, Texas. I run a little theme shop called DevPress and work for a startup called Nano. Find me on twitter @devinsays.

2 Responses

  1. Hi Devin,

    Excellent work, I always thinking about shortcode or widget for this type of situation. And by putting post id. You know it’s hard to get the post id for none technical people. But with wordpress navigation it’s a perfect solution. It’s very easy to mange none technical peoples. Thanks for sharing.

  2. Paul

    I like the idea of using the menus UI, although it doesn’t make logical sense to have to go to edit a nav menu to get related posts, users might find it counter intuitive.

    I’d add some caching for the query as post__in is quite expensive in terms of performance and you could also use `no_found_rows` as well.

Leave a Reply