最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

theme development - wp_editor() usage in custom meta box

matteradmin3PV0评论

i am building a custom meta box having a classic editor input rather than just input. The reason for using wp_editor is that I wanted to add paragraphs of text inside div but the simple input escaped the html. Now i am using this function. Now the problem is that when I output the data of this editor input, it escapes html. Here is the code I use for output.

echo get_post_meta($post_id, 'skyscraper_post', true );

I use this code for adding meta boxes.

add_action( 'add_meta_boxes_post', function ( $post ) {
    if ( $post->_wp_page_template === 'page-templates/skyscraper-post.php' ) {
        add_meta_box( 'sky_post_excerpt', 'SkyScraper Post Excerpt and Links', 'sky_post_excerpts', 'post', 'advanced', 'high' );
    }
});
function sky_post_excerpts() {
     global $post;
    $values = get_post_custom( $post->ID );
    $data = get_post_meta($post->ID, 'skyscraper_post', true);


    $strong_title = isset( $values['skyscraper_strong'] ) ? esc_html( $values['skyscraper_strong'][0] ) : "";
    $title = isset( $values['skyscraper_post_title'] ) ? esc_attr( $values['skyscraper_post_title'][0] ) : "";
    $text = isset( $values['skyscraper_post'] ) ?  $values['skyscraper_post'][0]  : "";
    $image = isset( $values['skyscraper_post_image'] ) ? esc_attr( $values['skyscraper_post_image'][0] ) : "";

    // We'll use this nonce field later on when saving.
    wp_nonce_field( 'my_post_meta_box_nonce', 'post_meta_box_nonce' );
    ?>

    <table class="form-table">
        <tbody>
        <tr valign="top">
            <th scope="row">
                <label><strong>Skyscraper Title</strong></label>
            </th>
            <td>
                <p><input class="widefat" name="skyscraper_strong" id="skyscraper_strong" ><?php echo $strong_title; ?></input>
                </p>
                <p><input class="widefat" rows="4" name="skyscraper_post_title" id="skyscraper_post_title" value="<?php echo $title; ?>"/>
                </p>
            </td>
        </tr>

        <tr valign="top">
            <th scope="row">
                <label for="skyscraper_post"><strong>Skyscraper Page Excerpt</strong></label>
            </th>
            <td>
                <?php wp_editor( $data, 'post_meta_box', $settings = array('textarea_name'=>'skyscraper_post')); ?>
                </p>
            </td>
        </tr>
        <tr valign="top">
            <th scope="row">
                <label for="skyscraper_image"><strong>SVG Image Link</strong></label>
            </th>
            <td>
                <p><input class="widefat" rows="4" name="skyscraper_post_image" id="skyscraper_post_image" value="<?php echo $image; ?>"/>
                </p>
            </td>
        </tr>

        </tbody>
    </table>
    <?php
}

To save the data I use this code.

    add_action( 'save_post', 'post_meta_box_save' );
    function post_meta_box_save( $post_id ) {
   // Bail if we're doing an auto save
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    // if our nonce isn't there, or we can't verify it, bail
    if( !isset( $_POST['post_meta_box_nonce'] ) || !wp_verify_nonce( $_POST['post_meta_box_nonce'], 'my_post_meta_box_nonce' ) ) return;

    // if our current user can't edit this post, bail
    if( !current_user_can( 'edit_post' ) ) return;
    //$allowed = wp_kses_allowed_html();
    $allowed= array(
        'p' => array(
            'class' => array(),
            'id' => array(),
        ),
        'strong' => array(),
    );


    // Make sure your data is set before trying to save it
    if( isset( $_POST['skyscraper_post'] ) )
        update_post_meta( $post_id, 'skyscraper_post', wp_kses( $_POST['skyscraper_post'], $allowed ) );

    // Make sure your data is set before trying to save it
    if( isset( $_POST['skyscraper_post_image'] ) )
        update_post_meta( $post_id, 'skyscraper_post_image', wp_kses( $_POST['skyscraper_post_image'], $allowed ) );

    // Make sure your data is set before trying to save it
    if( isset( $_POST['skyscraper_strong'] ) )
        update_post_meta( $post_id, 'skyscraper_strong', wp_kses( $_POST['skyscraper_strong'], $allowed ) );

    // Make sure your data is set before trying to save it
    if( isset( $_POST['skyscraper_post_title'] ) )
        update_post_meta( $post_id, 'skyscraper_post_title', wp_kses( 

    $_POST['skyscraper_post_title'], $allowed ) );
    }

