11

Is there a function, action or filter that I can use to add a third level drop-down menu to the WordPress admin menu.

For instance, right now in the sidebar menu, there is a menu for posts and under posts there are sub-menus for editing posts, adding a new post, categories, and tags. There is something similar for Pages.

What I would like to do is to add a menu item called Content and place underneath content Posts, Pages and my Custom Content Types and underneath each of those entries the relevant sub-menus (editing, adding, etc.).

I would like to do this through a custom plugin that I create. The problem is, I can't find any information on how to add a third-level sub-menu.

Any ideas?

Thanks.

1
  • 1
    IMO you can not!
    – Sumit
    May 18 '16 at 5:43
11

No, it is not possible to create third level menu in admin panel. If you look at the definition of add_submenu_page, you need to mention the parent slug name. For eg:

add_menu_page ( 'Test Menu', 'Test Menu', 'read', 'testmainmenu', '', '' );
add_submenu_page ( 'testmainmenu', 'Test Menu', 'Child1', 'read', 'child1', '');

The first parameter of the add_submenu_page will be parent slug name. So you may think we can write child1 as parent slug name to create the third level. Eg:

add_submenu_page ( 'child1', 'Test Menu', 'Child2', 'read', 'child2', '');

But this will not work. Look at the parameters definition and source section in this link. It clearly states that, you can only use the name of 'main menu of the plugin' or the file name of the WordPress plugin in parent slug name. So it is not possible to create submenus more than once in admin panel. However, you can create n number of sub menus in front end. To know more about creating menus and sub menus in front end, refer

2
  • There is no work-around or hack?
    – Moshe
    May 18 '16 at 10:01
  • You could always javascript something, there is always a way to hack something. Sep 22 '18 at 1:23
3

I wrote it myself using JS. It's just for one project and I didn't want to spend much time on it, so you have to adjust it for your personal needs ;)

It hides chosen menu elements and creates a button which toggles them.

You add it to the end of file /wp-admin/menu-header.php

<script>
    // Here is list of classes of chosen menu elements you want to toggle - li.menu-icon-slug
    let my_products = document.querySelectorAll("li.menu-icon-okna, li.menu-icon-drzwi, li.menu-icon-bramy_garazowe");
    
    my_products.forEach(prod => {
        prod.style.backgroundColor = "#283338";
    })
    
    // "Produkty" is a text on a toggling button, change it
        let my_button = jQuery('<li class="menu-top"><a class="menu-top"><div class="wp-menu-image dashicons-before dashicons-admin-post"></div><div class="wp-menu-name">Produkty</div></a></li>')[0];

        document.querySelector("ul#adminmenu").insertBefore(my_button, my_products[0]);

    function toggleProducts() {
        my_products.forEach(prod => {
            if(prod.style.display != "none") prod.style.display = "none";
            else prod.style.display = "block";
        })
    }
    toggleProducts();

    my_button.querySelector("a").addEventListener("click", toggleProducts);

</script>

. . with no jQuery:

<script>
    // Here is list of classes of chosen menu elements you want to toggle - li.menu-icon-slug
    let my_products = document.querySelectorAll("li.menu-icon-okna, li.menu-icon-drzwi, li.menu-icon-bramy_garazowe");

    my_products.forEach(prod => {
        prod.style.backgroundColor = "#283338";
    })

        let prod_li = document.createElement("li");
        prod_li.classList.add("menu-top");

        let prod_a = document.createElement("a");
        prod_a.classList.add("menu-top");

        let prod_div1 = document.createElement("div");
        prod_div1.classList.add("wp-menu-image","dashicons-before","dashicons-admin-post")

        let prod_div2 = document.createElement("div");
        prod_div2.classList.add("wp-menu-name");

        // Text on a button:
        prod_div2.appendChild(document.createTextNode("Produkty"));

        prod_a.append(prod_div1, prod_div2);
        prod_li.append(prod_a);

        document.querySelector("ul#adminmenu").insertBefore(prod_li, my_products[0]);

    function toggleProducts() {
        my_products.forEach(prod => {
            if(prod.style.display != "none") prod.style.display = "none";
            else prod.style.display = "block";
        })
    }
    toggleProducts();

    prod_a.addEventListener("click", toggleProducts);

</script>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.