ZF-2348: Zend_View_Helper_Paragraph


A new view helper, intended to replace nl2br() - ease and propagate the use of the semantically meaningful


p> element instead of


  • trim()-s the supplied text.
  • Deletes all carriage returns
  • Searches for all (possibly multiple) newlines, and replaces them with a closing and an opening p element (using preg_replace()).
  • Wraps the result into an opening and a closing p tag and returns.


class Zend_View_Helper_Paragraph
    public function paragraph($text)
        return '

' . preg_replace('/[\r\n]+(\h+[\r\n]+)?/', '

', trim($text)) . '

'; } }


In your view:

echo $this->paragraph($this->text);


Fixing a bug by eliminating carriage returns.

What about something like this?

function wpautop($pee, $br = 1) {
    $pee = $pee . "\n"; // just to make things a little easier, pad the end
    $pee = preg_replace('|
|', "\n\n", $pee); // Space things out a little $allblocks = '(?:table|thead|tfoot|caption|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)'; $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 $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "


\n", $pee); // make paragraphs, including one at the end $pee = preg_replace('|


|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace $pee = preg_replace('!

([^<]+)\s*?((?:div|address|form)[^>]*>)!', "


$2", $pee); $pee = preg_replace( '|

|', "$1

", $pee ); $pee = preg_replace('!

\s*(?' . $allblocks . '[^>]*>)\s*

!', "$1", $pee); // don't pee all over a tag $pee = preg_replace("|


|", "$1", $pee); // problem with nested lists $pee = preg_replace('|

]*)>|i', "

", $pee); $pee = str_replace('

', '
', $pee); $pee = preg_replace('!

\s*(?' . $allblocks . '[^>]*>)!', "$1", $pee); $pee = preg_replace('!(?' . $allblocks . '[^>]*>)\s*

!', "$1", $pee); if ($br) { $pee = preg_replace('/<(script|style).*?<\/\\1>/se', 'str_replace("\n", "", "\\0")', $pee); $pee = preg_replace('|(?)\s*\n|', "
\n", $pee); // optionally make line breaks $pee = str_replace('', "\n", $pee); } $pee = preg_replace('!(?' . $allblocks . '[^>]*>)\s*
!', "$1", $pee); $pee = preg_replace('!
(\s*?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee); if (strpos($pee, '
!is', 'clean_pre', $pee ); $pee = preg_replace( "|\n$|", '', $pee ); return $pee; }

I use it and I created a helper in my application for it but there is an explication of it. http://photomatt.net/scripts/autop/

It's part of Word Press so I'm not sure about the whole thing with the cla but if people are supportive of it I will gladly contact him to see if he has a problem signing one to share the code.

Thank you for the advice. I'm thinking about the advantages of handling the block level elements, but I don't want to bloat the function. In the meantime, I have improved the regex to avoid generating paragraphs containing only white-space.

Refactoring a bit: using smarter regex to deal with carriage returns instead of str_replace().

I just received an email back from Matt and he said the code is public domain + MIT + GPL so if we go with the more advanced function if we still need Matt to submit a CLA

I think that if you are going to do a paragraph class it should support block level elements and such as if I were to use this I would want to pass in text that I have stored in my db for say a news story or something to this function to normalize the paragraphs which is what I created my helper for.

while I do see your point in a simple function I think the advanced one would fit the 80/20 rule better.

I've thinked about it, you're right, will be added block-level-awareness. I don't want to copy-paste Matt's code, rather write own, so licensing won't be a problem.

Look back for upgrades in a few days.

On reviewing the comments, I feel that this needs to include block-level awareness before it can be included with ZF. Unless Ádám can complete it by next Wednesday (22 Feb 2008), we'll need to postpone its inclusion until after that release.

Please categorize/fix as needed.

Hey all, whats the status of this?

Is there code in the incubator for this helper? Is this a Jira based proposal?

Can we get this to Proposal like standards? Tests, docs, etc?


Ralph: I would like to implement block level awareness as soon as possible, but I was and will be a bit busy in the next ~month because of my work and exams... There's no code in the incubator yet. And yes, something like that :) Should I write a standard proposal for this?

Scheduling for next minor release. Adam, please coordinate with Ralph, and indicate status of block-level awareness.

What's the status of this?? Should it be moved to the proposals and done that way?

I intend to create a proposal for this. I have an almost working code for months now, but there some scurvy bug, which I had no time fix.

If you create the proposal and post the code I would be happy to help you find any bugs that exist in the code by writing unittests and such.

Is there a proposal for this? If not, I am inclined to close this issue.

Joó can you post your sample code. I will create the proposal and get this running if you don't have time.

Jon, I would be glad if you could help me with this. More on this in email. Issue is closed, proposal coming.