I have a plugin page created with add_submenu_page, I want to add a new section there but nothing happens:

add_submenu_page('parent', 'Foo', 'Foo', 'manage_options', 'foo-settings', 'anothercallback');
add_settings_section('foo-settings-section', 'Settings', 'acallback', 'foo-settings');

What's the right call to use it in a custom page? Do you have a complete example?

  • Do you have an "acallback" function defined?
    – tollmanz
    Aug 22, 2011 at 20:12
  • Yes, i have it defined.
    – thom
    Aug 22, 2011 at 20:30
  • Do you get any output? i.e. do you get your add_settings_section() callback text output? How is your add_submenu_page() callback defined? Can we see that code? Aug 22, 2011 at 20:42
  • Actually I've used an inline function definition (param, function () { echo 'here'; }, param); I'm running PHP 5.3. Thanks
    – thom
    Aug 22, 2011 at 20:45
  • Can you post all relevant code? Otherwise, it will be incredibly difficult to figure out where the problem is. Aug 22, 2011 at 23:04

2 Answers 2


The add_settings_section() function simply registers a form section with a certain slug with WordPress. In order to get the section and all the fields you've added to it to display on a certain menu page, you need to include the do_settings_sections($sections-slug) method in the menu's callback. This is, of course, assuming you are using the Settings API, which add_settings_section is part of.


function plugin_admin_init() {
     //All callbacks must be valid names of functions, even if provided functions are blank
     register_setting( 'option_group', 'option_name', 'sanitize_callback' );
     add_settings_section( 'section_id', 'section_title', 'section_callback', 'section_page_type' );
     add_settings_field( 'field_id', 'field_title', 'field_callback', 'section_page_type', 'section_id' );
add_action( 'admin_init', 'plugin_admin_init' );

function add_menus() {
     add_menu_page( 'menu_page_title', 'menu_title', 'menu_capability', 'menu_slug', 'menu_callback');
     add_submenu_page( 'menu_slug', 'submenu_page_title', 'submenu_title', 'submenu_capability', 'submenu_slug', 'submenu_callback' );
add_action( 'admin_menu', 'add_menus' );

function submenu_callback() {
     <div class='wrap'>
          <form method='post' action='options.php'>
               /* 'option_group' must match 'option_group' from register_setting call */
               settings_fields( 'option_group' );
               do_settings_sections( 'section_page_type' );
               <p class='submit'>
                    <input name='submit' type='submit' id='submit' class='button-primary' value='<?php _e("Save Changes") ?>' />

I did my best to keep all the parameter names unique, so you should be able to pick them apart and trace where they go. The Settings API gets very specific about what needs to go where, so make sure you have that all right. Also, keep in mind that I omitted all the callback functions from this example, but in reality they are necessary.

  • I do have this call too :(
    – thom
    Aug 22, 2011 at 21:16
  • @thom Ok, here's a full example generalized from some working code I have.
    – Chiubaka
    Aug 22, 2011 at 23:09
  • Thank you. The problem was with do_settings_section's parameter.
    – thom
    Aug 23, 2011 at 11:16
  • The only situation where do_settings_sections($sections_slug) is not necessary, to exhibit sections previously added to a submenu page, is when you add your sections to a pre-existing submenu page, like those in Settings menu (general, writing, reading, discussion, media, permalink). Apr 11, 2019 at 0:41

This is your problem, in your add_submenu_page() callback:

settings_fields( 'option_group' );
do_settings_section( 'section_page_type' );

For settings_fields():

  • You need to use the $optiongroup parameter you passed to register_setting().

For do_settings_sections():

  • The function is do_settings_sections(), not do_settings_section() (note plural)
  • You need to pass the $pageid parameter you passed to add_submenu_page().


Er, nevermind. I was responding to someone else's answer, which I misread as the actual callback function markup. The answers here may or may not apply; we still need to see the full code, including callbacks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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