Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a set of settings fields:

(...)
add_settings_field( 'Option1', 'Option 1', 'textarea', 'page1', 'plugin_options');  
add_settings_field( 'Option2', 'Option 2', 'textarea', 'page1', 'plugin_options'); 
add_settings_field( 'Option3', 'Option 3', 'text_input', 'page1', 'plugin_options');  
add_settings_field( 'Option4', 'Option 4', 'text_input', 'page1', 'plugin_options');
(...)   

All tutorials and Codex state that I have to create separate rendering functions for each settings field, but wouldn't be it much easier to create just basic functions for all input fields like checkbox, radio button, textarea etc. and reuse them?

I believe it will work smoothly if I'll be able to pass fields id to these functions, but I'm not sure how?

function textarea() {
    $options = get_option('my_settings');
    echo "<textarea id='[how to get ID?]' name='my_settings[[how to get ID?]'>{$options['how to get ID?']}</textarea>";
}
share|improve this question

1 Answer 1

up vote 7 down vote accepted

You're absolutely right that you can pass reusable form field markup to add_settings_field(). The trick is to define the data type for each setting, and then pass the same callback to each call to add_settings_field(). Within that callback, you simply add a switch that includes cases for each data type.

Here's how I do it in Oenology:

First, I dynamically output all calls to add_settings_field():

<?php
/**
 * Call add_settings_field() for each Setting Field
 * 
 * Loop through each Theme option, and add a new 
 * setting field to the Theme Settings page for each 
 * setting.
 * 
 * @link    http://codex.wordpress.org/Function_Reference/add_settings_field    Codex Reference: add_settings_field()
 * 
 * @param   string      $settingid  Unique Settings API identifier; passed to the callback function
 * @param   string      $title      Title of the setting field
 * @param   callback    $callback   Name of the callback function in which setting field markup is output
 * @param   string      $pageid     Name of the Settings page to which to add the setting field; passed from add_settings_section()
 * @param   string      $sectionid  ID of the Settings page section to which to add the setting field; passed from add_settings_section()
 * @param   array       $args       Array of arguments to pass to the callback function
 */
foreach ( $option_parameters as $option ) {
    $optionname = $option['name'];
    $optiontitle = $option['title'];
    $optiontab = $option['tab'];
    $optionsection = $option['section'];
    $optiontype = $option['type'];
    if ( 'internal' != $optiontype && 'custom' != $optiontype ) {
        add_settings_field(
            // $settingid
            'oenology_setting_' . $optionname,
            // $title
            $optiontitle,
            // $callback
            'oenology_setting_callback',
            // $pageid
            'oenology_' . $optiontab . '_tab',
            // $sectionid
            'oenology_' . $optionsection . '_section',
            // $args
            $option
        );
    } if ( 'custom' == $optiontype ) {
        add_settings_field(
            // $settingid
            'oenology_setting_' . $optionname,
            // $title
            $optiontitle,
            //$callback
            'oenology_setting_' . $optionname,
            // $pageid
            'oenology_' . $optiontab . '_tab',
            // $sectionid
            'oenology_' . $optionsection . '_section'
        );
    }
}
?>

And here's how I define oenology_setting_callback():

<?php
/**
 * Callback for get_settings_field()
 */
function oenology_setting_callback( $option ) {
    $oenology_options = oenology_get_options();
    $option_parameters = oenology_get_option_parameters();
    $optionname = $option['name'];
    $optiontitle = $option['title'];
    $optiondescription = $option['description'];
    $fieldtype = $option['type'];
    $fieldname = 'theme_oenology_options[' . $optionname . ']';

    // Output checkbox form field markup
    if ( 'checkbox' == $fieldtype ) {
        ?>
        <input type="checkbox" name="<?php echo $fieldname; ?>" <?php checked( $oenology_options[$optionname] ); ?> />
        <?php
    }
    // Output radio button form field markup
    else if ( 'radio' == $fieldtype ) {
        $valid_options = array();
        $valid_options = $option['valid_options'];
        foreach ( $valid_options as $valid_option ) {
            ?>
            <input type="radio" name="<?php echo $fieldname; ?>" <?php checked( $valid_option['name'] == $oenology_options[$optionname] ); ?> value="<?php echo $valid_option['name']; ?>" />
            <span>
            <?php echo $valid_option['title']; ?>
            <?php if ( $valid_option['description'] ) { ?>
                <span style="padding-left:5px;"><em><?php echo $valid_option['description']; ?></em></span>
            <?php } ?>
            </span>
            <br />
            <?php
        }
    }
    // Output select form field markup
    else if ( 'select' == $fieldtype ) {
        $valid_options = array();
        $valid_options = $option['valid_options'];
        ?>
        <select name="<?php echo $fieldname; ?>">
        <?php 
        foreach ( $valid_options as $valid_option ) {
            ?>
            <option <?php selected( $valid_option['name'] == $oenology_options[$optionname] ); ?> value="<?php echo $valid_option['name']; ?>"><?php echo $valid_option['title']; ?></option>
            <?php
        }
        ?>
        </select>
        <?php
    } 
    // Output text input form field markup
    else if ( 'text' == $fieldtype ) {
        ?>
        <input type="text" name="<?php echo $fieldname; ?>" value="<?php echo wp_filter_nohtml_kses( $oenology_options[$optionname] ); ?>" />
        <?php
    } 
    // Output the setting description
    ?>
    <span class="description"><?php echo $optiondescription; ?></span>
    <?php
}
?>

Note that I account for a "custom" type, so that I can output one-off markup for settings that might need it. These require individual callbacks.

Also, this code accounts for a tabbed settings page, which may be more complex than you need. It should be easy to make that bit static, though.

share|improve this answer
    
I guess I'm not PHP-wise enough as I'm scanning your code on github and I don't know what's exactly going on, for example there are some "empty" functions like oenology_get_options()? Where it comes from? I'll try to implement these reusable functions on my own using your tips, but I'm still a bit confused. Do I really have to generate my settings dynamically? I have a list of settings already. Thanks a lot! –  Wordpressor Feb 10 '12 at 0:32
    
Try to pay more attention to the method, rather than the specific implementation. If you want to see the rest of the code, though, just poke through the rest of the files on GitHub. –  Chip Bennett Feb 10 '12 at 0:38
    
I think I'm starting to get that, but hey, wouldn't add_settings_field last parameter ($args?) be enough? I guess I could pass the ID using $args. –  Wordpressor Feb 10 '12 at 1:28
    
You could certainly call add_settings_field() explicitly; just be sure to pass each call the same callback, and you're good to go. –  Chip Bennett Feb 10 '12 at 12:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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