How to exclude draft pages from the navigation menu in WordPress

How to exclude draft pages from the navigation menu in WordPress

The issue

Have you ever had a Published page in a WordPress Menu that you changed to Draft but noticed it still appears to visitors?

WordPress prevents its users from adding Draft pages to menus but it doesn’t hide the when you turn a Published page to a Draft page.

Yep, that’s right. It leaves the page in the menu and sends users, and crawl bots, to a dead end or what we like to call a ‘404 page’.

Although Google has said that 404 pages are a perfectly normal occurrence on the web, having a 404 page can frustrate visitors and cause them to leave your website. This could mean you lose a lead or sale, both are terribly bad. And as business owners, we should do our very best to limit visitors leaving our websites.

The client

Our team ran into this issue with a client wanting to change the 30+ pages which sit in various menus throughout the website to Draft mode.

Now, we could have easily removed those pages from the navigation menus individually but that would have taken a lot of time. It would also have meant the client would have to add each page back into its respect menu when they were ready to republish the page.

The solution

To resolve this, we set out to create a quick WordPress function that would exclude all pages with the status of Draft from any Menu on the website. Effectively hiding any potential 404 pages from visitors and minimising any customer concerns.

Do to this, we’ve used filter callback for the wp_nav_menu_objects hook which looks at the post_status for the object that the menu item stands for, and removes it from the menu if that object is set to draft.

If you’d like to use following code to excluding your draft pages from your navigation menus in WordPress, simply copy and paste it into your functions.php file. We’d suggest adding the code through your cPanel File Manager or FTP in case there are any issues.

/**
* Hide Draft Pages from the menu
*/
function filter_draft_pages_from_menu ($items, $args) {
 foreach ($items as $ix => $obj) {
  if (!is_user_logged_in () && 'draft' == get_post_status ($obj->object_id)) {
   unset ($items[$ix]);
  }
 }
 return $items;
}
add_filter ('wp_nav_menu_objects', 'filter_draft_pages_from_menu', 10, 2);

If you need to hide private pages instead, simply swap the 'draft' on line #3 with 'private'.

Quick diagram explaining where to place code in the functions file

Need more help?

If you’re having any issues with anything above or would just like to ask a WordPress related question, please don’t hesitate to reach out to our team of experts at either our Brisbane office or our Gold Coast office, we’re always happy to help.