How to pass arguments from add_settings_field() to the callback function?

I have a function like this:

add_settings_field( 'contact_phone', 'Contact Phone', 'settings_callback', 'general');

That works. It calls settings_callback. Cool. The problem I have with this is: I don’t want to have to define a callback function for every setting I add, if all I’m doing is echoing out a little bit of stuff.

Read More
function settings_callback()
{
    echo '<input id="contact_phone" type="text" class="regular-text" name="contact_phone" />';
}

Why on earth should I have to do that? The id, class, and name should all be params.

Is there no way to pass params to the settings_callback function? I started looking at the core, got here: http://core.trac.wordpress.org/browser/tags/3.1.3/wp-admin/includes/template.php

..and ran into this $wp_settings_fields global. Where is this defined?

Related posts

Leave a Reply

1 comment

  1. Look at the declaration for the function:

    function add_settings_field(
        $id,
        $title,
        $callback,
        $page,
        $section = 'default',
        $args    = array()
    ) { }
    

    The last parameter takes your arguments and passes them to the callback function.

    Example from my plugin Public Contact Data

    foreach ($this->fields as $type => $desc) {
      $handle = $this->option_name . "_$type";
      $args   = array(
          'label_for' => $handle,
          'type'      => $type
      );
      $callback = array($this, 'print_input_field');
    
      add_settings_field(
          $handle,
          $desc,
          $callback,
          'general',
          'default',
          $args
      );
    }
    

    The function print_input_field() gets these arguments as first parameter:

    /**
     * Input fields in 'wp-admin/options-general.php'
     *
     * @see    add_contact_fields()
     * @param  array $args Arguments send by add_contact_fields()
     * @return void
     */
    public function print_input_field( array $args )
    {
        $type   = $args['type'];
        $id     = $args['label_for'];
        $data   = get_option( $this->option_name, array() );
        $value  = $data[ $type ];
    
        'email' == $type and '' == $value and $value = $this->admin_mail;
        $value  = esc_attr( $value );
        $name   = $this->option_name . '[' . $type . ']';
        $desc   = $this->get_shortcode_help( $type );
    
        print "<input type='$type' value='$value' name='$name' id='$id'
            class='regular-text code' /> <span class='description'>$desc</span>";
    }
    

    No need to touch a global variable.