Tyler V.
Tyler V.

Reputation: 2561

Create New Type of Nav-Menu Item

A site I'm working on has a complicated "mega menu" type navigation. I would like content editors to be able to group menu items by column in the markup. Normally if I want 6 columns I would register 6 menus and name them columns 1-6, however these are dynamic sub-menus that need to be a child of another navigation item inside another menu.

What I'd really like to do is create a new type of nav-menu item (Currently Pages, Links, Categories, as well as my other custom post types and custom taxonomies) where that item would be just for columns. (The fact that I'm using it for columns isn't important here. This could just as easily be dividers, or something else. I just need a new nav-menu item type that I can create special markup with when I'm building the menus.)

Is there a way to create a new nav-menu item type without having to create a custom post type or custom taxonomy that is used only for this purpose?

Upvotes: 5

Views: 3528

Answers (1)

Tyler V.
Tyler V.

Reputation: 2561

What I ended up doing for this, was adding a new post type that was hidden everywhere on the site except the nav menus. I then added just a single entry of that post type type, and hid some of the fields.

<?php

function navMenuColumns_init() {
    register_post_type('menu_column',
        array(
            'labels' => array(
                'name'              => __('Menu Columns'),
                'singular_name'     => __('Menu Column')
            ),
            'supports' => array('title'),

            // Doesn't need to be listed most places as it's not a valid content item on it's own
            'public'                => false, // Base setting. More specific settings below
            'exclude_from_search'   => false,
            'publicly_queryable'    => false,
            'show_ui'               => false,
            'show_in_menu'          => false,
            'show_in_nav_menus'     => true,  // The only thing this is used for
            'show_in_admin_bar'     => false,
            'has_archive'           => false,
        )
    );

    $_version = (float)get_option('navMenuColumns_version', 0.0);

    if ($_version < 1.0) {
        navMenuColumns_install10();
    }

    add_action('admin_footer', 'navMenuColumns_adminFooter');
}

function navMenuColumns_install10() {
    $navMenuPost = wp_insert_post(array(
        'post_type'     => 'menu_column',
        'post_title'    => 'Column',
        'post_status'   => 'publish'
    ), true);

    if (!is_wp_error($navMenuPost)) {
        update_option('navMenuColumns_version', 1.0);
    }
}

function navMenuColumns_adminFooter() {
    ?><script>
        jQuery(document).ready(function($) {
            // Hides most of the fields when editing a Menu Column item.
            $('#menu-to-edit').on('click', 'a.item-edit', function() {
                var $li = $(this).parents('li.menu-item');

                if ($li.find('.item-type').text() == 'Menu Column') {
                    $li.find('p.description').hide();
                    $li.find('p.link-to-original').hide();
                    $li.find('p.field-move').show();
                }
            });
        });
    </script><?php
}

add_action('init', 'navMenuColumns_init');

?>

This allows the user to add this as a normal menu item. This won't play well with functions that build the menu markup for you, but if you traverse the menu item and build the markup for you, you can target this post type with custom markup.

Upvotes: 3

Related Questions