Hiding information from the WordPress admin

So, while I was working on my Back End Instructions plugin yesterday, I was talking to my husband about the client I had built it for. As a quick notation, it’s a group of women who are of a certain age (no offense to anyone – I’m getting there myself!) and who do not like change. It’s taken me almost three years of pulling teeth to get things to where they are now. They want to change, but man, are they putting up a fight for it.

Anyway, so I was telling my husband that the new plugin I made will make things so easy that even he could understand how to do it, and there would be no excuses for these people to do what they need to do.

(An aside, I really recommend getting a husband – or wife – who is clueless when it comes to computers. They are priceless when it comes to usability testing!)

After the expected “Oh, thanks honey,” comments, I asked him to come down and take a look for himself. He did, and he said I really did make it easy as pie. (Score!) However, he noted that some of the fields I was showing in the back end were not supposed to be touched (as mentioned in the video I made – that some fields were to be left alone) and he said that I should remove them if I didn’t want anyone to mess with them.

He had a point.

What I discovered last night doesn’t really have much to do with the plugin (save it’s handy) but more for WordPress. I was basically just trying to find some method of hiding the “Personal Options” in the profile.php page in the back end. I know for most sites, that should be left alone, but in this case, it’s an option that truly does not need to be messed with.

That’s when I found this post, which made things very interesting. (The following comment by BjornW made it even more interesting.)

It gave me a starting point.

Turns out you can take this a step further. There were some table rows within that profile.php page that I wanted to hide, but leave the rest to show. For example, the rows that contained the “JabberTalk”, “Aim” etc, and the”Bio” section. I wanted to retain the rest, but those fields really aren’t needed. So the question was, how to specify exact rows, while leaving others intact?

Oh, the life of a programmer. I had to know the answer. Lo and behold! I found it :)

Now the following code is simply to remove certain fields from the profile.php page – but I’m sure it has applications on other pages, if you so desired. On the site I’m using this for, I’m also using the Adminimize plugin, and Justin Tadlock’s “Members” plugin to remove further extraneous information a lot more easily.

So I’ll show you a “before” (i.e. before I added this blip of code to my functions.php file) photo of what the screen looked like:

And after the little blippy function:

Now before I give you the code, I also wanted to mention something I found via a reply in the WordPress forums. It was just a random thing someone mentioned in passing, and had they not, I never would have know this had existed.

Apparently, WordPress has created (recently, I believe) a particular variable that can be globalized in WordPress. Said variable is $pagenow. This is just an aside for you coders out there who don’t know about this wonderful little variable. Before, when I wanted to know what page I was on (and I couldn’t use anything like “is_page()”), I would grab the URL that was in the address bar, by using http://' . $_SERVER['HTTP_HOST'] . $_SERVER["REQUEST_URI"]; Then I would use an explode function to separate the string at the “/”, and list each result into a variable (or just using PHP’s end() function), allowing me to grab any part of the url. Usually, all I wanted was the last one: what page I was on. This lovely little variable has made all of that pointless. I just thought I’d share that :)

So, without making you wait any longer, here is the code: (Updated to reflect Nathan Briggs’ suggestions – thanks Nathan!)

add_action('admin_head', 'hide_profile_info');
function hide_profile_info() {
    global $pagenow;  // get what file we're on

    if(!current_user_can('edit_others_posts')) { // we want admins and editors to still see it
      switch($pagenow) {
        case 'profile.php':
          $output  = "\n\n" . '<script type="text/javascript">' . "\n";
          $output .= 'jQuery(document).ready(function() {' . "\n";
          $output .= 'jQuery("form#your-profile > h3:first").hide();' . "\n"; // hide "Personal Options" header
          $output .= 'jQuery("form#your-profile > table:first").hide();' . "\n"; // hide "Personal Options" table
          $output .= 'jQuery("table.form-table:eq(1) tr:first").hide();' . "\n"; // hide "username"
          $output .= 'jQuery("table.form-table:eq(1) tr:eq(3)").hide();' . "\n"; // hide "nickname"
          $output .= 'jQuery("table.form-table:eq(1) tr:eq(4)").hide();' . "\n"; // hide "display name publicly as"
          $output .= 'jQuery("table.form-table:eq(1)+h3").hide();' . "\n"; // hide "Contact Info" header
          $output .= 'jQuery("table.form-table:eq(2)").hide();' . "\n"; // hide "Contact Info" table
          $output .= 'jQuery("table.form-table:eq(3) tr:eq(0)").hide();' . "\n"; // hide "Biographical Info"
          $output .= '});' . "\n";
          $output .= '</script>' . "\n\n";

          $output = '';
    echo $output;

So basically, the jQuery("form#your-profile > table:first").hide(); line hides the first table completely – which is the “Personal Options” table. In jQuery, this would also be known as table.form-table:eq(0). The lovely :eq() function can count – without any extraneous code – where you are. You just have to specify where you want it to start counting, and go from there.

I’m pretty sure this can be used on any back-end page. All I needed it for was the profile page, and you can see how well it cleaned up all that stuff that didn’t need to be there!

Now I just have to test it in IE – and hopefully it doesn’t break!


  • Nathan Briggs says:

    Weird that there isn’t a filter for profile page fields.

    Thanks for the tip on $pagenow, that’s gonna be helpful.

    Its nitpicking, but it might be better form to test for $pagenow == ‘profile.php’ before going through the load of string concatenations.

  • Shelly says:

    Thanks Nathan!

    Excellent point. That *is* a good idea. I had it at the end, though, because I figured I might use it elsewhere (and I didn’t want to have the jQuery show up on pages it didn’t need to). But it definitely make sense to check if it’s needed, and *then* run the process. I’ll make that change now.


  • Nathan Briggs says:

    If you might test and output for more than one page in that function, I think I’d probably change it to a switch statement.

    Just to drive an old OOP tutor crazy :)

  • Jennifer says:

    Thank you so much! This is JUST what I needed for my client – 50 something Veterans…!

  • Shelley I really need this to work and if it does it will be a God send.

    However I have posted the code at the end of my theme functions.php file and unfortunely it doesn’t work. I am using WP 3.0.1 and the wasteland theme.

    I am not experienced with php but I have put the code between the so I haven’t made that basic error at least.

    What could prevent this working, any ideas? I have 8 plugins none of which alter the Dashboard as far as I know.



  • Shelly says:

    I’m not familiar with the Wasteland theme, but the above should be working okay if placed in your functions.php file.

    The first steps I would take in trying to troubleshoot this would be the following:

    1) Place the code in the functions.php file of the *default* theme.

    2) Deactivate your current theme and activate “Default.” If the code works, then you’ll know it’s something in the theme files (probably a function within the functions.php file).

    3) If that doesn’t work, try deactivating all of your plugins to see if it’s a plugin conflict. If it is, you’ll know which one is the culprit (deactivate one-by-one to see which one makes it “suddenly work.”

    4) If that still doesn’t work, it *could* possibly be a jQuery conflict. Right after the line that says < script type="text/javascript">, try adding in the following line:

    $output .= 'var $jHideFields = jQuery.noConflict();' . "\n";

    and then all the instances of “jQuery”you see after that, replace it with $jHideFields.

    Those are the only things I can think of off the top of my head. let me know what results you have if you try any of them.

  • Shaq says:


    i know its 3 years ago, but who cares :-)
    its not a jQuery conflict:

    change line 8 to:
    $output = “\n” . ” . “\n”;

    and line 19 to:
    $output .= ” . “\n”;

    thanks for the code

  • Have your say: