tags:

views:

263

answers:

6

I have a block of text which occasionally has a really long word/web address which breaks out of my site's layout.

What is the best way to go through this block of text and shorten the words?

EXAMPLE:

this is some text and this a long word appears like this fkdfjdksodifjdisosdidjsosdifosdfiosdfoisjdfoijsdfoijsdfoijsdfoijsdfoijsdfoisjdfoisdjfoisdfjosdifjosdifjosdifjosdifjosdifjsodifjosdifjosidjfosdifjsdoiofsij and i need that to either wrap in ALL browsers or trim the word.

+1  A: 

You need wordwrap function i suppose.

Sarfraz
Unfortunatly that wraps the entire string, not just the long words.
David
+1  A: 

You could truncate the string so it appears with an ellipsis in the middle or the end of the string. However, this would be independent from the actual rendering in a webbrowser. There is no way for PHP to determine the actual length a string will have with a certain font when rendered in a browser, especially if you have defined fallback fonts and don't know which font is used in the browser, e.g.

font-family: Verdana, Arial, sans-serif;

Compare the following:

I am 23 characters long
I am 23 characters long

Both chars have the same length, but since the one is monotyped and the other isn't the actual width it will have is different. PHP cannot determine this. You'd have to find a client side technology, probably JavaScript, to solve this for you.

You could also wrap the text into an element with the CSS property overflow:hidden to make the text disappear after a fixed length.

Look around SO. I'm pretty sure this was asked more than once before.

Gordon
+1 for the CSS solution. Simplicity wins.
Boldewyn
A: 

You could do something like this:

preg_replace("/(\\S{20})/", '$1‌', $text);

It should* add a zero-width non-join character into all words each 20 characters. This means they will word-wrap.

* (untested)

nickf
+1  A: 
function fixlongwords($string) {

$exploded = explode(' ', $string);
$result = '';
foreach($exploded as $curr) {
    if(strlen($curr) > 20) {
    $curr = wordwrap($curr, 20, '<br/>\n');
}
    $result .= $curr.' ';
}

return $result;

}

This should do the job.

JonnyLitt
+1  A: 

You could use the word-wrap: break-word CSS property to wrap the text that breaks your layout.

Check out the Mozilla Developer Center examples which demonstrate its use.

Simon Lieschke
Nice one. That's probably the best approach. Here is an code snippet for making it cross browser: http://snipplr.com/view/10979/css-cross-browser-word-wrap/
Gordon
A: 

Based on @JonnyLitt's answer, here's my take on the problem:

<?php

function insertSoftBreak($string, $interval=20, $breakChr='&shy;') {
    $splitString = explode(' ', $string);
    foreach($splitString as $key => $val) {
        if(strlen($val)>$interval) {
            $splitString[$key] = wordwrap($val, $interval, $breakChr, true);
        }
    }
    return implode(' ', $splitString);
}

$string = 'Hello, My name is fwwfdfhhhfhhhfrhgrhffwfweronwefbwuecfbryhfbqpibcqpbfefpibcyhpihbasdcbiasdfayifvbpbfawfgawg, because that is my name.';
echo insertSoftBreak($string);

?>

Breaking the string up in space-seperated values, check the length of each individual 'word' (words include symbols like dot, comma, or question mark). For each word, check if the length is longer than $interval characters, and if so, insert a &shy; (soft hyphen) every $interval'th character.

I've chosen soft hyphens because they seem to be relatively well-supported across browsers, and they usually don't show unless the word actually wraps at that position.

I'm not aware of any other usable (and well supported) HTML entities that could be used instead (&zwnj; does not seem to work in FF 3.6, at least), so if crossbrowser support for &shy; turns out lacking, a pure CSS or Javascript-based solution would be best.

Duroth