phpwordpresssubmenuwordpress-plugin-creation

How to change the WordPress submenu order


I hope you are doing great.

I was working on WordPress. I have registered new post type and two new taxonomies and A submenu page. Now my menu looks like this.

Datasets are Post type.

Species and groups are Taxonimies.

Upload Relational CSV is Submenu page

Datasets ↴

→ All Datasets

→ Add New Dataset

→ Species

→ Groups

→ Upload Relational CSV

enter image description here

I want to change the order of submenu items.

new order must be

Datasets ↴

→ All Datasets

→ Species

→ Groups

→ Upload Relational CSV

→ Add New Dataset

enter image description here

add_filter( 'custom_menu_order', '__return_true' );
add_filter( 'menu_order', function( $custom_order ) {
    return array(
        'edit.php?post_type=datasets',
        'edit-tags.php?taxonomy=species&post_type=datasets',
        'edit-tags.php?taxonomy=group&post_type=datasets',
        'edit.php?post_type=datasets&page=upload-homologs-relations',
        'post-new.php?post_type=datasets',
    );
} );

But this code does not help me.

Then I tried new code.

function custom_submenu_order( $submenu, $parent_slug ) {
    // Make sure you replace "dataset" with the slug of your custom post type
    if ( $parent_slug === 'edit.php?post_type=dataset' ) {
        // Define the new order of the submenu items
        $new_order = array(
            'edit-tags.php?taxonomy=species&post_type=dataset', // "Species"
            'edit-tags.php?taxonomy=groups&post_type=dataset', // "Groups"
            'admin.php?page=upload-csv', // "Upload Relational CSV"
            'post-new.php?post_type=dataset' // "Add new Dataset"
        );
        // Sort the submenu items based on the new order
        uasort( $submenu[ $parent_slug ], function( $a, $b ) use ( $new_order ) {
            $a_index = array_search( $a[2], $new_order );
            $b_index = array_search( $b[2], $new_order );
            return $a_index - $b_index;
        } );
    }
    return $submenu;
}
add_filter( 'submenu_order', 'custom_submenu_order', 10, 2 );

then I got it the hook submenu_order does not exists in WordPress. Please help me to find the solution.


Solution

  • The answer is by Nagendra Rao to this question Wordpress: Change admin submenu order.

    Nagendra Rao's answer has this line of code:

    add_filter( 'custom_menu_order', 'so_18766477_submenu_order' );
    

    ...which should really be two calls to add_filter():

    add_filter( 'custom_menu_order', '__return_true' );
    add_filter( 'menu_order', 'CALLBACK_FUNCTION' );
    

    ...where the CALLBACK_FUNCTION uses the menu_order filter hook and could look like the function below.

    Callback function

    Reordering top-level versus submenu items

    The callback function below demontrates how to modify top-level menu items and submenu items. There is an important difference between the two. The $menu_ord parameter passed by menu_order is used to modify top-level items. Items that you remove or omit from $menu_ord are automatically re-added to the final result in their usual order after the items you include. This is unlike the $submenu global variable. If you remove or omit items from $submenu, those missing items are not re-added to the final result.

    /**
     * Reorder either top-level menu items or submenu level items or both.
     * If not editing top-level items, return the $menu_ord variable unchanged.
     * 
     * @param array $menu_ord Associative array of menu and submenu items
     *   passed to the function by the menu_order filter hook.
     *
     * @return array
     */
    function CALLBACK_FUNTION( $menu_ord ) {
        // Global variable $submenu to be updated independently
        // from the local $reorder variable.
        global $submenu;
    
        // Optionally reorder top-level menu items.
        // Missing top-level items are automatically
        // added to the bottom of any items listed
        // here.
        // @see https://developer.wordpress.org/reference/hooks/menu_order/
        $reorder = array(
            'edit.php?post_type=page',
            'edit.php',
            'upload.php'
        );
    
    
        // Enable the next line to see all submenus
        //echo '<pre>'.print_r($submenu,true).'</pre>'.
        // See below for sample echo output.
    
        // Reorder submenu items for Post options.
        //my original order was 5,10,15,16
        $arr = array();
        $arr[] = $submenu['edit.php'][5];
        $arr[] = $submenu['edit.php'][10];
        $arr[] = $submenu['edit.php'][16];
        $arr[] = $submenu['edit.php'][15];
        $submenu['edit.php'] = $arr;
    
        return $reorder;
    }
    

    Sample echo output from $submenu global variable

    The echo output for the Post array element (edit.php) of the $submenu array could look like this:

    [edit.php] => Array
        (
            [5] => Array
                (
                    [0] => All Posts
                    [1] => edit_posts
                    [2] => edit.php
                )
    
            [10] => Array
                (
                    [0] => Add New
                    [1] => edit_posts
                    [2] => post-new.php
                )
    
            [15] => Array
                (
                    [0] => Categories
                    [1] => manage_categories
                    [2] => edit-tags.php?taxonomy=category
                )
    
            [16] => Array
                (
                    [0] => Tags
                    [1] => manage_post_tags
                    [2] => edit-tags.php?taxonomy=post_tag
                )
    
        )