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'm using this great [tuts+ tutorial][1] for creating theme options page. It works great for me be beause I need to change background images of divs via css. It works great with one image but I dont know how to make it work with 2 images?

It would be a huge help if you can tell me what I'm doing wrong here? Thanks!

  <?php
function wptuts_get_default_options() {
    $options = array();
        $options[] = array('logo' => '');
        $options[] = array('fav' => '');
    return $options;
}


function wptuts_options_init() {
     $wptuts_options = get_option( 'theme_wptuts_options' );

     // Are our options saved in the DB?
     if ( false === $wptuts_options ) {
          // If not, we'll save our default options
          $wptuts_options = wptuts_get_default_options();
          add_option( 'theme_wptuts_options', $wptuts_options );
     }

     // In other case we don't need to update the DB
}
// Initialize Theme options
add_action( 'after_setup_theme', 'wptuts_options_init' );

function wptuts_options_setup() {
    global $pagenow;
    if ('media-upload.php' == $pagenow || 'async-upload.php' == $pagenow) {
        // Now we'll replace the 'Insert into Post Button inside Thickbox' 
        add_filter( 'gettext', 'replace_thickbox_text' , 1, 2 );
    }
}
add_action( 'admin_init', 'wptuts_options_setup' );

function replace_thickbox_text($translated_text, $text ) {  
    if ( 'Insert into Post' == $text ) {
        $referer = strpos( wp_get_referer(), 'wptuts-settings' );
        if ( $referer != '' ) {
            return __('I want this to be my Image!', 'wptuts' );
        }
    }

    return $translated_text;
}

// Add "WPTuts Options" link to the "Appearance" menu
function wptuts_menu_options() {
    //add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function);
     add_theme_page('WPTuts Options', 'WPTuts Options', 'edit_theme_options', 'wptuts-settings', 'wptuts_admin_options_page');
}
// Load the Admin Options page
add_action('admin_menu', 'wptuts_menu_options');

function wptuts_admin_options_page() {
    ?>
        <!-- 'wrap','submit','icon32','button-primary' and 'button-secondary' are classes 
        for a good WP Admin Panel viewing and are predefined by WP CSS -->



        <div class="wrap">

            <div id="icon-themes" class="icon32"><br /></div>

            <h2><?php _e( 'WPTuts Options', 'wptuts' ); ?></h2>

            <!-- If we have any error by submiting the form, they will appear here -->
            <?php settings_errors( 'wptuts-settings-errors' ); ?>

            <form id="form-wptuts-options" action="options.php" method="post" enctype="multipart/form-data">

                <?php
                    settings_fields('theme_wptuts_options');
                    do_settings_sections('wptuts');
                ?>

                <p class="submit">
                    <input name="theme_wptuts_options[submit]" id="submit_options_form" type="submit" class="button-primary" value="<?php esc_attr_e('Save Settings', 'wptuts'); ?>" />
                    <input name="theme_wptuts_options[reset]" type="submit" class="button-secondary" value="<?php esc_attr_e('Reset Defaults', 'wptuts'); ?>" />        
                </p>

            </form>

        </div>
    <?php
}