I don't know why the html is being escaped. Any help will be appreciated, Thanks.

here is the escaped output.

i am building a custom meta box having a classic editor input rather than just input. The reason for using wp_editor is that I wanted to add paragraphs of text inside div but the simple input escaped the html. Now i am using this function. Now the problem is that when I output the data of this editor input, it escapes html. Here is the code I use for output.

echo get_post_meta($post_id, 'skyscraper_post', true );

I use this code for adding meta boxes.

add_action( 'add_meta_boxes_post', function ( $post ) {
    if ( $post->_wp_page_template === 'page-templates/skyscraper-post.php' ) {
        add_meta_box( 'sky_post_excerpt', 'SkyScraper Post Excerpt and Links', 'sky_post_excerpts', 'post', 'advanced', 'high' );
    }
});
function sky_post_excerpts() {
     global $post;
    $values = get_post_custom( $post->ID );
    $data = get_post_meta($post->ID, 'skyscraper_post', true);


    $strong_title = isset( $values['skyscraper_strong'] ) ? esc_html( $values['skyscraper_strong'][0] ) : "";
    $title = isset( $values['skyscraper_post_title'] ) ? esc_attr( $values['skyscraper_post_title'][0] ) : "";
    $text = isset( $values['skyscraper_post'] ) ?  $values['skyscraper_post'][0]  : "";
    $image = isset( $values['skyscraper_post_image'] ) ? esc_attr( $values['skyscraper_post_image'][0] ) : "";

    // We'll use this nonce field later on when saving.
    wp_nonce_field( 'my_post_meta_box_nonce', 'post_meta_box_nonce' );
    ?>

    <table class="form-table">
        <tbody>
        <tr valign="top">
            <th scope="row">
                <label><strong>Skyscraper Title</strong></label>
            </th>
            <td>
                <p><input class="widefat" name="skyscraper_strong" id="skyscraper_strong" ><?php echo $strong_title; ?></input>
                </p>
                <p><input class="widefat" rows="4" name="skyscraper_post_title" id="skyscraper_post_title" value="<?php echo $title; ?>"/>
                </p>
            </td>
        </tr>

        <tr valign="top">
            <th scope="row">
                <label for="skyscraper_post"><strong>Skyscraper Page Excerpt</strong></label>
            </th>
            <td>
                <?php wp_editor( $data, 'post_meta_box', $settings = array('textarea_name'=>'skyscraper_post')); ?>
                </p>
            </td>
        </tr>
        <tr valign="top">
            <th scope="row">
                <label for="skyscraper_image"><strong>SVG Image Link</strong></label>
            </th>
            <td>
                <p><input class="widefat" rows="4" name="skyscraper_post_image" id="skyscraper_post_image" value="<?php echo $image; ?>"/>
                </p>
            </td>
        </tr>

        </tbody>
    </table>
    <?php
}

