21

Is there a way to add a arbitrary hyperlink to the WordPress admin menu (I mean the menu on the left when you log into the admin dashboard)? For example, can one add a link to Google?

In my particular case, I'd like to add a styleguide page for a Wordpress theme I'm working on so I can show the user how different HTML elements are styled with the theme and to demo how to style various things nicely.

This is the code I have so far (note: it is incomplete): In functions.php I have added a new menu item in the Appearance section:

add_action('admin_menu', 'create_theme_style_page');

function create_theme_style_page() {
  add_theme_page('Theme Styleguide', 'Theme Styleguide', 'administrator', basename(__FILE__),'build_styleguide_page');
}

function build_styleguide_page() {
 echo "Not sure what goes here to redirect admin to a arbitrary url?";
}

In build_styleguide_page(), attempting to redirect with header() gives a error (Cannot modify header information).

3 Answers 3

13

Hi @Tom,

If I understand your question correctly you don't so much need to know how to add a link to the menu (it seems you already know that) but instead need to learn how to get your link to redirect correctly, right?

Redirecting to an External URL from an Admin Menu Item

If so what you need to do is to not use the menu item function but instead "hook" WordPress early enough such that it hasn't output anything except possibly HTTP headers. The earliest hook when calling /wp-admin/themes.php appears to be after_setup_theme and it appears to work well.

Use a "Menu Slug" So You Can Test for it in a Hook

But to get it to work we first need to modify your call to add_theme_page in the admin_menu hook / your create_theme_style_page() function. We dropped the fifth parameter (the function to call to implement the admin option) because we don't need it, and changed the fourth parameter (the "menu slug") to be themes.php?goto=build-styleguide-page.

Although we could have chosen almost literally anything for the fourth parameter, given we are going to redirect I routed to the same page (themes.php) as other appearance options for consistency. I also just arbitrarily came up with the name goto because WordPress doesn't use it and it seems to make sense for this.

add_action('admin_menu', 'create_theme_style_page');
function create_theme_style_page() {
  add_theme_page(
    'Theme Styleguide',
    'Theme Styleguide',
    'administrator',
    'themes.php?goto=build-styleguide-page'
  );
}

BTW, we got rid of your build_styleguide_page() function because we don't need it for this solution.

Redirect in the Earliest Hook for themes.php: after_setup_theme

As our last bit of code we implement our after_setup_theme hook in our redirect_from_admin_menu() function. We have it test to see if the current page is themes.php and to ensure a URL parameter of goto was passed on the URL. Then it tests the value of goto using a switch/case statement to see if it has a value of 'build-styleguide-page'; if so it redirects to your stated hypothetical e.g. Google otherwise we just redirect back to the admin dashboard:

add_action('after_setup_theme', 'redirect_from_admin_menu');
function redirect_from_admin_menu($value) {
  global $pagenow;
  if ($pagenow=='themes.php' && !empty($_GET['goto'])) {
    switch ($_GET['goto']) {
      case 'build-styleguide-page':
        wp_redirect("http://www.google.com");
        break;
      default:
        wp_safe_redirect('/wp-admin/');
        break;
    }
    exit;
  }
}

Notes:

  1. I chose to use the switch/case statement in the after_setup_theme hook / redirect_from_admin_menu() function so that it would be easier to add additional goto redirects if you need to; just add more case statements.

  2. the wp_redirect() and wp_safe_redirect() functions don't actually terminate; you need to explicit issue an exit statement to get WordPress to stop and not override your redirect.

Hope this helps!

0
22

If you add your item into the menu by adding it to the $submenu array directly you'll avoid the need to do the redirect and be able to use a complete offsite URL as the menu link (i do this myself).

add_action( 'admin_menu' , 'admin_menu_new_items' );
function admin_menu_new_items() {
    global $submenu;
    $submenu['index.php'][500] = array( 'Menu item name', 'manage_options' , 'http://example.com' ); 
}  

index.php represents the key/link of the parent menu, so in the example i'm basically adding an item to the Dashboard menu..

Sure, it's not quite as pretty as using the add_{type}_page functions, but it does work-around the fact WordPress prevents off-site URLs in admin menu links..

I use something similar to add my various virtual hosts into the menu, so i can switch to other installations directly from the admin menu (all done with a script, but basically uses a glorified version of the above code).

NOTE: If you decide to use the code, just be careful not to assign a key that's in use(the 500 array key in the example code).

TIP: You can actually use negative values in the menu keys to, so you can force you menu items to sit before any of the native WordPress items.

9
  • NOTE: I think you will need to set that negative key as a string though, ie. '-5' and not -5, else the key is regarded invalid(i think).. (negative strings works though, if i'm not mistaken)..
    – t31os
    Commented Dec 9, 2010 at 23:52
  • Thanks, sucks that you can't do it with the real functions, but this is a whole lot better than having to add a hook/redirect combo just to have a link.
    – El Yobo
    Commented Sep 12, 2011 at 23:39
  • 2
    This particular answer helped me with my plugin Post Status Menu Items (you can probably guess what it does). Anyway, because I didn't know what other plugins would be adding stuff to what menus, I thought I'd just add that I used array_push() to append the menu items to avoid colliding with any other plugins.
    – mrwweb
    Commented Apr 28, 2012 at 21:42
  • Works like a charm, plus bonus point for using such a small snippet.
    – João
    Commented Nov 7, 2012 at 10:44
  • 2
    +1. Rather than picking a key and hoping, just grab the last key and increment. For example, when adding a submenu item to the Tools menu: global $submenu; $key = end(array_keys($submenu['tools.php'])) + 1; $submenu['tools.php'][$key++] = etc.
    – webaware
    Commented May 29, 2013 at 7:19
3

I have achieved same with this:

function add_custom_menu_item(){
    add_menu_page( 'Menu Item Title', 'Page Title', 'manage_options', 'page_slug', 'function', 'dashicons-icon', 1 );
}
add_action( 'admin_menu', 'add_custom_menu_item' );

function custom_menu_item_redirect() {

    $menu_redirect = isset($_GET['page']) ? $_GET['page'] : false;

    if($menu_redirect == 'page_slug' ) {
        wp_safe_redirect( home_url('/my-page') );
        exit();
    }

}
add_action( 'admin_init', 'custom_menu_item_redirect', 1 );

What you do here is you add menu item and define slug, then on 'admin_init' you check if slug exists and redirect to your desired location.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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