0

I use the add_menu_page function in my custom theme builds but when I export my local copy of the site and import it in the production site some of post id numbers change and I have to update this function manually (ie: in the code below: ?post=8, ?post=8, ?post=10). Is there a way to have these numbers be dynamic?

function custom_admin_menu_links() {
    $user = wp_get_current_user();
    if ( ! $user->has_cap( 'manage_options' ) ) {
        add_menu_page( 'Home', 'Home', 'edit_posts', 'post.php?post=6&action=edit', '', 'dashicons-admin-home', 1);
        add_menu_page( 'About', 'About', 'edit_posts', 'post.php?post=8&action=edit', '', 'dashicons-id', 2);
        add_menu_page( 'Contact', 'Contact', 'edit_posts', 'post.php?post=10&action=edit', '', 'dashicons-phone', 3);
    }
}
add_action( 'admin_menu', 'custom_admin_menu_links' );

3 Answers 3

0

There is a function called get_page_by_title that accepts a post title and returns the ID of that post. You might even use it in conjunction with get_edit_post_link by passing the ID and retrieve the edit link.

However, how can you be sure the post's title will never change? You could go a little further and add a settings page where you would map a particular post / page to an entity such as HOME_ID, ABOUT_ID etc. Then, instead of using the get_page_by_title you would just have this settings array and you could build those add_menu_page calls like this:

if ( ! $user->has_cap( 'manage_options' ) ) {
    $options = get_option( 'wt_menu_post_ids', array() );

    add_menu_page( 'Home', 'Home', 'edit_posts', get_edit_post_link( $options['HOME_ID'] ), '', 'dashicons-admin-home', 1);
    // [...]
}
1
  • Thanks, I like this idea. But it will probably take me a few days (I'm a PHP novice) to figure out how to do a custom settings page and the "entity" option but I won't have time for a few weeks.
    – codeview
    Jul 7, 2015 at 17:05
0

The quick and dirty answer would be something like this:

function custom_admin_menu_links() {
  $user = wp_get_current_user();
  if (  $user->has_cap( 'manage_options' ) ) {
    $type = 'book';

    $page = get_page_by_title('home','object',$type);
    if (!empty($page)) {
      add_menu_page( 'Home', 'Home', 'edit_posts', 'post.php?post='.$page->ID.'&action=edit', '', 'dashicons-admin-home', 1);
    }

    $page = get_page_by_title('About','object',$type);
    if (!empty($page)) {
      add_menu_page( 'About', 'About', 'edit_posts', 'post.php?post=8&action=edit', '', 'dashicons-id', 2);
    }

    $page = get_page_by_title('Contact','object',$type);
    if (!empty($page)) {
      add_menu_page( 'Contact', 'Contact', 'edit_posts', 'post.php?post=10&action=edit', '', 'dashicons-phone', 3);
    }
  }
}
add_action( 'admin_menu', 'custom_admin_menu_links' );

But you are running a lot of queries on every admin page load. You really should work out a way to cache the results. Something like:

function cache_custom_admin_menu_links($post_ID, $post) {
  $links = get_option('my_menu_links');

  $keys = array(
    'home',
    'about',
    'contact'
  );

  if (in_array($post->post_name,$keys)) {
    $links[$post->post_name] = $post_ID;

    update_option('my_menu_links',$links);
  }
}
add_action('save_post','cache_custom_admin_menu_links',10,2);

function custom_admin_menu_links() {
  $user = wp_get_current_user();

  if (  $user->has_cap( 'manage_options' ) ) {
    $type = 'book';
    $links = get_option('my_menu_links');
    $i = 1;
    foreach ($links as $k=>$v) {
      add_menu_page( $k, ucfirst($k), 'edit_posts', 'post.php?post='.$v.'&action=edit', '', 'dashicons-phone', $i);
      $i++;
    }
  }
}
add_action( 'admin_menu', 'custom_admin_menu_links' );

Then you just have to resave your posts rather than edit the code. I am sure even that could be automated if you needed it to be.

1
  • Thanks for the info. I will give your caching code example a try but it looks quite complicated to understand for me.
    – codeview
    Jul 7, 2015 at 17:06
0

yes possible to make the post IDs dynamic in the add_menu_page() function. we can used get_page_by_title() function to fetch the post IDs based on post titles.

function custom_admin_menu_links() {
    $user = wp_get_current_user();
    if ( ! $user->has_cap( 'manage_options' ) ) {
        $home_post = get_page_by_title( 'Home' );
        $about_post = get_page_by_title( 'About' );
        $contact_post = get_page_by_title( 'Contact' );

        if ($home_post) {
            add_menu_page( 'Home', 'Home', 'edit_posts', 'post.php?post=' . $home_post->ID . '&action=edit', '', 'dashicons-admin-home', 1);
        }
        if ($about_post) {
            add_menu_page( 'About', 'About', 'edit_posts', 'post.php?post=' . $about_post->ID . '&action=edit', '', 'dashicons-id', 2);
        }
        if ($contact_post) {
            add_menu_page( 'Contact', 'Contact', 'edit_posts', 'post.php?post=' . $contact_post->ID . '&action=edit', '', 'dashicons-phone', 3);
        }
    }
}
add_action( 'admin_menu', 'custom_admin_menu_links' );

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.