9
votes

Under Pages menu in Wordpress Admin page, I got this layout:

Pages

  • Edit (url: edit-pages.php)
  • Add New (url: page-new.php)
  • Special Pages (url: edit-pages.php?special-pages=true)

as you can see, I've added a new submenu item called Special Pages which is pretty much a link to to Edit page with custom filter. Because Wordpress use file name to identify and highlight the submenu item, so whenever I click on Special Pages, the Edit submenu item is selected. Is there anyway to force Wordpress to select Special Pages menu item instead?

Cheers

7

7 Answers

9
votes

better solution:

add_filter('parent_file', 'my_plugin_select_submenu');
function my_plugin_select_submenu($file) {
        global $plugin_page;
        if ('__my-current-submenu-slug__' == $plugin_page) {
            $plugin_page = '__my-submenu-slug-to-select__';
        }
        return $file;
}
5
votes

To further clarify Ken Vu's answer, edit the global variables $submenu_file and $parent_file. E.g., to highlight your page:

global $submenu_file;
$submenu_file = "edit-pages.php?special-pages=true";

If you need to change the top-level item highlighted, use $parent_file. E.g., highlight the "Writing" setting page:

global $parent_file;
global $submenu_file;
$parent_file = 'options-general.php';
$submenu_file = 'options-writing.php';
3
votes

Solution: use $submenu_file variable

$submenu_file = "edit-pages.php?special-pages=true"

2
votes

Thanks Ken Vu and Jonathan Brinley. Using your answers, I finally got the highlighting of my admin menu to work properly. As I struggled a bit to get it to work, I though I would post the entire result here, so other people can find it more easily :

The idea is to call the parent_file filter (undocumented, as many Wordpress parts unfornatunately). In my case, I was adding a custom menu instead of the default generated when creating a custom post type.

In my custom post code, I call the add_meta_boxes action. Within this hook, I issue my call to the parent_file filter :

add_filter('parent_file',     array(&$this, 'highlight_admin_menu'));

_

Then this is how my hightlight_admin_menu function looks like :

function highlight_admin_menu($some_slug){

  global $parent_file;

  $parent_file = 'post.php?post=149&action=edit';

  return $parent_file;
}

_

This got my menu to highlight properly. Try playing around with you own code to know where to issue the add_filter('parent_file', ...) code. Find a bit of code executed only on that particular page load, but soon enough that it is still possible to modify the $parent_file variable.

I hope this helps!

1
votes

For changing the highlighted menu item for a submenu item, the proper filter is submenu_file.

add_filter('submenu_file', 'menuBold');

static function menuBold($submenu_file)
{
    if ( checkProperPage($_GET) ) {
        // The address of the link to be highlighted
        return 'post-new?post_type=foobar&foo=bar';
    }

    // Don't change anything
    return $submenu_file;
}

The check happens in WP's ~/wp-admin/menu-header.php file on line 194 (Wordpress 4.5.3):

if ( isset( $submenu_file ) ) {
    if ( $submenu_file == $sub_item[2] )
        $class[] = 'current';
...
}
0
votes

You can modify this code to work for you. You can change both parent and submenu with that. Tested code.

function change_active_parent($submenu_file)
{ 
    global $parent_file;

    $zone = 'edit-tags.php?taxonomy=zone&post_type=product';
    $storefront = 'edit-tags.php?taxonomy=storefront&post_type=product';
    $container = 'edit-tags.php?taxonomy=container&post_type=product';
    
    if (esc_html($zone) == $submenu_file) {
        $parent_file = 'parent';
        $submenu_file = $zone;
    }
    elseif (esc_html($storefront) == $submenu_file) {
        $parent_file = 'parent';
        $submenu_file = $storefront;
    }
    elseif (esc_html($container) == $submenu_file) {
        $parent_file = 'parent';
        $submenu_file = $container;
    }
    
    return $submenu_file;
}

add_filter( 'submenu_file', 'change_active_parent' );
0
votes

Use the load-{$page_hook} action hook and modify the necessary globals:

/**
 *  For giggles, lets make an admin page that is not "in the menu" to play with.
 */
add_action('admin_menu', 'mort1305_admin_menu');
function mort1305_admin_menu() {
    add_submenu_page(
        NULL,
        'Page Title',
        '',
        'administrator',
        'my_slug',
        'mort1305_page_content'
    );
}

/**
 *  The menu item to highlight and the submenu item to embolden.
 */
add_action('load-admin_page_my_slug', 'mort1305_on_page_load');
function mort1305_on_page_load(){
    global $plugin_file, $submenu_file, $title;
    $plugin_page = 'slug-of-menu-item-to-be-highlighted';
    $submenu_file = 'slug-of-submenu-item-to-be-bold';
    foreach($submenu[NULL] as $submenu_arr) {
        if($submenu_arr[2] === 'test_page_slug') {
            $title = $submenu_arr[3];
            break;
        }
    }
}

/**
 *  Page content to display.
 */
function mort_1305_page_content() {
    echo This is the '. get_admin_page_title() .' page.  The slug of my parent is '. get_admin_page_parent() .'.';
}