Hey guys, I've added a TinyMCE to some textareas that are displayed in a custom meta box. All of the formatting works perfectly fine, except that the editor will not save <p> or <br/> tags. It doesn't preserve the line breaks.

The TinyMCE is setup like this:

wp_tiny_mce(true, array('editor_selector' => $field['class'] ) );

'<textarea name="', $field['id'], '" class="', $field['class'], '" id="', $field['id'], '" cols="60" rows="8" style="width:97%">', $meta ? esc_html($meta) : $field['std'], '</textarea>';

And that all works perfectly fine. All the formatting buttons work fine, except for the <P> and <BR> tags.

I'm not sure if the editor is stripping them out before or after the post meta is saved.


  • I managed to get it to work in one way. By duplicating the function from core, and changing 'remove_linebreaks' => true to 'remove_linebreaks' => false. But it doesn't work if I specify 'remove_linebreaks' => false in the settings array passed to the function
    – Pippin
    Commented Apr 22, 2011 at 19:29
  • @Arthur Carabott yes, that did the trick for me too. Let's add a link to the docs: codex.wordpress.org/Function_Reference/wpautop Bye! Commented Nov 18, 2011 at 15:02
  • We're seeing a very weird thing. Posts that are hand-entered/copy-pasted have the breaks preserved on edit. Posts that we imported are subject to the editor blowing away the line breaks on edit.
    – JCL1178
    Commented Feb 7, 2012 at 22:31

7 Answers 7


I recently got this working. You should search and replace metaname with your meta box name.

The key to maintaining formatting was using wpautop(); when saving the data.

add_action( 'add_meta_boxes', 'add_metaname_box');

add_action( 'save_post', 'metaname_save');

function add_metaname_box() {
        __( 'metaname text', 'metaname_textdomain'),

function metaname_custom_box() {
    global $post;
    wp_nonce_field( plugin_basename( __FILE__ ), 'metaname_noncename' );
    $data = get_post_meta($post->ID, 'metaname_custom_box', true);
    echo <<<EOT
    <script type="text/javascript">
jQuery(document).ready(function() {
    if ( typeof( tinyMCE ) == "object" &&
         typeof( tinyMCE.execCommand ) == "function" ) {
        tinyMCE.execCommand("mceAddControl", false, "metaname_custom_box");
    <textarea id="metaname_custom_box" name="metaname_custom_box">$data</textarea>

function metaname_save($post_id) {
    global $post;

    // Verify
     if ( !wp_verify_nonce( $_POST['metaname_noncename'], plugin_basename(__FILE__) )) {
         return $post_id;
     if ( 'page' == $_POST['post_type'] ) {
         if ( !current_user_can( 'edit_page', $post_id ))
             return $post_id;
     } else {
         if ( !current_user_can( 'edit_post', $post_id ))
             return $post_id;

     $key = 'metaname_custom_box';
    $data = wpautop($_POST[$key]);

     // New, Update, and Delete
     if(get_post_meta($post_id, $key) == "") 
         add_post_meta($post_id, $key, $data, true);
     elseif($data != get_post_meta($post_id, $key, true))
         update_post_meta($post_id, $key, $data); 
     elseif($data == "")
         delete_post_meta($post_id, $key, get_post_meta($post_id, $key, true));        
  • update_post_meta will also add_post_meta if the meta_key to be inserted does not exist. Commented Dec 9, 2011 at 13:26

This seems to have changed a little in subsequent versions of Wordpress. You can now disable this functionality thusly:

add_filter('tiny_mce_before_init', function($init) {
    $init['wpautop'] = false;
    return $init;

Here's (a pared-down version of) what I use to custom-configure TinyMCE:

// http://tinymce.moxiecode.com/wiki.php/Configuration
function cbnet_tinymce_config( $init ) {

    // Don't remove line breaks
    $init['remove_linebreaks'] = false; 

    // Pass $init back to WordPress
    return $init;
add_filter('tiny_mce_before_init', 'cbnet_tinymce_config');

I assume this is what you tried already?


You may need to include some other config changes, such as:

// Convert newline characters to BR tags
$init['convert_newlines_to_brs'] = true; 
// Do not remove redundant BR tags
$init['remove_redundant_brs'] = false;

Play around with the TinyMCE configuration parameters, and find the one that you need to change.

  • No, I didn't use that. How would I filter my wp_tiny_mce with your function?
    – Pippin
    Commented Apr 27, 2011 at 4:06
  • Drop the code in functions.php. Commented Apr 27, 2011 at 13:07
  • Hmmm, that's not working.
    – Pippin
    Commented Apr 27, 2011 at 14:04
  • See my edit. You may not be targeting the correct configuration parameter. Commented Apr 27, 2011 at 14:20
  • 1
    It should already get hooked, into tiny_mce_before_init. You don't have it inside another function, or object, etc., do you? Commented Apr 27, 2011 at 15:19

Found perhaps a simpler workaround for this:

on the actual template, change this:

<?php echo get_the_content());?>

to this:

<?php echo wpautop(get_the_content());?>

This way wpautop() adds the tags stripped out by TinyMCE on a template by template basis.


why not you use wordpress new function wp_editor to render the tinymce. That way everything will get handled. And when you show the content to the user apply the filter the_content.

Like this:

$meta = "content of the metabox";
echo apply_filters('the_content', $meta);

The filter the_content will autmatically convert the link brakes to <br> and <p>.

  • At the time this question was posted, the wp_editor() function was not available.
    – Pippin
    Commented Jan 23, 2012 at 4:17

Another simple solution: Use Shortcodes!

Place this code into functions.php and use [br] in the content editor - HTML or visual - wherever you want a br tag to appear.

add_shortcode("br", "br_tag");

function br_tag(){


this is for who use the metaboxes for wordpress: Plugin Name: Meta Box Plugin URI: deluxeblogtips com/meta-box

i have modify the /vendor/meta-box/inc/fields/wysiwyg.php in static function :

static function html( $html, $meta, $field )

//just after the else i have added :
$meta = html_entity_decode($meta); // 
//and solve the problem ;)


Put this into functions.php, it calls the filter from the metaboxes pluggin:

function meta_wysiwyg_antes_save($meta)
    $meta = html_entity_decode($meta);
    return $meta;
add_filter("rwmb_(ID-OF-METABOX-FIELD)_meta", "meta_wysiwyg_antes_save"); //en meta-box.php 194
  • Now you cannot update the plugin anymore. Not a good solution.
    – fuxia
    Commented Nov 6, 2013 at 12:26
  • Have Some a little more constructive opinion? :) Where can i put this code on functions.php?
    – ClaudioC
    Commented Nov 6, 2013 at 17:15
  • Hook into save_post earlier than the plugin and prepare the value in a separate function?
    – fuxia
    Commented Nov 6, 2013 at 17:33

Your Answer

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

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