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.

On the site I'm currently developing I have created a theme options page (under Appearance). All there is on this page is a text area so the client can add some summary text to appear above their posts.

I am using TinyMCE on this textarea so they can format their text, but if I have TinyMCE enabled the 'Save Options' button doesn't do anything upon clicking it. If I comment out the following lines in my theme-options file to disable TinyMCE, then it saves correctly.

<?php
    wp_tiny_mce( false , // true makes the editor "teeny"
        array(
            "editor_selector" => "large-text"
        )
    );
?>

Note: The TinyMCE loads and displays correctly - text can be formatted, just not saved.

Any idea what could be causing this?

I am using WordPress 3.2.

Thanks!

Edit: The entire code in my theme-options.php file is as follows

<?php

add_action( 'admin_init', 'theme_options_init' );
add_action( 'admin_menu', 'theme_options_add_page' );

/**
 * Init plugin options to white list our options
 */
function theme_options_init(){
    register_setting( 'client_options', 'client_theme_options', 'theme_options_validate' );
}

/**
 * Load up the menu page
 */
function theme_options_add_page() {
    add_theme_page( __( 'Intro/Welcome Text', 'client' ), __( 'Intro/Welcome Text', 'client' ), 'edit_theme_options', 'theme_options', 'theme_options_do_page' );
}


/**
 * Create the options page
 */
function theme_options_do_page() {
    global $select_options, $radio_options;

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

    ?>
    <div class="wrap">
        <?php screen_icon(); echo "<h2>" . __( ' Intro/Welcome Text', 'client' ) . "</h2>"; ?>

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

        <form method="post" action="options.php">
            <?php settings_fields( 'client_options' ); ?>
            <?php $options = get_option( 'client_theme_options' ); ?>
            <?php
            wp_tiny_mce( true , // true makes the editor "teeny"
                array(
                    "editor_selector" => "large-text"
                )
            );
            ?>
            <table class="form-table">

                <?php
                /**
                 * A sample textarea option
                 */
                ?>
                <tr valign="top"><th scope="row"><?php _e( 'Intro/Welcome Text' ); ?></th>
                    <td>
                        <textarea id="client_theme_options[intro_content]" class="large-text" cols="50" rows="10" name="client_theme_options[intro_content]"><?php echo esc_textarea( $options['intro_content'] ); ?></textarea>
                        <label class="description" for="client_theme_options[intro_content]"><?php _e( 'Enter content here to be displayed above the <em><strong>Posts</strong></em>.', 'client' ); ?></label>
                    </td>
                </tr>
            </table>

            <p class="submit">
                <input type="submit" class="button-primary" value="<?php _e( 'Save Options', 'client' ); ?>" />
            </p>
        </form>
    </div>
    <?php
}

/**
 * Sanitize and validate input. Accepts an array, return a sanitized array.
 */
function theme_options_validate( $input ) {
    global $select_options, $radio_options;

    // Our checkbox value is either 0 or 1
    if ( ! isset( $input['option1'] ) )
        $input['option1'] = null;
    $input['option1'] = ( $input['option1'] == 1 ? 1 : 0 );

    // Say our text option must be safe text with no HTML tags
    $input['sometext'] = wp_filter_nohtml_kses( $input['sometext'] );

    // Our select option must actually be in our array of select options
    if ( ! array_key_exists( $input['selectinput'], $select_options ) )
        $input['selectinput'] = null;

    // Our radio option must actually be in our array of radio options
    if ( ! isset( $input['radioinput'] ) )
        $input['radioinput'] = null;
    if ( ! array_key_exists( $input['radioinput'], $radio_options ) )
        $input['radioinput'] = null;

    // Say our textarea option must be safe text with the allowed tags for posts
    $input['sometextarea'] = wp_filter_post_kses( $input['sometextarea'] );

    return $input;
}

// adapted from http://planetozh.com/blog/2009/05/handling-plugins-options-in-wordpress-28-with-register_setting/
share|improve this question
    
Can we see the code for the entire Theme Options page, including the register_setting() call and sanitization callback function? –  Chip Bennett Jul 11 '11 at 12:15
    
Thanks for your response - I will update my question accordingly :) –  Probocop Jul 11 '11 at 12:58

2 Answers 2

What output do you get on-submit, if you add the following to the top of your sanitization callback:

var_dump( $input ); die;

i.e. add it here:

function theme_options_validate( $input ) {
    var_dump( $input ); die;

Compare the results with and without TinyMCE. Let's figure out what's changing.

Also: this isn't directly related to the issue you're having (at least, I think it isn't), but your sanitization callback doesn't actually sanitize the input you're sending it, i.e. client_theme_options['intro_text']. It appears to be a conglomeration of copy-pasta, example sanitization functions.

You need to sanitize your actual option, probably with a wp_filter_post_kses() filter, since you're allowing for HTML input.

EDIT

Perhaps you are having a similar issue to this other SO questioner, in which the textarea data isn't being submitted, because of the way that TinyMCE hijacks the textarea?

The solutions to that question included:

  • before submit call tinyMCE.triggerSave();
  • And this suggestion:

Add a hidden field to the form:

<input type="hidden" id="question_html" name="question_html" />

Before posting the form, get the data from the editor and put in the hidden field:

$('#question_html').val(tinyMCE.get('question_text').getContent());

Here's another SO question related to the same issue. It suggests using this script code:

var editor = tinymce.get( editor_id);
editor.save();  // writes content back to the textarea
// you may now use jQuery or editor.getContent(); to acces the content

(Which I think is similar to the other suggestions.)

Not sure if any of those would be helpful?

share|improve this answer
    
It appears the form is never getting submitted at all. IE the page never reloads. Also no error message is displayed. Note: there are also no JS errors on the page. –  Probocop Jul 11 '11 at 14:02
    
So, when you click "submit", nothing at all happens? Is that true both with and without TinyMCE enabled? –  Chip Bennett Jul 11 '11 at 14:05
    
With TinyMCE disabled, the form submits fine and the page reloads with the new value in the textarea. Only with TinyMCE enabled does the submit button not work. –  Probocop Jul 11 '11 at 15:15
    
So, you didn't add var_dump( $input ); die; to your sanitization callback function? You need to do that, so we can diagnose what's going on. –  Chip Bennett Jul 11 '11 at 15:52
    
Hi, with TinyMCE disabled, I get the following from the var_dump(): array(1) { ["intro_content"]=> string(56) "Lorem ipsum dolor sit amet, consectetur adipiscing elit." } –  Probocop Jul 12 '11 at 8:24

I had the same issue and after a day of frustration I found that if I added the wp_tiny_mce inside the table it worked.

    <table class="form-table">

    <tr>
    <td>
                <?php
wp_tiny_mce( false , // true makes the editor "teeny"
  array(
    "editor_selector" => "mce-text",
  'width' => '80%',
  'theme' => 'advanced',
  'skin' => 'wp_theme'
  )
);
    ?>
    </td>
    </tr>
share|improve this answer

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.