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:

https://gist.github.com/devinsays/a78a00d239d7304d264716cf53db1855

About Devin

I am a developer based in Austin, Texas. I run a little theme shop called DevPress and help manage a WooCommerce shop with Universal Yums. Find me on twitter @devinsays.

4 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.

  3. This works with a limitation: wp_get_nav_menu_items() takes a menu, while has_nav_menu() takes a menu location; so the only way it will work is if both the menu and its location share the same name. The ideal thing would be to check for the location only, regardless of the name the user gives to the menu in it. I got it to work with this:

    $location = ‘featured-content’; // Replace with your menu location identifier
    if ( has_nav_menu( $location ) ) :
    // Get data of the menu in the location
    $locations = get_nav_menu_locations();
    $menu = get_term( $locations[$location], ‘nav_menu’ );
    // Get post ids of items in the menu
    $items = wp_get_nav_menu_items( $menu->term_id );

  4. Marek

    Thank you very much. This is exactly the thing I was looking for. I had many pages but wanted to show only those that are in my menu and I wasn’t sure if I could somehow extract id’s from the menu.

Leave a Reply