Skip to content

Instantly share code, notes, and snippets.

@vincentorback
Last active March 31, 2020 20:31
Show Gist options
  • Save vincentorback/18af95aea34bbc78b09b5d09686a9b3e to your computer and use it in GitHub Desktop.
Save vincentorback/18af95aea34bbc78b09b5d09686a9b3e to your computer and use it in GitHub Desktop.
Truncate text with PHP and CSS
/**
* Text truncation
*
* Prevent text from wrapping onto multiple lines, and truncate with an
* ellipsis.
*
* 1. Ensure that the node has a maximum width after which truncation can
* occur.
* 2. Fix for IE 8/9 if `word-wrap: break-word` is in effect on ancestor
* nodes.
*/
.u-textTruncate {
max-width: 100%; /* 1 */
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
word-wrap: normal !important; /* 2 */
}
<?php
function textTruncate($string = '', $widows = 2, $truncateClass = 'u-textTruncate')
{
// Remove trailing whitespace
$string = trim($string);
// If html, split up each element and run textTruncate on them.
// Only paragraphs and list items for now.
if (substr($string, 0, 2) === '<p' || substr($string, 0, 3) === '<li') {
$string = preg_replace_callback_array([
'/(\<[p][^\>]*\>)(.*?)(\<\/[p]\>)/' => function ($matches) {
return $matches[1] . textTruncate($matches[2]) . $matches[3];
},
'/(\<li[^\>]*\>)(.*?)(\<\/li\>)/' => function ($matches) {
return $matches[1] . textTruncate($matches[2]) . $matches[3];
}
], $string);
return $string;
}
// Split words into array
$split = explode(" ", str_replace('&nbsp;', " ", $string));
$split_count = sizeof($split);
// If less than 5 words; do not truncate
if ($split_count < 5) {
return $string;
}
// If last word is longer than 12 characters; do not truncate.
if (strlen($split[$split_count - 1]) > 12) {
return $string;
}
// If there are more words than allowed widows; truncate
if ($split_count > $widows) {
$words = $split[$split_count - 2] . ' ' . $split[$split_count - 1];
// Skip numbers because they could be long with spaces like 1 000 000.
if (!startsWithNumber($words) && endsWithNumber($words)) {
$string = str_replace($words, '<span class="' . $truncateClass . '">' . $words . '</span>', $string);
}
}
return $string;
}
function startsWithNumber ($str)
{
return preg_match('/^\d/', $str) === 1;
}
function endsWithNumber ($str)
{
return preg_match('/\d$/', $str) === 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment