In: , ,
On: 2009 / 12 / 28 Viewed: 37862 times
Shorter URL for this post:

The essence of plugins is giving to WordPress users more control over their blog, that is, most of the time, more options. Typically, a plugin adds a page under the Settings menu, where you can modify the options (see this article on register_setting() for best practices).

But if you think about multi user blogs, it can make sense to implement per user options instead of "global" settings. And guess what? It's dead easy.

First, a few theory, then a complete example. Scroll down if you're the kind of guy who likes code, not explanations :)

Modify the "Profile" page

What we are going to do is play with the action hooks provided by file wp-admin/user-edit.php to add some fields to the profile page, then save them.

To add content (ie fields, checkboxes, texareas…) to the profile page, you can use any of the 3 actions:

  • personal_options: append content to the "Personal Options" block
  • profile_personal_options: add content after the "Personal Options" block (like add a whole new custom block)
  • show_user_profile: add content right before the "Update Profile" button

For instance, to add content within the "Personal Options" block, you simply need to do something like:

  1. add_action('personal_options', 'ozh_personal_options');
  2. function ozh_personal_options() {
  3.     echo "<p>Content added by action 'personal_options'</p>";
  4. }

These action hooks will pass one parameter to your function (that is ozh_personal_options() in the above example) containing a WP_user object.

Save custom per user data

Simply adding fields and pressing "Update Profile" won't do, you need to tell WordPress what you want to save. Hook into action personal_options_update and sanitize, I mean, SANITIZE, the POSTed data. This action will pass the user ID as a parameter to your custom function. Example:

  1. add_action('personal_options_update', 'ozh_save_user_setting');
  2. function ozh_save_user_setting( $user_id ) {
  3.     $option = ( $_post['somecheckbox'] == 'yes' ? 'yes' : 'no' ); // sanitize: accept only 'yes' or 'no'
  4.     update_usermeta( $user_id, 'some_user_options', $option  );
  5. }

Complete example of a plugin with per user setting

Let's make a dummy plugin that will allow registered users of a blog to be nagged by a silly javascript alert box on every admin page they'll visit.

  1. <?php
  2. /*
  3. Plugin Name: Example plugin - Per User Settings
  4. Plugin URI:
  5. Description: Add a silly per user setting to your <a href="profile.php">Profile</a> page
  6. Author: Ozh
  7. Author URI:
  8. */
  10. // Add a custom field to the form in "Profile"
  11. function ozh_user_setting_alert_box($user) {
  12. ?>
  13.     <tr>
  14.         <th scope="row">Add Alert Box</th>
  15.         <td><label for="ozh_add_nag">
  16.         <input name="ozh_add_nag" type="checkbox" id="ozh_add_nag" value="1" <?php checked('1', $user->ozh_add_nag); ?> /> Add a silly and annoying alert box on each admin page
  17.         </label></td>
  18.     </tr>
  19. <?php
  20. }
  22. // Handle data that's posted and sanitize before saving it
  23. function ozh_save_user_setting_alert_box( $user_id ) {
  24.     $ozh_add_nag = ( !empty($_POST&#91;'ozh_add_nag'&#93;) ? 1 : 0 );
  25.     update_usermeta( $user_id, 'ozh_add_nag', $ozh_add_nag );
  26. }
  28. // Now, the per user behavior itself: add the silly alert box if applicable
  29. function ozh_get_user_setting_alert_box() {
  30.     if( get_user_option('ozh_add_nag') ) {
  31.     ?>
  32.     <script type="text/javascript">
  33.         alert("Annoying, isn't it?");
  34.     </script>
  35.     <?php
  36.     }
  37. }
  39. // Hook everything
  40. add_action('personal_options', 'ozh_user_setting_alert_box');
  41. add_action('personal_options_update', 'ozh_save_user_setting_alert_box');
  42. add_action('admin_head', 'ozh_get_user_setting_alert_box');
  44. ?>

For your convenience, the above plugin example and a few more inline comments is available here (rename as .php)

Best practices

A few things you'll want to do:

  • Visual integration: use the same markup and CSS classes than the latest WordPress as of date to add rows and fields. Your plugin must add content to the profile page as if it was a built-in option. I hate it when plugin options look like weird plugin option. It must look like WordPress.
  • Data sanitization: don't save blindly and assume everything posted will be stupid or malicious. If you're expecting an integer, use intval(). If you're expecting one value from a set, explicitely test for each value. If you're expecting free text including HTML, use esc_html(). And so on. Sanitize everything.
  • Data concatenation: if you're going to add several options, please, put them in one array and save only this one entry.
  • Wise implementation: sometimes it just makes sense to have a standalone plugin option page with global settings instead of per user settings. The typical WordPress blog is a single user blog.

Shorter URL

Want to share or tweet this post? Please use this short URL:


This entry "How To: Per User Options in WordPress" was posted on 28/12/2009 at 3:46 pm and is tagged with , ,
Watch this discussion : Comments RSS 2.0.

12 Blablas

  1. John Taylor says:

    Thanks for this great article..

  2. johnbillion says:

    There's a fourth place on the Profile screen where you can add fields.

    By filtering 'user_contactmethods' you can quickly add a text input field to the Contact Info section. You can also use the filter to remove or rename the existing fields if so inclined.

    Here's some example code:

    function my_user_contactmethods($methods){
    $methods['phone'] = 'Phone Number';
    return $methods;

    The above code will add a 'Phone Number' text input to the Contact Info section.

    Note that you still have to include the code to manually update the user meta when the form is submitted, as in Ozh' examples.

  3. Jerry says:

    I am using you wordpress admin menu plugin and was wondering if it is possible to ad an option to sort the menu items!

    Thanks. Love the plugin!


  4. wykydtron says:

    I cant seem to get it to work on multiple authors in 3.0

  5. Bofy says:


    I want to write a simple plugin for my WordPress blog but I didn't find any documentation for what I need.

    I want to have a settings/options page to save each user's website URL (by user ID) on a separate admin menu page, not on the Profile page.

    I want to give each Logged In user the possibility to save and see the settings page with their individual options saved.

    Can you post on your website an example, please?
    I would appreciate if you send me a link to an example or tutorial regarding my problem.


  6. John says:

    Thanks for showing your code. I actually use something similar to what you showed to prevent registered users from seeing a part of the dashboard that should be limited to admins!

  7. John says:

    Wow I just noticed the nifty flag plugin you have beside each commenter's name. Can you please forward me the name of that? I think it would be a wonderful addition to my site! Thanks!

  8. Ozh says:

    John ยป My own plugin IP to Nation

  9. John says:

    Thanks Ozh, I shall definitely check it out. It will be so handy for my site!

  10. Thomas says:

    I always wondered how these things are really done. Thanks for showing! Now I am sure I will never be able modify any code to adjust it to my needs. I shall always ask for expert help. Thanks once more!

  11. Zach Reed says:

    This is awesome. Is there a way to default it checked, so when the plugin is on, all users are defaulted to it checked and "on", but then they can go to their profile to turn it off?

    Thanks! :)

  12. Roelof says:

    Hi Ozh,

    I know this is a pretty old post. Hope you will still read it though.

    Could you point me in the right direction of writing a plugin for users instead of admin?

    Thanks a bunch!

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Gravatars: Curious about the little images next to each commenter's name ? Go to Gravatar and sign for a free account
Spam: Various spam plugins may be activated. I'll put pins in a Voodoo doll if you spam me.

Read more ?