How to stop wordpress from mangling HTML in a metabox textarea

I’v re-worked your code. I’ll try to explain some of the changes after the code block

add_action("admin_menu", "tf_book_deets_create");

function tf_book_deets_create(){

    add_meta_box('tf_book_details', 'Book Details', 'tf_book_details', 'books');
}

function tf_book_details () {
    global $post;

    $tf_book_media = get_post_meta($post->ID, "tf_book_media", true);
    $tf_book_review = get_post_meta($post->ID, "tf_book_review", true);


    ?>

    <div class="admin_meta"> 
    <ul>

    <li><label>Reviews:</label><textarea rows="5" cols="70" name="tf_book_review"><?php echo esc_textarea($tf_book_review); ?></textarea></li>

    <li><label>Media:</label><textarea rows="5" cols="70" name="tf_book_media"><?php echo esc_textarea($tf_book_media); ?></textarea></li>
    </ul>

    <?php wp_nonce_field( 'book-nonce', 'book_nonce_name', false ); ?>

    </div>


<?php 
}

add_action ('save_post', 'save_tf_book_details');   


function save_tf_book_details( $post_id ) {

    // make sure we're on a supported post type
    if ( $_POST['post_type'] != 'books' ) return;  

    // verify this came from our screen and with proper authorization.
    if ( !wp_verify_nonce( $_POST['book_nonce_name'], 'book-nonce' )) return;

    // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;


    // Check permissions
    if ( 'page' == $_POST['post_type'] ) {
        if ( !current_user_can( 'edit_page', $post_id ) ) return;
    } else {
        if ( !current_user_can( 'edit_post', $post_id ) ) return;
    }

    // OK, we're authenticated: we need to find and save the data
    if ( isset( $_POST["tf_book_media"] ) ) update_post_meta( $post_id, "tf_book_media", wp_kses_post( $_POST["tf_book_media"] ) );
    if ( isset( $_POST["tf_book_review"] ) ) update_post_meta( $post_id, "tf_book_review", wp_kses_post( $_POST["tf_book_review"] ) );

}

Textarea markup

First I switched the textarea markup. The value of a textarea is set in between the opening and closing textarea tags. The textarea’s value is also escaped with esc_textarea()

Basic sanitization and nonce security

I added some basic validation and nonce security to the save_tf_book_details() function. First the nonce that I added to the metabox callback function is verified here, so we’re sure the data is coming from the right place.

I also ran the text area inputs through the wp_kses_post() function, which filters out any scripts or other tags that are not allowed in regular posts.

Leave a Comment