6

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.

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 } ?>
4
  • 1
    Are you using register_setting() for these Theme Settings? There is a LOT of old/obsolete code/methods employed here, but I think we can at least get your new option working correctly. Jul 23, 2011 at 20:43
  • No, it doesn't use register_setting() Jul 24, 2011 at 22:31
  • It would be nice to work with what's here rather than rewrite it all. One existing option hooks into wp_head to load scripts. Jul 25, 2011 at 16:21
  • Sorry if I'm covering ground already covered: can you clarify what's not working right? The option appears in the Settings Page form; what's the issue? Is it not saving properly in the DB? Is it not outputting properly in the template? Jul 25, 2011 at 18:19

2 Answers 2

3
+50

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.

9
  • Ah, starting to make sense. Yes, the options checkbox appears (small screenshot above; the extra closing parenthesis might be a clue to what's broken?). This is a theme I'm adapting from wp.com to self-hosted. I grabbed all the files from wp.com subversion. Everything in the theme works; just trying to add another option. Jul 24, 2011 at 22:30
  • See updated answer, that tries to address the issue of the settings form field value not saving correctly to the DB. Jul 25, 2011 at 18:25
  • Thanks! Good point to see if the option is getting saved to the DB; it is, in the same option value as the two other options that were already part of the theme. So I think it is being santized and serialized correctly near the bottom of the main code sample above, becuase it gets saved in the DB as either true or false. I substitued vertigo_font for disable_comments_link in the if (get_option(... in the template file with no luck; so something is wrong with the template file option call? Jul 25, 2011 at 19:18
  • Okay, one more update, hopefully addressing how properly to use the option in the Theme template. Jul 25, 2011 at 19:28
  • Hmm.... Still no luck. But maybe we're getting closer. Added what the options look like in the DB: are they serialized? And gain substituting vertigo_font for disable_comments_link in the the template call to test with no luck. Jul 25, 2011 at 20:27
1

doesn't really answer your question, but as a heads up there are several really good plugins for building theme options. to me it almost isn't worth the effort to do it myself anymore.

http://wordpress.org/extend/plugins/options-framework/

3
  • Thanks, and that would work, but I need to fix the built-in options rather than use a plugin. Jul 25, 2011 at 16:19
  • i haven't done it but i am pretty sure you can lift the framework code directly into your theme. Jul 26, 2011 at 3:42
  • That's possible, and there are lots of examples of basic theme option panels I could adapt, but I want to work with what already exists to keep from rewriting it all. Turned out to be a simple issue from moving the theme from wp.com to self-hosted. Jul 26, 2011 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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