To save the data I use this code.

    add_action( 'save_post', 'post_meta_box_save' );
    function post_meta_box_save( $post_id ) {
   // Bail if we're doing an auto save
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    // if our nonce isn't there, or we can't verify it, bail
    if( !isset( $_POST['post_meta_box_nonce'] ) || !wp_verify_nonce( $_POST['post_meta_box_nonce'], 'my_post_meta_box_nonce' ) ) return;

    // if our current user can't edit this post, bail
    if( !current_user_can( 'edit_post' ) ) return;
    //$allowed = wp_kses_allowed_html();
    $allowed= array(
        'p' => array(
            'class' => array(),
            'id' => array(),
        ),
        'strong' => array(),
    );


    // Make sure your data is set before trying to save it
    if( isset( $_POST['skyscraper_post'] ) )
        update_post_meta( $post_id, 'skyscraper_post', wp_kses( $_POST['skyscraper_post'], $allowed ) );

    // Make sure your data is set before trying to save it
    if( isset( $_POST['skyscraper_post_image'] ) )
        update_post_meta( $post_id, 'skyscraper_post_image', wp_kses( $_POST['skyscraper_post_image'], $allowed ) );

    // Make sure your data is set before trying to save it
    if( isset( $_POST['skyscraper_strong'] ) )
        update_post_meta( $post_id, 'skyscraper_strong', wp_kses( $_POST['skyscraper_strong'], $allowed ) );

    // Make sure your data is set before trying to save it
    if( isset( $_POST['skyscraper_post_title'] ) )
        update_post_meta( $post_id, 'skyscraper_post_title', wp_kses( 

    $_POST['skyscraper_post_title'], $allowed ) );
    }

I don't know why the html is being escaped. Any help will be appreciated, Thanks.

here is the escaped output.

Share Improve this question edited Apr 5, 2019 at 9:10 Raashid Din asked Apr 5, 2019 at 3:33 Raashid DinRaashid Din 2182 silver badges19 bronze badges 11
  • This part escapes the HTML code: htmlspecialchars($_POST['skyscraper_post']). Perhaps you could just remove that and the htmlspecialchars_decode() ? – Sally CJ Commented Apr 5, 2019 at 4:45
  • after removing this it still escapes the html. Any other way to output the data – Raashid Din Commented Apr 5, 2019 at 4:51
  • Have you tried to decode it using wp_specialchars_decode instead of htmlspecialchars_decode? Also you could use the sanitize_text_field instead of wp_kses to sanitize the $_POST data. – Tiago Hillebrandt Commented Apr 5, 2019 at 4:54
  • applied the methods but still escaping p tags. – Raashid Din Commented Apr 5, 2019 at 4:59
  • is there any other way to output data of wp_editor other than get post meta – Raashid Din Commented Apr 5, 2019 at 5:10
 |  Show 6 more comments

1 Answer 1

Reset to default 4

This may not solve the problem, but I hope it helps you.

  1. In the sky_post_excerpts() function, I used this to display the TinyMCE/classic editor: (the $data is get_post_meta($post->ID, 'skyscraper_post', true))

    <?php wp_editor( $data, 'post_meta_box', array('textarea_name'=>'skyscraper_post')); ?>
    
  2. In the post_meta_box_save() function, I saved the meta like so, where $allowed is wp_kses_allowed_html():

    update_post_meta( $post_id, 'skyscraper_post', wp_kses( $_POST['skyscraper_post'], $allowed ) );
    
  3. On the front-end, I display the metadata like so:

    // This is really just an example. And I was on a single post.
    echo get_post_meta( get_the_ID(), 'skyscraper_post', true );
    

And everything worked well for me — all HTML remained as generated by the TinyMCE editor.

UPDATE

if I use visual not text in TinyMCE then the p tags doesn't show

wp_kses_allowed_html() when called without specifying the $context parameter, will use the global variable $allowedtags which is an array of KSES allowed HTML elements, which (by default) do not include p tags/elements.

If you want to allow p elements, you can:

  • Use wp_kses_allowed_html( 'post' ) which will use the global variable $allowedposttags which also holds similar array as the $allowedtags variable, but $allowedposttags has many elements allowed including table and video.

  • Or manually enable the p elements:

    $allowed = wp_kses_allowed_html();
    $allowed['p'] = array(); // allows all attributes!
    
  • Same as above, but build your own allowed tags:

    $allowed = array();
    $allowed['p'] = array(); // allows all attributes!
    

But, you shouldn't allow all attributes.. so:

$allowed['p'] = array(
  'class' => true,
  'id'    => true,
  ...other attributes...
);
Post a comment

comment list (0)

  1. No comments so far