Add a new checkbox in theme options

I’m trying to add a new option to a theme options panel to hide/show the comments links in the theme template files.

I’ve got the option to show up in the panel, but there’s something wrong in that it doesn’t work and there are no php errors. I’ve noted below in Main options code where I’ve added the option as an array and where it is sanitized and validated.

Read More

And at the bottom is the php that shows/hides the comments links according to the options setting.

Is this a php logic problem? And ideas?

Main options code:

/**
* Describe the available options
**/
$vertigo_options_template = array(
array(
    'name' => __( 'Accent Color', 'vertigo' ),
    'desc' => __( 'Change the accent color by entering a HEX color number. (ie: <code>EE3322</code>)', 'vertigo' ),
    'id' => 'accent_color',
    'std' => 'ee3322',
    'type' => 'colorpicker'
),

array(
    'name' => __( 'Font', 'vertigo' ),
    'desc' => __( 'Enable Hitchcock custom font (Note: this font only supports basic Latin uppercase letters, numerals, and some punctuation.)', 'vertigo' ),
    'id' => 'vertigo_font',
    'std' => ( '1' == get_option( 'lang_id' ) ) ? 'true' : 'false',
    'type' => 'checkbox'
),  


/** My new Option  **/

array(
    'name' => __( 'Comments', 'vertigo' ),
    'desc' => __( 'Disable comment links)', 'vertigo' ),
    'id' => 'disable_comments_link',
    'std' => ( '1' == get_option( 'lang_id' ) ) ? 'true' : 'false',
    'type' => 'checkbox'
),  
);


/**
* Calculate default option values
*
* @return array
**/
function vertigo_get_default_options() {
global $vertigo_options_template;
$default_options = array();

foreach ( $vertigo_options_template as $option )
    $default_options[$option['id']] = $option['std'];

return $default_options;
}

/**
* Create the options form
**/
function vertigo_theme_options_do_page() {
global $vertigo_options_template;

if ( ! isset( $_REQUEST['settings-updated'] ) )
    $_REQUEST['settings-updated'] = false;
?>

<div class="wrap">

    <?php screen_icon(); echo "<h2>" . get_current_theme() . ' ' . __( 'Theme Options', 'vertigo' ) . "</h2>"; ?>

    <?php if ( false !== $_REQUEST['settings-updated'] ) : ?>
    <div class="updated fade"><p><strong><?php _e( 'Options saved.', 'vertigo' ); ?></strong></p></div>
    <?php endif; ?>

    <form method="post" action="options.php">
        <?php settings_fields( 'vertigo_options' ); ?>
        <?php $vertigo_options = vertigo_get_theme_options(); ?>

        <table class="form-table">

        <?php foreach ( $vertigo_options_template as $option ) {
            // Use default value if no option exists
            $value = ( isset ( $vertigo_options[$option['id']] ) && !empty( $vertigo_options[$option['id']] ) ? $vertigo_options[$option['id']] : $option['std'] );
        ?>
            <tr valign="top">
                <th scope="row">
                    <?php echo $option['name']; ?>
                </th>
                <td>
                <?php switch ( $option['type'] ) {
                    case 'colorpicker':
                ?>
                    <input type="text" name="vertigo_theme_options[<?php echo esc_attr( $option['id'] ); ?>]" id="<?php echo esc_attr( $option['id'] ); ?>" value="<?php echo esc_attr( $value ); ?>" class="color { pickerPosition:'right' }" />
                <?php break;

                case 'checkbox':
                ?>
                    <input type="checkbox" name="vertigo_theme_options[<?php echo esc_attr( $option['id'] ); ?>]" id="<?php echo esc_attr( $option['id'] ); ?>" value="true" <?php echo ( 'true' == $value ) ? 'checked="checked"' : ''; ?> />
                <?php break;

                    default:
                        break;
                } // END switch ?>

                    <label class="description" for="<?php echo esc_attr( $option['id'] ); ?>">
                        <?php echo $option['desc']; ?>
                        <?php if ( 'vertigo_font' == $option['id'] ) { ?>
                            <img src="<?php echo get_template_directory_uri(); ?>/inc/images/hitchcock.gif" alt="Hitchcock" id="hitchcock-sample"/>
                        <?php } ?>
                    </label> 

                </td>
            </tr>

        <?php } // END foreach ?>
        </table>

        <p class="submit">
            <?php submit_button( __( 'Save Options', 'vertigo' ), 'primary', 'submit', false ); ?>
            <?php submit_button( __( 'Reset Options', 'vertigo' ), 'secondary', 'vertigo_theme_options[reset]', false, array( 'id' => 'reset' ) ); ?>
        </p>

    </form>

</div><!-- .form-wrap -->

<?php
}

