limit_text is only outputting plain text and not showing bold font - php

I have some code that outputs a title and a description for a list of posts. I am trying to limit the length of text for both. The title is $story->title, and outputs just fine. However the description, represented by $story->excerpt in the code, contains html tags in the database. The limit_text function seems to strip these tags from the text. I think I need to limit the characters differently or need a function to allow those tags to work.
I have tried some functions that allows the tags to be seen but not function properly. But I am new to php in general so I don't know many functions.
<?php
foreach($stories as $story) {
echo '<h2>'.limit_text($story->title, 80).'</h2>';
if(!empty($story->excerpt)) {
echo '<p>'.limit_text($story->excerpt, 150).'</p>';
} else {
echo limit_text($story->body, 150);
}
}
?>
I found the function for limit_text
function limit_text($string, $limit = 140) {
$string = preg_replace('/<figcaption>.*?<\/figcaption>/','',$string);
$string = preg_replace('/<div class=\"wp_image_caption\">.*?<\/div>/','',$string);
$string = str_replace(' ','',$string);
$string = substr($string, strpos($string, "<p><strong>"));
$string = strip_tags($string);
$string = substr($string, 0, $limit);
$string = $string.'...';
return $string;
}

The reason why my tags were being stripped was the strip_tagsmethod right in the function. Duh. Hehe. Thanks for the comments.

Try this limit text function instead
public function limitText($text, $len)
{
$text = preg_match('#<\s*?b\b[^>]*>(.*?)</b\b[^>]*>#s', $text, $matches);
return "<b>" . substr($text,0, $len) . "</b>";
}

Related

How can I split html value and normal string into different array in php?

