Hi,
with the following code snippet there will appear a selection dropdown in your WordPress Navigation’s Items that will hide them for logged-out, logged-in, or all users or more so show them to only the specified users. This code is extremely helpful for things like Login and Logout Links in your Navigation.
Add to your functions.php, or via a Snippet Plugin.
// Add custom field to menu items
function add_custom_nav_fields($menu_item) {
$menu_item->visibility = get_post_meta($menu_item->ID, '_menu_item_visibility', true);
return $menu_item;
}
add_filter('wp_setup_nav_menu_item', 'add_custom_nav_fields');
// Save custom field value
function update_custom_nav_fields($menu_id, $menu_item_db_id, $args) {
if (isset($_REQUEST['menu-item-visibility'][$menu_item_db_id])) {
$visibility_value = sanitize_text_field($_REQUEST['menu-item-visibility'][$menu_item_db_id]);
update_post_meta($menu_item_db_id, '_menu_item_visibility', $visibility_value);
}
}
add_action('wp_update_nav_menu_item', 'update_custom_nav_fields', 10, 3);
// Add visibility option to menu item
function add_visibility_field_nav_menu_item($item_id, $item) {
$visibility_options = array(
'all' => 'All Users',
'logged-in' => 'Logged-in Users',
'logged-out' => 'Logged-out Users'
);
$selected_visibility = get_post_meta($item->ID, '_menu_item_visibility', true);
if (!$selected_visibility) $selected_visibility = 'all';
?>
<p class="field-visibility description description-wide">
<label for="edit-menu-item-visibility-<?php echo $item_id; ?>">
Visibility:<br />
<select id="edit-menu-item-visibility-<?php echo $item_id; ?>"
name="menu-item-visibility[<?php echo $item_id; ?>]">
<?php foreach ($visibility_options as $value => $label) : ?>
<option value="<?php echo esc_attr($value); ?>"
<?php selected($selected_visibility, $value); ?>>
<?php echo esc_html($label); ?>
</option>
<?php endforeach; ?>
</select>
</label>
</p>
<?php
}
add_action('wp_nav_menu_item_custom_fields', 'add_visibility_field_nav_menu_item', 10, 2);
// Filter menu items based on visibility setting
function filter_nav_menu_items($items) {
foreach ($items as $key => $item) {
$visibility = get_post_meta($item->ID, '_menu_item_visibility', true);
if (!$visibility) $visibility = 'all';
if ($visibility == 'logged-in' && !is_user_logged_in()) {
unset($items[$key]);
} elseif ($visibility == 'logged-out' && is_user_logged_in()) {
unset($items[$key]);
}
}
return $items;
}
add_filter('wp_nav_menu_objects', 'filter_nav_menu_items');
Leave a Reply