/**
* Sanitize and validate form input
*
* @param array options
* @return array sanitized options
**/
function vertigo_theme_options_validate( $input ) {
global $vertigo_options_template;
$defaults = vertigo_get_default_options();

// Check accent color input format
// Valid = hexadecimal 3 or 6 digits
$accent_color = preg_replace( '/[^0-9a-fA-F]/', '', $input['accent_color'] );
if ( 6 == strlen( $accent_color ) || 3 == strlen( $accent_color ) )
    $input['accent_color'] = $accent_color;
else
    $input['accent_color'] = $defaults['accent_color'];

// Check that Vertigo font checkbox value is either true or false
if ( ! isset( $input['vertigo_font'] ) )
$input['vertigo_font'] = ( $input['vertigo_font'] == 'true' ? 'true' : 'false' );

// My New Option: Check that Disable Comment Links checkbox value is either true or false
if ( ! isset( $input['disable_comments_link'] ) )
$input['disable_comments_link'] = ( $input['disable_comments_link'] == 'true' ? 'true' : 'false' );

// Reset to default options
if ( ! empty( $input['reset'] ) ) {
    $defaults = vertigo_get_default_options();
    foreach ( $input as $field => $value ) {
        if ( isset( $defaults[$field] ) )
            $input[$field] = $defaults[$field];
        else
            unset( $input[$field] );
    }
}

return $input;
}

And I’m using this in my template files to show/hide the comments template:

<?php if ( 'true' == $vertigo_theme_options['disable_comments_link'] ) { ?> 
<?php comments_template( '', true ); ?>
<?php } ?>

This is what the options look like in the DB called vertigo_theme_options:

a:3:{s:12:"accent_color";s:6:"EE3322";s:12:"vertigo_font";s:4:"true";s:21:"disable_comments_link";s:5:"true";}

Edit 7/25/11: This works in template file; need to call options first:

<?php $vertigo_theme_options = get_option( 'vertigo_theme_options' ); ?>

<?php if ( 'false' == $vertigo_theme_options['disable_comments_link'] ) { ?> 
<?php comments_template( '', true ); ?>
<?php } ?>

Related posts

Leave a Reply

2 comments

  1. To answer the first part of your question: your settings form already has the checkbox case covered; so if you add a new checkbox input, you don’t need to add anything to the switch. This code will apply to all checkbox inputs you add:

    case 'checkbox':
    ?>
        <input type="checkbox" name="vertigo_theme_options[<?php echo esc_attr( $option['id'] ); ?>]" id="<?php echo esc_attr( $option['id'] ); ?>" value="true" <?php echo ( 'true' == $value ) ? 'checked="checked"' : ''; ?> />
    <?php break;
    

    More on switch from the PHP.net manual and from w3schools.

    I’m a bit confused by the wording of your question:

    I’ve got the option to show up in the panel via the array

    vs.

    I’ve noted below… where it appears I need to add it in the “create form” section in the php that builds the form.

    So: does the new checkbox currently appear in the Settings page form, or does it not appear?

    EDIT

    Since the setting field appears properly in the settings form, I’m going to try to tackle the next two issues: the option not saving properly, and the option not outputting properly.

    First things first: is the option saving its value properly in the DB, based on the settings form field selection?

    If it’s not saving correctly, then the issue may be that you’re not checking for it properly. With a checkbox, if the checkbox isn’t enabled, then the entire parameter is omitted from the POST data. In that case, in order to save its value in the DB, you need to check for the option value being set, e.g.:

    <?php
    $vertigo_options['disable_comments_link'] = ( isset( $_POST['disable_comments_link'] ) ? true : false );
    ?>
    

    Note: you’ll want to adjust for however you are sanitizing the form data. If you were using the Settings API, it would look more like this:

    <?php
    $output['disable_comments_link'] = ( isset( $input['disable_comments_link'] ) ? true : false );
    ?>
    

    Does this get us closer?

    EDIT 2

    So we know that the option is saving properly in the DB. Now we just need to get it to output properly in the template.

    Next question: are the options stored in the DB discretely, or as an array?

    From your settings form markup, it appears that the options are stored as an array, so we need to call get_option() on the array, and then use values in that array:

    <?php
    $vertigo_theme_options = get_option( 'vertigo_options' );
    ?>
    

    Note: to find the actual database entry name, refer to the vertigo_get_theme_options() function. You could also just call this function:

    <?php
    $vertigo_theme_options = vertigo_get_theme_options();
    ?>
    

    Either way, now you should be able to reference your option in $vertigo_theme_options; e.g.:

    <?php if ( 'true' == $vertigo_theme_options['disable_comments_link'] ) { ?> 
    <?php comments_template( '', true ); ?>
    <?php } ?>
    

    Does that get us there?

    EDIT 3

    option_name under wp_options is vertigo_theme_options

    Then try this:

    <?php
    $vertigo_theme_options = get_option( 'vertigo_theme_options' );
    ?>
    
    <?php if ( 'true' == $vertigo_theme_options['disable_comments_link'] ) { ?> 
    <?php comments_template( '', true ); ?>
    <?php } ?>
    

    I’m just about 100% sure this should do it.