Say I have string such as below:
"b<a=2<sup>2</sup>"
Actually its a formula. I need to display this formula on webpage but after b string is hiding because its considered as broken anchor tag. I tried with htmlspecialchars method but it returns complete string as plain text. I am trying with some regex but I can get only text between some tags.
UPDATE:
This seems to work with this formula:
"(c<a) = (b<a) = 2<sup>2</sup>"
And even with this formula:
"b<a=2<sup>2</sup>"
HERE'S THE MAGIC:
<?php
$_string = "b<a=2<sup>2</sup>";
$string = "(c<a) = (b<a) = 2<sup>2</sup>";
$open_sup = strpos($string,"<sup>");
$close_sup = strpos($string,"</sup>");
$chars_array = str_split($string);
foreach($chars_array as $index => $char)
{
if($index != $open_sup && $index != $close_sup)
{
if($char == "<")
{
echo "<";
}
else{
echo $char;
}
}
else{
echo $char;
}
}
OLD SOLUTION (DOESN'T WORK)
Maybe this can help:
I've tried to backslash chars, but it doesn't work as expected.
Then i've tried this one:
<?php
$string = "b&lta=2<sup>2</sup>";
echo $string;
?>
Using &lt html entity it seems to work if i understood your problem...
Let me know
Probably you can give spaces such as :
b < a = 2<sup>2</sup>
It does not disappear the tag and looks much more understanding....
You could try this regex approach, which should skip elements.
$regex = '/<(.*?)\h*.*>.+<\/\1>(*SKIP)(*FAIL)|(<|>)/';
$string = 'b<a=2<sup>2</sup>';
$string = preg_replace_callback($regex, function($match) {
return htmlentities($match[2]);
}, $string);
echo $string;
Output:
b<a=2<sup>2</sup>
PHP Demo: https://eval.in/507605
Regex101: https://regex101.com/r/kD0iM0/1

Create and simplify links from body of text in PHP

I need to extract all links in a body of text in php and make them clickable. The problem is I can't seem to simplify the text of the link in any way.
I tried using preg_replace_callback but I can't seem to get the trimming function working properly:
function trimUrl($url){
$maxLength = 3;
if(strlen($url)>$maxLength){
$urlShort = substr($str,0,$maxLength).'...';
}
else{
$urlShort = $url;
}
return $urlShort;
}
function enableLinks($text){
return preg_replace_callback("!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9#:%_+.~#?&;//=]+)!i", "<a href='$1' target='_blank'>".trimUrl("$1")."</a>", $text);
}
enableLinks("Visit more work at http://www.google.com");
How can I run a second function within the preg_replace_callback that trims the output text?
What if you used a function inside that function. So if the first function evaluates to true then run this next function? And also try using preg_replace_callback in a variable format so its easier to work with
First, you are using substring(). Where have you defined the variable $str? And, if you do this:
$var = preg_replace_callback("!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9#:%_+.~#?&;//=]+)!i", "<a href='$1' target='_blank'>".trimUrl("$1")."</a>", $text);
Than can you use a new function:
return function($var);
Ended up using a more expanded function to achieve this, works on multiple urls with or without "http://":
function trimUrlOutput($url){
$maxLength = 30;
if(strlen($url)>$maxLength){
$urlShort = substr($url,0,$maxLength).'...';
}
else{
$urlShort = $url;
}
return $urlShort;
}
function enableLinks($text){
$text = ereg_replace( "www\.", "http://www.", $text );
$text = ereg_replace( "http://http://www\.", "http://www.", $text );
$text = ereg_replace( "https://http://www\.", "https://www.", $text );
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
if(preg_match_all($reg_exUrl, $text, $url)) {
$matches = array_unique($url[0]);
foreach($matches as $match) {
$linkText = trimUrlOutput($match);
$replacement = "<a href=".$match." target='_blank'>{$linkText}</a>";
$text = str_replace($match,$replacement,$text);
}
return $text;
}
else{
return $text;
}
}
enableLinks("Visit more work at http://www.google.com");
Hope this helps someone.

Excerpt isn't working with file contents

$excerpt= excerpt(file_get_contents("data/file.txt"), 30);
echo $excerpt;
function excerpt($str, $chars){
$index = strripos($str, ' ');
return substr($str, 0, $index)."...";
}
It don't return the text stripped at the 30 characters or less. It returns the whole text without the last word and the dots added but if you use a string typed manually it works perfect.
Why this isn't working if content is loaded from a text file? I think that the /n's are broking the strripos.
You want to use stripos, not strripos.
<?php
$excerpt= excerpt(file_get_contents("data/file.txt"), 30);
echo $excerpt;
function excerpt($str, $chars){
$index = stripos($str, " ", $chars);
return substr($str, 0, $index)."...";
}
?>
The problem is not related to the stripos usage. As I can see you're trying to trim the string at 30 characters without cutting words in half. In order to do that you need to correct your excerpt function:
function excerpt($str, $chars) {
//no need to trim, already shorter than wanted dimension
if (strlen($tr) <= $chars) {
return $str;
}
//find last space within wanted dimension
$last_space = strrpos(substr($str, 0, $chars), ' ');
$trimmed_text = substr($str, 0, $last_space);
return $trimmed_text . '...';
}
and yes, your function doesn't even use the $chars param...
I gues you want an excerpt with as many whole words as possible.
Some tips:
If you only just want the first 3o chars you should not read the whole file!
What you should do: read only to the maximum excerpt lenght and then format it.
function readExcerpt($path){
$fhand = fopen($path,"r");
$excerpt = fread($fhand ,30);
fclose($fhand);
return $excerpt;
}
function fromatExcerpt($excerpt){
//remove last word/word fragment
$index = strripos($excerpt,' ');
if($index!==false){
$excerpt= substr($excerpt,0,$index);
}
return $excerpt.'...';
}
echo fromatExcerpt(readExcerpt("D:\hotfix.txt"));

How can I shorten a very long string in PHP

I have a problem with a PHP breadcrumb function I am using, when the page name is very long, it overflows out of the box, which then looks really ugly.
My question is, how can I achieve this: "This is a very long string" to "This is..." with PHP?
Any other ideas on how I could handle this problem would also be appreciated, thanx in advance!
Here is the breadcrumb function:
function breadcrumbs() {
// Breadcrumb navigation
if (is_page() && !is_front_page() || is_single() || is_category()) {
echo '<ul class="breadcrumbs">';
echo '<li class="front_page">'.get_bloginfo('name').' <span style="color: #FFF;">»</span> </li>';
if (is_page()) {
$ancestors = get_post_ancestors($post);
if ($ancestors) {
$ancestors = array_reverse($ancestors);
foreach ($ancestors as $crumb) {
echo '<li>'.get_the_title($crumb).' <span style="color: #FFF;">»</span> </li>';
}
}
}
if (is_single()) {
$category = get_the_category();
echo '<li>'.$category[0]->cat_name.'</li>';
}
if (is_category()) {
$category = get_the_category();
echo '<li>'.$category[0]->cat_name.'</li>';
}
// Current page
if (is_page() || is_single()) {
echo '<li class="current">'.get_the_title().'</li>';
}
echo '</ul>';
} elseif (is_front_page()) {
// Front page
echo '<ul class="breadcrumbs">';
echo '<li class="front_page">'.get_bloginfo('name').'</li>';
echo '<li class="current">Home Page</li>';
echo '</ul>';
}
}
If you want a more nice (word limited) trucation you can use explode to split the string by spaces and then append each word (array entry) until you've reached your max limit
Something like:
define("MAX_LEN", 15);
$sentance = "Hello this is a long sentance";
$words = explode(' ', $sentance);
$newStr = "";
foreach($words as $word) {
if(strlen($newStr." ".$word) >= MAX_LEN) {
break;
}
$newStr = $newStr." ".$word;
}
If you are working with UTF-8 as charset, I suggest using the mb_strimwidth method as it is multibyte safe and won´t mess up multibyte chars. It also appends a placeholder string like ... automatically, with substr you´d have to do that in an additional step.
Usage sample:
echo mb_strimwidth("Hello World", 0, 10, "...", "UTF-8"); // .. or some other charset
// outputs Hello W...
You can safely use substr.
and eventually wordwrap() to break long words
$string = "This is a very long string";
$newString = substr( $string, 0, 7)."...";
// Output = This is...
Ideally, it should be done on the client side. You can use CSS/JS for the same.
Set this CSS property: text-overflow: ellipsis.
However, it will work only in IE. To use the same in Firefox as well, you can do something like this.
If you do not mind javascript plugins, use one of the jQuery ellipsis plugin.
Edit: These methods will work even when dealing with unicode, which can be a bit tricky if you try to handle this using php. (Like substr function)
Edit 2: If your problem is just the overflowing text and you do not mind not having the "..." at the end then it is even more simple. Simply, use the CSS: text-overflow: hidden;.
You can truncate the string at max length and then search for the last space:
Multibyte safe (Requires PHP > = 4.2)
function mb_TruncateString($string, $length = 40, $marker = "...")
{
if (mb_strlen($string) <= $length)
return $string;
// Trim at given length
$string = mb_substr($string, 0, $length);
// Get the text before the last space
if(mb_ereg("(.*)\s", $string, $matches))
$string = $matches[1];
return $string . $marker;
}
Following is not multibyte safe
function TruncateString($string, $length = 40, $marker = "...")
{
if (strlen($string) <= $length)
return $string;
// Trim at given length
$string = substr($string, 0, $length);
// Get the text before the last space
if(preg_match("/(.*)\s/i", $string, $matches))
$string = $matches[1];
return $string . $marker;
}
You're after a truncate function. This is what I use:
/**
* #param string $str
* #param int $length
* #return string
*/
function truncate($str, $length=100)
{
$str = substr($str, $length);
$words = explode(' ', $str); // separate words into an array
array_pop($words); // discard last item, as 9/10 times it's a partial word
$str = implode(' ', $words); // re-glue the string
return $str;
}
And usage:
echo truncate('This is a very long page name that will eventually be truncated', 15);

How to get first x chars from a string, without cutting off the last word?

I have the following string in a variable.
Stack Overflow is as frictionless and painless to use as we could make it.
I want to fetch first 28 characters from the above line, so normally if I use substr then it will give me Stack Overflow is as frictio this output but I want output as:
Stack Overflow is as...
Is there any pre-made function in PHP to do so, Or please provide me code for this in PHP?
Edited:
I want total 28 characters from the string without breaking a word, if it will return me few less characters than 28 without breaking a word, that's fine.
You can use the wordwrap() function, then explode on newline and take the first part:
$str = wordwrap($str, 28);
$str = explode("\n", $str);
$str = $str[0] . '...';
From AlfaSky:
function addEllipsis($string, $length, $end='…')
{
if (strlen($string) > $length)
{
$length -= strlen($end);
$string = substr($string, 0, $length);
$string .= $end;
}
return $string;
}
An alternate, more featureful implementation from Elliott Brueggeman's blog:
/**
* trims text to a space then adds ellipses if desired
* #param string $input text to trim
* #param int $length in characters to trim to
* #param bool $ellipses if ellipses (...) are to be added
* #param bool $strip_html if html tags are to be stripped
* #return string
*/
function trim_text($input, $length, $ellipses = true, $strip_html = true) {
//strip tags, if desired
if ($strip_html) {
$input = strip_tags($input);
}
//no need to trim, already shorter than trim length
if (strlen($input) <= $length) {
return $input;
}
//find last space within length
$last_space = strrpos(substr($input, 0, $length), ' ');
$trimmed_text = substr($input, 0, $last_space);
//add ellipses (...)
if ($ellipses) {
$trimmed_text .= '...';
}
return $trimmed_text;
}
(Google search: "php trim ellipses")
Here's one way you could do it:
$str = "Stack Overflow is as frictionless and painless to use as we could make it.";
$strMax = 28;
$strTrim = ((strlen($str) < $strMax-3) ? $str : substr($str, 0, $strMax-3)."...");
//or this way to trim to full words
$strFull = ((strlen($str) < $strMax-3) ? $str : strrpos(substr($str, 0, $strMax-3),' ')."...");
This is the easiest way:
<?php
$title = "this is the title of my website!";
$number_of_characters = 15;
echo substr($title, 0, strrpos(substr($title, 0, $number_of_characters), " "));
?>
This is the simplest solution I know of...
substr($string,0,strrpos(substr($string,0,28),' ')).'...';
I would use a string tokenizer to split the string into words much like this:
$string = "Stack Overflow is as frictionless and painless to use as we could make it.";
$tokenized_string = strtok($string, " ");
Then you can pull out the individual words any way you want.
Edit: Greg has a much better and more elegant way of doing what you want. I would go with his wordwrap() solution.
you can use wordwrap.
string wordwrap ( string $str [, int $width= 75 [, string $break= "\n" [, bool $cut= false ]]] )
-
function firstNChars($str, $n) {
return array_shift(explode("\n", wordwrap($str, $n)));
}
echo firstNChars("bla blah long string", 25) . "...";
disclaimer: didn't test it.
additionally, if your string contains \ns, it might get broken earlier.
try:
$string='Stack Overflow is as frictionless and painless to use as we could make it.';
$n=28;
$break=strpos(wordwrap($string, $n,'<<||>>'),'<<||>>');
print substr($string,0,($break==0?strlen($string):$break)).(strlen($string)>$n?'...':'');
$string='Stack Overflow';
$n=28;
$break=strpos(wordwrap($string, $n,'<<||>>'),'<<||>>');
print substr($string,0,($break==0?strlen($string):$break)).(strlen($string)>$n?'...':'');
function truncate( $string, $limit, $break=" ", $pad="...") {
// return with no change if string is shorter than $limit
if(strlen($string) <= $limit){
return $string;
}
$string = substr($string, 0, $limit);
if(false !== ($breakpoint = strrpos($string, $break))){
$string = substr($string, 0, $breakpoint);
}
return $string . $pad;
}
Problems can arise if your string has html tags, &nbsp and multiple spaces. Here is what I use that takes care of everything:
function LimitText($string,$limit,$remove_html=0){
if ($remove_html==1){$string=strip_tags($string);}
$newstring = preg_replace("/(?:\s| )+/"," ",$string, -1); // replace &nbsp with space
$newstring = preg_replace(array('/\s{2,}/','/[\t\n]/'),' ',$newstring); // replace duplicate spaces
if (strlen($newstring)<=$limit) { return $newstring; } // ensure length is more than $limit
$newstring = substr($newstring,0,strrpos(substr($newstring,0,$limit),' '));
return $newstring;
}
usage:
$string = 'My wife is jealous of stackoverflow';
echo LimitText($string,20);
// My wife is jealous
usage with html:
$string = '<div><p>My wife is jealous of stackoverflow</p></div>';
echo LimitText($string,20,1);
// My wife is jealous
This's Working for me Perfect
function WordLimt($Keyword,$WordLimit){
if (strlen($Keyword)<=$WordLimit) { return $Keyword; }
$Keyword= substr($Keyword,0,strrpos(substr($Keyword,0,$WordLimit),' '));
return $Keyword;
}
echo WordLimt($MyWords,28);
// OutPut : Stack Overflow is as
it will adjust and break on last Space without cut word...
why not try exploding it and getting the first 4 elements of the array?
substr("some string", 0, x);
From the PHP Manual

Categories