function wptuts_options_validate( $input ) {
    $default_options = wptuts_get_default_options();
    $valid_input = $default_options;

    $wptuts_options = get_option('theme_wptuts_options');

    $submit = ! empty($input['submit']) ? true : false;
    $reset = ! empty($input['reset']) ? true : false;
    $delete_logo = ! empty($input['delete_logo']) ? true : false;
    $delete_fav = ! empty($input['delete_fav']) ? true : false;

    foreach ( $wptuts_options   as $wptuts_options ) {  
        if ( $submit ) {
            if ( $wptuts_options['logo'] != $input['logo']  && $wptuts_options['logo'] != '' )
                delete_image( $wptuts_options['logo'] );

            $valid_input['logo'] = $input['logo'];
        }
        elseif ( $reset ) {
            delete_image( $wptuts_options['logo'] );
            $valid_input['logo'] = $default_options['logo'];
        }
        elseif ( $delete_logo ) {
            delete_image( $wptuts_options['logo'] );
            $valid_input['logo'] = '';
        }
        if ( $submit ) {
            if ( $wptuts_options['fav'] != $input['fav']  && $wptuts_options['fav'] != '' )
                delete_image( $wptuts_options['fav'] );

            $valid_input['fav'] = $input['fav'];
        }
        elseif ( $reset ) {
            delete_image( $wptuts_options['fav'] );
            $valid_input['fav'] = $default_options['fav'];
        }
        elseif ( $delete_fav ) {
            delete_image( $wptuts_options['fav'] );
            $valid_input['fav'] = '';
        }

    return $valid_input;
}

function delete_image( $image_url ) {
    global $wpdb;

    // We need to get the image's meta ID..
    $query = "SELECT ID FROM wp_posts where guid = '" . esc_url($image_url) . "' AND post_type = 'attachment'";  
    $results = $wpdb -> get_results($query);

    // And delete them (if more than one attachment is in the Library
    foreach ( $results as $row ) {
        wp_delete_attachment( $row -> ID );
    }   
}

/********************* JAVASCRIPT ******************************/
function wptuts_options_enqueue_scripts() {
    wp_register_script( 'wptuts-upload', get_template_directory_uri() .'/wptuts-options/js/wptuts-upload.js', array('jquery','media-upload','thickbox') );  

    if ( 'appearance_page_wptuts-settings' == get_current_screen() -> id ) {
        wp_enqueue_script('jquery');

        wp_enqueue_script('thickbox');
        wp_enqueue_style('thickbox');

        wp_enqueue_script('media-upload');
        wp_enqueue_script('wptuts-upload');

    }

}
add_action('admin_enqueue_scripts', 'wptuts_options_enqueue_scripts');


function wptuts_options_settings_init() {
    register_setting( 'theme_wptuts_options', 'theme_wptuts_options', 'wptuts_options_validate' );

    // Add a form section for the Logo
    add_settings_section('wptuts_settings_header', __( 'Logo Options', 'wptuts' ), 'wptuts_settings_header_text', 'wptuts');
    // Add Logo uploader
    add_settings_field('wptuts_setting_logo',  __( 'Logo', 'wptuts' ), 'wptuts_setting_logo', 'wptuts', 'wptuts_settings_header');
    // Add Current Image Preview 
    add_settings_field('wptuts_setting_logo_preview',  __( 'Logo Preview', 'wptuts' ), 'wptuts_setting_logo_preview', 'wptuts', 'wptuts_settings_header');

    // Add a form section for the fav
    add_settings_section('wptuts_settings_header', __( 'fav Options', 'wptuts' ), 'wptuts_settings_header_text', 'wptuts');
    // Add fav uploader
    add_settings_field('wptuts_setting_fav',  __( 'fav', 'wptuts' ), 'wptuts_setting_fav', 'wptuts', 'wptuts_settings_header');
    // Add Current Image Preview 
    add_settings_field('wptuts_setting_fav_preview',  __( 'fav Preview', 'wptuts' ), 'wptuts_setting_fav_preview', 'wptuts', 'wptuts_settings_header'); 

}
add_action( 'admin_init', 'wptuts_options_settings_init' );

function wptuts_setting_logo_preview() {
    $wptuts_options = get_option( 'theme_wptuts_options' );  ?>
    <div id="upload_logo_preview" style="min-height: 100px;">
        <img style="max-width:100%;" src="<?php echo esc_url( $wptuts_options['logo'] ); ?>" />
    </div>
    <?php
}

function wptuts_setting_fav_preview() {
    $wptuts_options = get_option( 'theme_wptuts_options' );  ?>
    <div id="upload_fav_preview" style="min-height: 100px;">
        <img style="max-width:100%;" src="<?php echo esc_url( $wptuts_options['logo'] ); ?>" />
    </div>
    <?php
}

function wptuts_settings_header_text() {
    ?>
        <p><?php _e( 'Manage Options for WpTuts Theme.', 'wptuts' ); ?></p>
    <?php
}

function wptuts_setting_logo() {
    $wptuts_options = get_option( 'theme_wptuts_options' );
    ?>
        <input type="hidden" id="logo_url" name="theme_wptuts_options[logo]" value="<?php echo esc_url( $wptuts_options['logo'] ); ?>" />
        <input id="upload_logo_button" type="button" class="button" value="<?php _e( 'Upload Logo', 'wptuts' ); ?>" />
        <?php if ( '' != $wptuts_options['logo'] ): ?>
            <input id="delete_logo_button" name="theme_wptuts_options[delete_logo]" type="submit" class="button" value="<?php _e( 'Delete Logo', 'wptuts' ); ?>" />
        <?php endif; ?>
        <span class="description"><?php _e('Upload an image for the banner.', 'wptuts' ); ?></span>
    <?php
}

function wptuts_setting_fav() {
    $wptuts_options = get_option( 'theme_wptuts_options' );
    ?>
        <input type="hidden" id="fav_url" name="theme_wptuts_options[fav]" value="<?php echo esc_url( $wptuts_options['fav'] ); ?>" />
        <input id="upload_fav_button" type="button" class="button" value="<?php _e( 'Upload fav', 'wptuts' ); ?>" />
        <?php if ( '' != $wptuts_options['fav'] ): ?>
            <input id="delete_fav_button" name="theme_wptuts_options[delete_fav]" type="submit" class="button" value="<?php _e( 'Delete fav', 'wptuts' ); ?>" />
        <?php endif; ?>
        <span class="description"><?php _e('Upload an image for the banner.', 'wptuts' ); ?></span>
    <?php
}


?>
share|improve this question
    
Themes should use the Theme Customization API. The Options API is nowadays reserved for plugins. –  kaiser Jan 20 '13 at 16:03
    
Make what work with two images? Please narrow this down. –  s_ha_dum Jan 20 '13 at 16:19
    
Thanks for editing, I'm new here so any help is welcome. About images, if you checked original tutorial, it shows how to create option page for theme with single upload image field. I need to upload 2 or more images (like fav image etc). Everything looks fine but not working. –  Valeka Jan 20 '13 at 17:49
    
@kaiser the Theme Customizer is simply a UI for Theme options. It can use either the Settings API or theme_mods. At this time, either one is perfectly valid and acceptable. –  Chip Bennett Jan 20 '13 at 17:53
1  
Valeka, that's really a huge mass of code to dig into & it has a missing curly bracket and needs a non provided JS file... I suggest starting over, build a minimal working code and go adding features. :::: Alternatives: this Q&A may be useful + the plugin Advanced Custom Fields has a premium add-on (Options) that is quite handy and has a lite version to use with themes. –  brasofilo Jan 20 '13 at 22:52

2 Answers 2

up vote 0 down vote accepted

I can't comment on your code, but you might find this link useful:

Options Framework Theme: http://wptheming.com/options-framework-theme/

This is something you have to edit carefully, but it has pretty much every type of control you can think of in there. It also had the only working MCE Editor that I could find. I wanted that for allowing text to be saved in the theme, things like editing the address in the footer, or the copyright.

share|improve this answer

You need to add your new options to the validation callback, wptuts_options_validate().

Without seeing all of your code, it will be impossible to say for sure what exact code needs to be added. But in general, here's how the validation callback works: with the Settings API, all user input is whitelisted: that is: input is only saved to the database if it is explicitly declared as being a valid option, and then sanitized before being saved.

Let's say you have 3 options: 'A', 'B', and 'C'. Here's what the validation callback does:

function validation_callback( $input ) {

}

First, the $input parameter is the $_POST data passed from the user via the settings form. It is the untrusted data. The idea is to manipulate the user data, then save it in the databaase.

The whitelist aspect of the callback means that the function will explicitly manipulate only known options, and then pass the manipulated, known list to the database. Something like so:

function validation_callback( $input ) {
    // Get current option values
    // and use them as the current "valid" values
    $valid_input = get_option( 'some_options_group' );
    // A is a checkbox
    // If it is set, then return true; else return false
    $valid_input['A'] = ( isset( $input['A'] ? 'true' : 'false' );
    // B is a select
    // If the value passed in $input is contained
    // in the array of known-good values, then return
    // $input value; else return the current value
    $valid_options_b = array( 'X', 'Y', 'Z' );
    $valid_input['B'] = ( in_array( $input['B'], $valid_options_b ) ? $input['B'] : $valid_input['B'] );
    // C is plain text, for which no HTML is expected
    // Simply return filtered $input value if set;
    // else return an empty string
    $valid_input['C'] = ( isset( $input['C'] ) ? wp_filter_nohtml_kses( $input['C'] ) : '' );

    // All known values have been sanitized,
    // so return those values
    return $valid_input;
}

So now, you want to add another valid option, 'D'.

If you've added the option itself, and it appears on your settings page, great. That's the first step. Your option 'D' will now be included in the $input array that gets passed to the validation callback.

But, because your callback doesn't have option 'D' whitelisted, it essentially gets filtered out of $input, and never saved to the database. So, you need to add it. Perhaps like so:

// D is a file
// So let WordPress handle the file upload
$valid_input['D'] = ( isset( $input['D'] ) ? wp_handle_upload( $input['D'] ) : $valid_input['D'] );

You would add that into your validation callback:

function validation_callback( $input ) {
    // Get current option values
    // and use them as the current "valid" values
    $valid_input = get_option( 'some_options_group' );
    // A is a checkbox
    // If it is set, then return true; else return false
    $valid_input['A'] = ( isset( $input['A'] ? 'true' : 'false' );
    // B is a select
    // If the value passed in $input is contained
    // in the array of known-good values, then return
    // $input value; else return the current value
    $valid_options_b = array( 'X', 'Y', 'Z' );
    $valid_input['B'] = ( in_array( $input['B'], $valid_options_b ) ? $input['B'] : $valid_input['B'] );
    // C is plain text, for which no HTML is expected
    // Simply return filtered $input value if set;
    // else return an empty string
    $valid_input['C'] = ( isset( $input['C'] ) ? wp_filter_nohtml_kses( $input['C'] ) : '' );

    // ADD INPUT D HERE
    // D is a file
    // So let WordPress handle the file upload
    $valid_input['D'] = ( isset( $input['D'] ) ? wp_handle_upload( $input['D'] ) : $valid_input['D'] );

    // All known values have been sanitized,
    // so return those values
    return $valid_input;
}

Now, option 'D' is whitelisted, and should get properly saved to the database.

share|improve this answer
    
Thanks Chip a lot for your answer. I guessed that validation is the problem. I tried to add validation for input fields (as you wrote) but still nothing. I uploaded all my PHP code here and if that doesnt take you too much time can you check again. There is function "wptuts_options_validate". Or maybe I'm wrong somewhere else? Huge thanks one more time! –  Valeka Jan 20 '13 at 18:57
    
I found where problem was. Declaration of an array in very first function wptuts_get_default_options was not good. And of course as you said function for declaration. Thanks! –  Valeka Jan 21 '13 at 19:03
    
@Valeka Then please mark the answer as solution or add your own answer in case the solution is different from above answer by Chip. –  kaiser Mar 11 at 16:48

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.