Originally posted here: http://ottodestruct.com/blog/2009/wordpress-settings-api-tutorial/

When writing the Simple Facebook Connect plugin, I investigated how the Settings API worked. It’s relatively new to WordPress (introduced in version 2.7), and many things I read said that it was much easier to use.

It is much easier to use in that it makes things nice and secure almost automatically for you. No confusion about nonces or anything along those lines. However, it’s slightly more difficult to use in that there’s very little good documentation for it. Especially for the most common case: Making your own settings page.

So, here is my little documentation attempt.

Making your own settings page

First, add yourself an options page. Code to do that:

<?php // add the admin options page
add_action('admin_menu', 'plugin_admin_add_page');
function plugin_admin_add_page() {
add_options_page('Custom Plugin Page', 'Custom Plugin Menu', 'manage_options', 'plugin', 'plugin_options_page');

What this does is quite simple, really:

a. It adds a link under the settings menu called “Custom Plugin Menu”.
b. When you click it, you go to a page with a title of “Custom Plugin Page”.
c. You must have the “manage_options” capability to get there though (admins only).
d. The link this will be will in fact be /wp-admin/options-general.php?page=plugin (so “plugin” needs to be something only you will use).
e. And the content of the page itself will be generated by the “plugin_options_page” function.

Oh wait, we need that function! Let’s go ahead and create that, shall we?

<?php // display the admin options page
function plugin_options_page() {
<h2>My custom plugin</h2>
Options relating to the Custom Plugin.
<form action="options.php" method="post">
<?php settings_fields('plugin_options'); ?>
<?php do_settings_sections('plugin'); ?>

<input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes'); ?>" />


Hang on a minute, where’s all the options? Well, here’s where the Settings API kicks in a bit. Up to now, this has been more or less the same as previous tutorials. Adding the options pages is really quite easy. But now, we’re going to use two new functions.

First, we call settings_fields(‘plugin_options’). This outputs the hidden bits that we need to make our options page both do what we want and to make it secure with a nonce. The string “plugin-options” can be anything, as long as it’s unique. There is another call we’re going to have to make with this same string later.

Next, we call do_settings_sections(‘plugin’). This is going to output all of our input fields. Text input boxes, radio fields, anything we like. Obviously though, we have to tell it what those fields are and look like somewhere. We do both of these things in the next section.

Defining the settings

<?php // add the admin settings and such
add_action('admin_init', 'plugin_admin_init');
function plugin_admin_init(){
register_setting( 'plugin_options', 'plugin_options', 'plugin_options_validate' );
add_settings_section('plugin_main', 'Main Settings', 'plugin_section_text', 'plugin');
add_settings_field('plugin_text_string', 'Plugin Text Input', 'plugin_setting_string', 'plugin', 'plugin_main');

Here we’ve done three things. Let’s break that down, shall we?

<?php register_setting( 'plugin_options', 'plugin_options', 'plugin_options_validate' );?>

First, we register the settings. In my case, I’m going to store all my settings in one options field, as an array. This is usually the recommended way. The first argument is a group, which needs to be the same as what you used in the settings_fields function call. The second argument is the name of the options. If we were doing more than one, we’d have to call this over and over for each separate setting. The final arguement is a function name that will validate your options. Basically perform checking on them, to make sure they make sense.

Ignoring the validation function for a moment, lets move on to the setting section. This one is actually quite simple.

<?php add_settings_section('plugin_main', 'Main Settings', 'plugin_section_text', 'plugin'); ?>

This creates a “section” of settings.
The first argument is simply a unique id for the section.
The second argument is the title or name of the section (to be output on the page).
The third is a function callback to display the guts of the section itself.
The fourth is a page name. This needs to match the text we gave to the do_settings_sections function call.

That function callback in the third argument should look a bit like this:

<?php function plugin_section_text() {
echo '<p>Main description of this section here.</p>';
} ?>

Simple, really. You can put any HTML you like here.

Now that we’ve talked about the section itself, we need to talk about the fields in that section.

<?php add_settings_field('plugin_text_string', 'Plugin Text Input', 'plugin_setting_string', 'plugin', 'plugin_main'); ?>

The first argument is simply a unique id for the field.
The second is a title for the field.
The third is a function callback, to display the input box.
The fourth is the page name that this is attached to (same as the do_settings_sections function call).
The fifth is the id of the settings section that this goes into (same as the first argument to add_settings_section).

The only difficult one here is, again, the callback. Let’s look at that, shall we?

<?php function plugin_setting_string() {
$options = get_option('plugin_options');
echo "<input id='plugin_text_string' name='plugin_options[text_string]' size='40' type='text' value='{$options['text_string']}' />";
} ?>

Simple. It just gets the options then outputs the input HTML for it. Note the “name” is set to plugin_options[text_string]. This is not coincidence, the name *must* start with plugin_options in our case. Why? Because that is the second argument we passed to register_settings.

The settings pages use a whitelist system. Only valid options get read. Anything else gets tossed out, for security. Here, we’re using a php trick. PHP interprets an incoming GET or POST data of name[thing] as being an array called name with ‘thing’ as one of the elements in it. So, all our options are going to take the form of plugin_options[some_thing], so that we get that single array back, and the array name itself is whitelisted.

Since this is designed with security in mind, we have one last callback to deal with: The validation callback that we skipped earlier:

<?php // validate our options
function plugin_options_validate($input) {
$newinput['text_string'] = trim($input['text_string']);
if(!preg_match('/^[a-z0-9]{32}$/i', $newinput['text_string'])) {
$newinput['text_string'] = '';
return $newinput;

Here I’m taking a liberty with the code. I’m going to say that our text_string has to be exactly 32 alphanumerics long. You can actually validate any way you want in here. The point of this function is simply to let you check all the incoming options and make sure they are valid in some way. Invalid options need to be fixed or blanked out. Finally, you return the whole input array again, which will get automatically saved to the database.

Take special note of the fact that I don’t return the original array. One of the drawbacks of this sort of approach is that somebody could, in theory, send bad options back to the plugin. These would then be in the $input array. So by validating my options and *only* my options, then any extra data they send back which might make it here gets blocked. So the validation function not only makes sure that my options have valid values, but that no other options get through. In short, $input is untrusted data, but the returned $newinput should be trusted data.

Update: What if you have multiple options screens? Or just want to only be able to edit a few of your options? One downside of the validation method I detail above is that your single plugin_options field gets completely replaced by $newinput. If you only want to have it change a few of your options, then there’s an easy technique to do that:

<?php // validate our options
function plugin_options_validate($input) {
$options = get_option('plugin_options');
$options['text_string'] = trim($input['text_string']);
if(!preg_match('/^[a-z0-9]{32}$/i', $options['text_string'])) {
$options['text_string'] = '';
return $options;

Basically I load the existing options, then update only the ones I want to change from the $input values. Then I return the whole thing. The options I don’t change thus remain the same.

And we’re done. Wait, what?

Yes, the whole point of this exercise is that the options are automatically saved for you. And everything else. You have an options page, you have fields on it, you are validating them… and that’s it. The actual *display* of the page is even done for you. Remember the input we made? It’ll get put into a table with the title on the left side before it, waiting for input.

Another nice thing is that this is easily expandable. For each option to add we:
1. Do a new add_settings_field call.
2. Make the function to display that particular input.
3. Add code to validate it when it comes back to us from the user.

To add a new section, you:
1. Do a new add_settings_section call.
2. Make the function to display any descriptive text about it.
3. Add settings fields to it as above.

One last thing

Sometimes we don’t need a whole page. Sometimes we only have one setting, and it would work well on some existing page. Maybe on the general page, or the discussion page. Well, we can add settings to those too!

If you look through the core code, you’ll find references like do_settings_sections(‘general’) or do_settings_sections(‘writing’), and so on. These you can add on to like any others, getting your settings on the main WordPress settings pages instead of having to make your own.

Just do this:
1. Make an add_settings_section call. The last argument should be “general”, or wherever you want to add your new section.
2. Add fields to your new section, using add_settings_field.
3. You still need to make your own settings whitelisted. To do this, you’ll need to make a call to register_setting. The first argument should be the same as the page name, like ‘general’, or wherever you’re putting your settings. This will let that page recognize and allow your settings to come through.

All the callbacks will basically be the same for this method. You’re just skipping a step of making your own page. Easy.

And there you go. More reading: http://codex.wordpress.org/Settings_API



  1. for clarities sake, this nice tutorial would work much better if you used something like “myplugin” for those parts that can be name freely

    • Agreed. It’s difficult to follow which strings are meant to be literals and which are programmer-defined. I’m guessing as I go along.

      Also, it’s bad style to mix languages — in this case, HTML and PHP. I know it’s the whole raison d’etre of PHP to be able to mix it freely, but just because PHP does it doesn’t mean it’s right. (In fact, the opposite is usually true.) It would be better to use print "<div>\n"; than <?php <div> ?> throughout. Readability would be vastly improved.

      Finally, your clever syntax highlighting thingy doesn’t seem to work with the Linux clipboard, as far as I can tell. That might be a Firefox thing; I don’t know.

      But apart from these minor nitpicks, thank you very much — I’m on a deadline to produce two rather fiddly plugins, and you’re a life saver.

      • Sorry guys, Otto’s a gifted programmer and you’d be hard pressed to find better resources on the net toward this subject on admin panels. Otto, I have a question – I’d like to make use of 1.10ui (assuming this is next step up), and have take a look at a load of plugins to see what parts are being used to make accordions with hoverIntent/sorting/easing/css/buttons work properly (in the admin panel only, option page) – I can’t for some reason get the accordion working properly without hopping to CDN – I have seen one plug in with a custom script “easing.js” which seemed rather odd – can you list the scripts or pieces that may be missing from the native core (or confirms that it works come 3.6 and just overlooking something) I don’t care much for how WP breaks up the build it’s so counter intuitive – it makes so much more sense to throw in different versions of JQuery, not pieces of it. In fact, many themes and plugs may have been compromised due in part to the fact the native build is so limiting and authors needed to find a way to circumvent what was there to suit their needs, and maybe cause potential conflicts. If you have a better reason besides file size for why WP does this, I’d also like to hear an opinion on this.

        • eburnett: I can’t make much sense out of your post, but if you’re having problems like “I can’t for some reason get the accordion working properly without hopping to CDN”, then I expect that you’re using code which assumes “$” instead of “jQuery”.

          WordPress loads jQuery in noConflict mode. You need to use a noConflict wrapper around your $ based code.

          See http://codex.wordpress.org/Function_Reference/wp_enqueue_script#jQuery_noConflict_Wrappers

          • I’m trying to run in no-conflict mode, but what I mean about not having all the parts is this – just have a look at the base scripts that WP includes…it’s all chopped up so going in it’s a guessing game trying to tell what’s actually in there – the css to smoothness is part of what I’d like to include, WP does not include these so I’d have to point outward or include them in, nor the buttons – from what I can tell on the included scripts page on the codex it seems like all the parts are there that are needed minus the styling…enqueueing/hooking is ok – it’s just when the CDN ui I have link is pulled out it no longer works. I am using shortcut but I’ve defined an $ function in the document ready – I’m assuming I should be ok? – I kind of scrapped the model and went with a different approach but will be coming back to this issue and hoping to get everything working properly after glueing the panel together.

            • Again, not really giving me enough information to understand what you’re talking about. What CSS is not included? What are you trying to accomplish?

              I’m no master of jQuery and so I don’t know it all off the top of my head, so posting some links, or references, or explanations of what it is that you’re trying to do would be more helpful.

              jQuery is a javascript library. It doesn’t have any CSS. If you want to include some jQuery UI themes, then just, you know, include them. They’re not in core. Nor should they be, really. Needless bulk. Third-party code that uses them can include them itself.

    • Hey Otto,

      Awesome tute. It’s hard to piece together how all the WP functions hang together, just using the codex. You’ve bridged the gap really, really nicely. Thanks.

      Regarding idleberg’s comment above, something I’ve done in the past (and will be using here) is remove these “magic strings” and replace them with constants declared the once. This makes for more maintainable code, but in this case would make it really clear where these constants are actually linking the pieces together.

      Eg, with


      at the top, you could then replace all references of 'plugin' with PLUGIN_HANDLE and appropriate 'plugin_options' with PLUGIN_OPTIONS_HANDLE.

      Just an idea!

      Thanks again, great tute.

  2. Hi,

    It seems I can’t used your solution for multiple option screen. It just… Won’t work! I’ve opened a stackexchange on the question, feel free to drop by if you (anyone! :P) can help! 🙂


  3. While this is great, can you say more about files and locations as i cannot get my admin menu to appear, but the plugin is showing in active plugins.

    I appreciate the effort you have put into this, but to get here, i have gone through several wordpress documentation pages that seem to see admin menus as something separate so provide a link. In that passing off, no-one seems to mention the file name for where this code goes or another means of including it. For instance xoops has a specific file name you must use in your module for the admin stuff.


    • Look at the tutorial again. Adding the options page is literally the first bit of code in this post.

      See that line that says “add_options_page”? That adds the options page and the associated menu item to get there. Next, the bit with the plugin_options_page function? That outputs the HTML to displays the options page.

      There’s no code needed to make an admin menu, it does that for you when you add the admin page.

      WordPress doesn’t use a file structure for this sort of thing. You specify it in the code.

  4. Your tutorial explains the functions pretty well, but the code is not working. It looks like you have syntax errors in places, and all I seem to get is white screen no matter what I do. It would be really useful if you had a working version of the code posted as the Codex points to your tutorial as a “better example” of making this happen.

  5. Great job, nice tutorial.
    Just a question on the validation bit: I was wondering how I could possibly output some text explaining to the user why his input has been rejected.
    Any idea?

  6. Hi,

    Thanks for the great tutorial.

    I have seen a few tutorials on the subject and none of them explain where the changes are saved to.
    Once the option is set up, when the admin makes changes to whatever option was created, where is the data saved to when the submit button is clicked? Maybe I am missing something but I cant figure it out 🙂

    Also, in this tutorial and most tutorials I have seen no one ever mentions which file the code should go into. I just put it all in functions.php but could I put it in any file even a new one I creat in the theme folder?


  7. […] Oriented WordPress Development bookShow Template pluginOtto’s favorite pluginsOtto on FacebookOtto on the WordPress Settings APIOtto on the WordPress 3.4 theme customizerWordPress BBQ teamDisclaimer: Automattic has advertised on […]

  8. hi,

    great post. I’m starting to create my options page and your tutorial was a great help.

    I have one question, how do i use my options on a theme page?

    Let me explain, one of my options will be the link to a youtube video, so what i’d like to do is put somewhere on my code the content of that option. like

    can you help me on this?

  9. hey this is great and has helped a lot but could you expand this to include a little validation failure notice? I’ve seen the add_settings_error documentation but i cant get it to work with your example

  10. […] WordPress has an extensive article on how these new features work. I also recommend a review of his WordPress Settings API Tutorial. Chip Bennett describes even more on how to update your WordPress Theme for custom backgrounds and […]

  11. can you provide a downloadable file?

  12. Does this mean we have to register every single input field and write a callback for it, that itself calls get_option() so we can display the old value? I wonder how useful this is for big settings pages…

  13. Also, your function plugin_setting_string() will create a PHP Notice if the option is not yet set.

    • Notices are not errors. This is demo code, intended to show how something works. If you understand how the Settings API works from this demo code, then the goal has been accomplished. Not every bit of PHP code in the world has to be letter perfect.

  14. Hi Otto,

    Thanks for this great tutorial here. This gave me a new idea to make my second plugin after finishing my very first. Of course this time with option settings page. Soon, I will release it at http://www.annupex.com and WordPress repository.

  15. hi otto,

    i didnt want an array to use with the options, so i have 2 seperate options. so i made 2 add_settings_field and register_settings. it all puts it down nicely but the problem is that it doesnt save the options when i click on save changes. do you know why? my code: http://pastebin.com/Xr6Wvhhw thx in advance!

  16. Hi Otto,
    Your tutorial is very helpful for me. But so far as I can see it only storing static data. What I looking for is to storing dynamic data in the wp_options table, where user can add,read,delete and update the data.

    Is it possible to do so?


  17. Hi Otto,

    I found your tutorial really useful, it helped me to get my framework for my plugin working.

    Now I have a challenge to create an options page that can be used with an array of objects to add, delete, or edit these data objects.

    The objects are for url shortening e.g. shortname and url to redirect to, plus an integer to count the clicks.

    The options page will display a table of the current links plus click count, and have a delete button, and edit button per row. And an Add new item function.

    So I am wondering if this new way to simplify creation of an options page will be suitable in my case? I am thinking that I can maybe use the validate function to massage the input data into my object format.

    • I worked out how to do it. The option data can be a 2-dimensional array so it’s easy to map the array elements to a table of input fields.

      I use the validate function to check for deleted items i.e. where the first table column value is blank.

      And my table has a blank row at the end to allow for adding new items.

    • Dear Andy

      I am working on a similar requirement that is, to create an options page where I can add, delete or edit data objects.
      I am not able to figure out the way to utilize Otto’s tutorial to achieve the requirements.

      Will it be possible for you to share your code (leaving out the sensitive information) that can help me.
      I would appreciate your kind help.


  18. I keep getting an error when I try to update my option…
    “Warning: Cannot modify header information – headers already sent by (output started at /home/content/…”

    The data exists in the database but when I try to modify the parameter it comes up with that every time.


  19. Hi Otto, Great tutorial.. I’m almost there. I have everything set up but after I save changes my fields only say “Array”. My code is below.. any suggestions?


  20. What I don’t get is that you say that in order to add a new option, you just add a “add_settings_field” but how does that connect to the registered option? If you do get_option(‘option_group’, ‘option_name’), that is tied to ONE registered setting. So wouldn’t you need to add an additional “register_setting” AND a “add_settings_field” along with its callback just to add another field in order to retrieve it using get_option???

  21. […] If it helps, I’ve been building this settings page in the same file as the plugin itself, with the help of this guide: http://ottopress.com/2009/wordpress-settings-api-tutorial/ […]

  22. I feel like I must be missing something… I’ve followed this tutorial and several others, and now I have a lovely settings page, but it doesn’t actually save my settings. Is this really all you need to do to get a settings page working, or do I need to add some more code to save the settings to the database and use them in my plugin?

  23. i tried your solution but register_setting() callback returns NULL input to me. Can anyone tell me where is the exact problem??

    register_setting( 'theme_hcg_options', 'theme_hcg_options', 'theme_logo_validate');

    function theme_logo_validate($input){
    $default_option = hcgDefaultOptions();
    $logoURL = $default_option;


    $submit = !empty($input['submit']) ? TRUE : FALSE;

    $logoURL['hcg_logo'] = trim($input['hcg_logo']);
    $logoURL['hcg_logo'] = "Error";

    return $logoURL;

  24. options.php 404 not found – has wordpress changed since this was write?

  25. Dear Zohan,
    I recently (15 days back) utilized this tutorial with WordPress 3.5.1 and its working fine.
    I don’t have any trouble making it work.

    Plz try again and check

  26. Hey Otto,

    Thanks for the tut. I do have one issue though. I copied your code verbatim but when I click save, the page refreshes but the data I entered in the text box (“this is a test”) does not show up. I made an empty check in the validate function on the $options array (using the second validation method) and $options array is empty. I was wondering what could be the problem since everything looks OK to me.



  27. I copied it from above, but here it is:

    function plugin_options_validate($input) {
    $options = get_option('plugin_options');
    $options['text_string'] = trim($input['text_string']);
    if(!preg_match('/^[a-z0-9]{32}$/i', $options['text_string'])) {
    $options['text_string'] = '';
    return $options;

    • Okay, well, that example validation code rejects any text that is not a 32-character long alphanumeric. You need to write your own validation code, to validate to what you expect the input to actually be.

  28. Ok, this is what the entire code looks like. I commented out the validation and returned the array as is, but still no data. Deleted cache and refreshed. So I’m pretty sure I messed it up somewhere.

    // add the admin options page
    add_action('admin_menu', 'plugin_admin_add_page');
    function plugin_admin_add_page() {
    add_options_page('Custom Plugin Page', 'Custom Plugin Menu', 'manage_options', 'plugin', 'plugin_options_page');

    // display the admin options page
    function plugin_options_page() {

    My custom plugin
    Options relating to the Custom Plugin.

    <input name="Submit" type="submit" value="" />


    // add the admin settings and such
    add_action('admin_init', 'plugin_admin_init');
    function plugin_admin_init(){
    register_setting( 'plugin_options', 'plugin_options', 'plugin_options_validate' );
    add_settings_section('plugin_main', 'Main Settings', 'plugin_section_text', 'plugin');
    add_settings_field('plugin_text_string', 'Plugin Text Input', 'plugin_setting_string', 'plugin', 'plugin_main');

    function plugin_section_text() {
    echo 'Main description of this section here.';

    function plugin_setting_string() {
    $options = get_option('plugin_options');
    echo "";

    // validate our options
    function plugin_options_validate($input) {
    $options = get_option('plugin_options');
    $options['text_string'] = trim($input['text_string']);
    if(!preg_match('/^[a-z0-9]{5}$/i', $options['text_string'])) {
    $options['text_string'] = '';
    return $options;

    • Yeah, that won’t work either because now you’re not doing anything with the $input variable.

      The $input variable contains your new settings. The $options variable contains the old settings. You need to merge the new, validated settings into the $options array and then return that.

  29. I keep getting a “Warning: Illegal string offset ‘text_string'” error when trying to save the input fields’ values.

    The database field is appearing but with an empty value. I can’t figure out where you’re getting the ‘text_string’ value in this line:

    echo “”;

  30. Hi,

    I am newbie. My basic question is what will be the appropriate location to put the above sample code given? I am not very much familiar with anatomy of wordpress right now. Do I need to create a separate plugin for this or i can put this code in functions.php? Please guide me.


  31. Would it be possible to wrap this into a page template and display plugin settings from the front end on a page?

  32. Great tutorial!
    You forgot to concatenate value='{$options[‘text_string’]}’
    Would spit errors for the people who are doing copy paste,
    and isn’t defining default values in array is a good idea?

  33. I tested this code. Took me a while to understand the code (total newbie) but it definitely works. Great tutorial! Thanks for this Otto. Been to wordpress but couldn’t create an options page using the info there. Then I got here and accomplished what I wanted to learn. Thanks, man!

  34. This is a great tutorial and all but you didnt explain how to fetch the stored information. Or how to make the information actually store. Can you refer me to a good resource where I can learn more?

  35. mine is outputting this to my page literally instead of showing the actual id/name/value:


  36. mine is outputting this to my page literally instead of showing the actual id/name/value:

    input id=”plugin_text_string” name=”plugin_options[text_string]” size=”40″ type=”text” value=””


  37. never mind, got it. was using the plugin_options_validate() from the example so it was not saving.

  38. […] For more reference on creating admin options, see Codex and Otto’s tutorial. […]

  39. Could you please tell me how to add Combo box, Radio Button instead of text box ?

  40. […] best and clearest guide I could find to the not so intuitive WordPress Settings API was the one by Otto on WordPress. I’ve read other guides on the matter but when it comes to clarity this is the best and it […]

  41. Found this tutorial rather hard to follow since it provided no full code samples. Which parts go where… ect.

    Tried various versions of this but wasn’t able to get it to do anything.

  42. hello, great tut
    need help on how to validate another value in option array

    function validate($input) {
    $options = get_option(‘settings’);
    $options[‘a’] = trim($input[‘a’]);
    $options[‘b’] = trim($input[‘b’]);

    if(!preg_match(‘/^[a-z0-9]{32}$/i’, $options[‘Candle’])) {
    $options[‘a’] = ”;}

    if(!preg_match(‘/^[a-z0-9]{32}$/i’, $options[‘Havdala’])) {
    $options[‘b’] = ”;}

    return $options;

  43. The last 2 functions you describe:

    function plugin_setting_string() {
            $options = get_option('plugin_options');
            echo "<input id='plugin_text_string' name='plugin_options[text_string]' size='40' type='text' value='{$options['text_string']}' />";


        // validate our options
        function plugin_options_validate($input) {
            $newinput['text_string'] = trim($input['text_string']);
            if(!preg_match('/^[a-z0-9]{32}$/i', $newinput['text_string'])) {
                $newinput['text_string'] = '';
            return $newinput;

    Should these be inside the function:

    function plugin_admin_init(){


    Could you perhaps add source file’s so I can download them and compare them.

  44. Still working on this, I think I may have to create a dummy plugin with all your settings to actually see if they work instead of trying to apply to my existing plugin.

    So far no matter what I always get options page doesn’t exist when I try to save.

    My plugin is a bit different in that I’m not just adding a page in settings, I have my own options page under my plugins menu so it’s a little confusing which parts should go in my plugin file, the settings file i have, or the display file for the options page.

    • Tutorial has: register_setting( ‘plugin_options’, ‘plugin_options’, ‘plugin_options_validate’ );

      First is Group ID.

      Tutorial has: settings_fields(‘plugin_options’);

      WP Codex says settings_fields is looking for Group ID not Name.

      Should be settings_fields(‘plugin-options’);

      Not that it works this way for me either. =)

      Now the page just reloads without saving (Yes i have entered in valid data).

      • Sorry I am mistaken, tutorial has it correct as “plugin_options”.

        • Appears on my separate options.php page, the get_option is not working.

          And the plugin_options_validate also never gets called.

          (I have plugin_section_text(), plugin_setting_string(), and plugin_options_validate all inside my options.php which is the page that outputs the form.)

          • I finally got this working with between multiple pages. I don’t have a specific fix that I can share, but my advice if someone else is stuck is to make sure that:

            – your functions are being called
            – the expected data is in the expected placed

            All of these settings have some reference to another setting so just double check that everything is named consistantly and good luck.

  45. […] Build an Option Panel for your WordPress Plugin Building your first WordPress plugin WordPress Settings API Tutorial […]

  46. If I do
    ‘Settings Admin’,
    ‘My Settings’,

    I get “You do not have sufficient permissions to access this page.” when i click on the page link in the settings menu

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Need to post PHP code? Wrap it in [php] and [/php] tags.