Controlling Menu Item Visibility in WordPress Based on User Login Status
WordPress menus provide an excellent way to structure and organize your website’s navigation. However, there are times when you might want to control the visibility of certain menu items based on whether a user is logged in or logged out. In this guide, we’ll walk through the process of achieving this functionality using custom fields and code.
Introduction
The objective is to add an extra visibility option to each menu item in the WordPress admin panel, enabling you to decide whether a menu item should be visible to all users, only logged-in users, or only logged-out users.
// Add visibility options to the menu item
function add_menu_visibility_fields($item_id, $item, $depth, $args) {
$visibility_options = array(
‘all’ => ‘Visible for All Users’,
‘loggedin’ => ‘Visible for Logged In Users’,
‘loggedout’ => ‘Visible for Logged Out Users’,
);
$visibility = get_post_meta($item_id, ‘_menu_item_visibility’, true);
echo ‘<p class=”field-visibility description description-wide”>’;
echo ‘<label for=”menu-item-visibility-‘ . esc_attr($item_id) . ‘”>’;
echo ‘Visibility: ‘;
echo ‘<select id=”menu-item-visibility-‘ . esc_attr($item_id) . ‘” class=”widefat” name=”menu-item-visibility[‘ . esc_attr($item_id) . ‘]”>’;
foreach ($visibility_options as $key => $label) {
$selected = ($visibility === $key) ? ‘selected=”selected”‘ : ”;
echo ‘<option value=”‘ . esc_attr($key) . ‘” ‘ . $selected . ‘>’ . esc_html($label) . ‘</option>’;
}
echo ‘</select>’;
echo ‘</label>’;
echo ‘</p>’;
}
add_filter(‘wp_nav_menu_item_custom_fields’, ‘add_menu_visibility_fields’, 10, 4);
// Save the custom fields when the menu is saved
function save_menu_visibility_fields($menu_id, $menu_item_db_id, $menu_item_args) {
if (isset($_REQUEST[‘menu-item-visibility’][$menu_item_db_id])) {
$visibility = sanitize_key($_REQUEST[‘menu-item-visibility’][$menu_item_db_id]);
update_post_meta($menu_item_db_id, ‘_menu_item_visibility’, $visibility);
}
}
add_action(‘wp_update_nav_menu_item’, ‘save_menu_visibility_fields’, 10, 3);
// Exclude menu items based on visibility
function exclude_menu_items_by_visibility($items, $menu, $args) {
foreach ($items as $key => $item) {
$visibility = get_post_meta($item->ID, ‘_menu_item_visibility’, true);
if (($visibility === ‘loggedin’ && !is_user_logged_in()) ||
($visibility === ‘loggedout’ && is_user_logged_in())) {
unset($items[$key]);
}
}
return $items;
}
// Hook the function to the ‘wp_get_nav_menu_items’ filter with priority 10 and 3 arguments
add_filter(‘wp_get_nav_menu_items’, ‘exclude_menu_items_by_visibility’, 10, 3);
Incorporate this code into your theme’s functions.php
file to enhance the menu management experience on your WordPress site. This code introduces a new meta box to the menu item settings, allowing you to choose the visibility option for each menu item.
Feel free to modify the visibility options and customize the code to suit your specific requirements. Enjoy extending the functionality of your WordPress menus!