Ask your WordPress questions! Pay money and get answers fast! (more info)

stop editor removing br and p tags WordPress

  • SOLVED

I know this is a big problem with WordPress but is there a work around?

I want to be able to press enter twice and to keep the spacing when published.

Currently I get this:


<p>some very nice text here then a return</p>
<p>then a double return</p>
<p>then a break<br />
then two</p>
<p>then end</p>


The big problem is where I press enter twice it only outputs one p tag.
It also changes the double br (shift and enter twice) to a p tag.

The main reason want this is for when aligning images in a page/post.
If two images are floated left they will be in the way at time and i need to be able to move it down by pressing enter.

EDIT:

I have tried the TinyMCE Advanced plugin but unfortunately the plugin has a bug that adds in extra p tags with a br space such as <p><br class"_spacer" /></p> especially where images are so the plugin is not an option.

Is there a way to add something in the functions file to stop wpautop from removing the br tags? if i can get that to work then i think i can combine that with the advanced editor.

if i edit the formatting.php file and change it to function wpautop($pee, $br = 0) {

it keeps the br tags but ideally i need something to go into my functions file

Answers (6)

2010-05-04

Erez S answers:

Install this plugin:
http://wordpress.org/extend/plugins/tinymce-advanced/
Enjoy


Lee comments:

Please see the edit


Erez S comments:

We can preventing WordPress from adding <p> and <br> tags completely in our posts/contents. Just modify this page /wp-includes/formatting.php

Change the following line

function wpautop($pee, $br = 1) {

to
function wpautop($pee, $br = 0) {

AND

comment this line for preventing extra <p> tags

$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee);

The problem is you would have to modify this page each time there is new wordpress version


Lee comments:

is there a way to use a hook so i can put it in the functions.php file so it won't require updating it every time WordPress has a new release?


Erez S comments:

Or you can posts this code instead of new line:
<br style=”height:4em” />
Through the HTML editor
BTW this is the code above but in CODE tag:
function wpautop($pee, $br = 1) {
to
function wpautop($pee, $br = 0) {
AND
comment this line for preventing extra <p> tags
$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee);
to
//$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee);


Erez S comments:

As far as I know there is no hook that working in this particular function


Erez S comments:

Just found good filter for what I've wrote you above:
remove_filter ('the_content', 'wpautop');


Erez S comments:

Try this:
function wpautop2($pee, $br = 0) {

if ( trim($pee) === '' )
return '';
$pee = $pee . "\n"; // just to make things a little easier, pad the end
$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
// Space things out a little
$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr|fieldset|legend)';
$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
if ( strpos($pee, '<object') !== false ) {
$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
$pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
}
$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
// make paragraphs, including one at the end
$pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);
$pee = '';
foreach ( $pees as $tinkle )
$pee .= '' . trim($tinkle, "\n") . "\n";
$pee = preg_replace('|<p>\s*</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
$pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
if ($br) {
$pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<WPPreserveNewline />", $matches[0]);'), $pee);
$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
$pee = str_replace('<WPPreserveNewline />', "\n", $pee);
}
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
if (strpos($pee, '<pre') !== false)
$pee = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is', 'clean_pre', $pee );
$pee = preg_replace( "|\n</p>$|", '</p>', $pee );

return $pee;
}
remove_filter ('the_content', 'wpautop');
add_filter ('the_content', 'wpautop2');


Lee comments:

shame it did not work i get totally unformatted text.


Erez S comments:

I can't find any solution,so maybe you can use this plugin:
http://wordpress.org/extend/plugins/post-editor-buttons/
and add new button to the editor that will add this code:
<br style=”height:4em” />


Lee comments:

is there a way to add something in the functions file to stop wpautop from removing the br tags? if i can get that to work then i think i can combine that with the advanced editor.

if i edit the formatting.php file and change it to function wpautop($pee, $br = 0) {

it keeps the br tags but ideally i need something to go into my functions file


Erez S comments:

This will do what you need:
function wpautop2($pee) {

if ( trim($pee) === '' )
return '';
$pee = $pee . "\n"; // just to make things a little easier, pad the end
$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
// Space things out a little
$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr|fieldset|legend)';
$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
if ( strpos($pee, '<object') !== false ) {
$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
$pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
}
$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
// make paragraphs, including one at the end
$pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);
$pee = '';
foreach ( $pees as $tinkle )
$pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
$pee = preg_replace('|<p>\s*</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
$pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
if (false) {
$pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<WPPreserveNewline />", $matches[0]);'), $pee);
$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
$pee = str_replace('<WPPreserveNewline />', "\n", $pee);
}
$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
if (strpos($pee, '<pre') !== false)
$pee = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is', 'clean_pre', $pee );
$pee = preg_replace( "|\n</p>$|", '</p>', $pee );

return $pee;
}
remove_filter ('the_content', 'wpautop');
add_filter ('the_content', 'wpautop2');

Enjoy


Erez S comments:

I have an idea,maybe you can add blank image and to set her height to the line height*lines you need to have


Lee comments:

Thanks for trying I very much appreciate your effort. The image idea is not very user friendly. What I really need is a bit of code I can use in the functions file or a plugin to stop the removal of the br tags


Erez S comments:

I got a solution ! Install TinyMCE Advanced and activate the option that stop removing the <p> and <br> tags,and then add this code to your functions.php file:
function wpautop2($pee) {
$pee = str_replace('<p><br class="spacer_" /></p>','<br />',$pee);
return $pee;
}
add_filter ('the_content', 'wpautop2');

Enjoy


Erez S comments:

BTW,now that I think about it,you was able to add margin to your images throgh your css,but I already found you good solution in the message above:
<blockquote>I got a solution ! Install TinyMCE Advanced and activate the option that stop removing the <p> and <br> tags,and then add this code to your functions.php file:
function wpautop2($pee) {
$pee = str_replace('<p><br class="spacer_" /></p>','<br />',$pee);
return $pee;
}
add_filter ('the_content', 'wpautop2');

Enjoy </blockquote>


Lee comments:

Thanks that does seem to work. By removing the p tag the gap reduced if the double p tag with spacers appears but still allows me to use more than one br - thanks

2010-05-04

Milan Petrovic answers:

Best solution is to install this plugin:

http://wordpress.org/extend/plugins/tinymce-advanced/

One of the options this plugin has (Settings -> TinyMCE Advanced -> Advanced) is to modify the editor behavior and stop it from Stop removing the <p> and <br /> tags when saving.


Lee comments:

Unfortunately the TInyMCE Advanced plugin has bugs that add in extra p tags with a br space such as <p><br class"_spacer" /></p> especially where images are so the plugin is not an option.


Milan Petrovic comments:

No bugs with this plugin as far as I know. I use it on all my blogs, and on 2 of them I use that option to stop removing tags. Maybe some old version were buggy, but the latest one is not.


Lee comments:

I have looked on the plugin homepage and in the comments others have the same issue

2010-05-04

Monster Coder answers:

You may try putting the following line:

<br class="blank">

this won't be stripped by wordpress editor. you may also read:
http://www.tystips.com/archives/54/how2-insert-space-between-paragraphs-in-wordpress-without-using-br-and-p-tags/

This simple plugins may help you too.
http://urbangiraffe.com/plugins/disable-wpautop/


Lee comments:

Thanks for the reply unfortunately using code is not an option as the editor who will be using it does not know HTML and it would get them very confused


Monster Coder comments:

It is better to use http://urbangiraffe.com/plugins/disable-wpautop/ plugin rather than changing a core file. Changing core file may be the last resort of doing something as it may break the portability.


Lee comments:

using that plugin or using the remove_filter in the functions file to stop the wpautop working means that the output has no html what so ever as it does not get formatted.

if i could use that but have the p tags etc in there then that would be perfect

2010-05-04

Samuel Arendt answers:

easy,

functions.php


<?php
// functions
function clear_br($content){
return str_replace("<br />","</p><p>", $content);
}
add_filter('the_content', 'clear_br');
?>


Lee comments:

almost but not quite. i need it to allow me to press enter twice and leave the empty paragraph and allow me to press shift and enter twice for two br tags and leave them


Samuel Arendt comments:

Unless you change the editor, I do not see how, because even with shift pressed, it creates a blank space, the solution will cause the <br/> only becomes a double.

<?php

// functions

function clear_br($content){

return str_replace("<br />","<br /><br />", $content);

}

add_filter('the_content', 'clear_br');

?>


Lee comments:

is there a way to add something in the functions file to stop wpautop from removing the br tags? if i can get that to work then i think i can combine that with the advanced editor.

if i edit the formatting.php file and change it to function wpautop($pee, $br = 0) {

it keeps the br tags but ideally i need something to go into my functions file


Samuel Arendt comments:

???


<?php

// functions

function clear_br($content){

return str_replace("<br />","", $content);

}

add_filter('the_content', 'clear_br');

?>

2010-05-04

Andrzej answers:

I believe there would be also a problem with TinyMCE, even if you tune wp_autop function to render as you want, every time content will go back to TinyMCE, double <p> tags gets removed.


Andrzej comments:

If you would like to do the <em>wpautop($pee, $br = 0)</em> solution, but without touching core code, here's what you add to your functions.php file:

function my_wpautop_correction() {
function my_wpautop( $pee ) {
return wpautop($pee, 0);
}
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );
add_filter( 'the_content', 'my_wpautop' );
add_filter( 'the_excerpt', 'my_wpautop' );
}
add_action('pre_get_posts', 'my_wpautop_correction');


Andrzej comments:

...and as I said, this task is kinda tricky, becasue even if you fix the backend side of it, in this case change wpautop function, TinyMCE editor will always remove multiple <p> tags, so you end up adding them every time you go back and edit a post. Adjusting that would require writing a JavaScript plugin to TinyMCE, which unfortunately doesn't fit in this question's budget.

I have an idea, which might be a possible solution - you said the editor would be a non-technical person, who shouldn't need to write any code. Would it be possible to convice him to put just an _ (underline) character in the paragraph that he wants to leave blank? (So in code view it would be like <p>_</p>, in visual editor just a single _ in paragrah)

Then, by adding this code to fuctions.php, all this "_" paragraphs would be changed to blank ones:


function my_replaceblankparas( $content ) {
return str_replace( '<p>_</p>', '<p>&nbsp;</p>', $content );
}
add_filter( 'the_content', 'my_replaceblankparas' );
add_filter( 'the_excerpt', 'my_replaceblankparas' );


Lee comments:

i can use the tinymce advanced plugin to stop the editor removing the p and br tags but i need to stop the wpautop removing the double br tags. removing the filter completely does not work. If i manually go into formatting and change this line to wpautop($pee, $br = 0) { then it works but is there a hook i can use in my functions file?


Andrzej comments:

Hey,
I'm actaully not tring to convice you to use TinyMCE Advanced - pls read my post above. If you're looking to hook into functions.php with wpautop change, then also see my post (2 above this :)).


Lee comments:

thanks for the reply. How much would it be to write a TintMCE plugin?


Andrzej comments:

just send you a private message


Andrzej comments:

Hey, does this tips taken you anywhere? Are you able to point a winner? :)

2010-05-04

Sidd answers:

There is one based on somewhat cheating. No code is required.

Where you need to have <br /> just add some //////////////////// as many required and then select all of them and change the font colour to that of the background and it will act as white space.
This can be done in the visual editor itself.

Post this in your HTML viewer and then switch to the Visual mode and see the line breaks !
<blockquote>"Hello

<span style="color: #ffffff;">///////</span>

<span style="color: #ffffff;">///////</span>

Next paragraph here with 2 lines breaks before
"</blockquote>

This is just playing around but might do the trick for you !


Lee comments:

nice idea but this won't work as it will mean anyone reading the site without css for example will see ///////// in the text.