Skip to content

Instantly share code, notes, and snippets.

@axi
Forked from instabledesign/TruncateHtmlExtension.php
Last active July 27, 2016 03:27
Show Gist options
  • Save axi/9639247 to your computer and use it in GitHub Desktop.
Save axi/9639247 to your computer and use it in GitHub Desktop.
<?php
/*
* This file is part of the Twig Extension TruncateHtmlExtension.
*
* Author Leon Radley <[email protected]>
* Rewrite by Instabledesign
*
*
* Truncate Html string without stripping tags
* register in Resources/config/services.yml with:
*
* services:
* truncatehtml.twig.extension:
* class: Radley\TwigExtensionBundle\Extension\TruncateHtmlExtension
* tags:
* - { name: twig.extension }
*
* Usage:
* {{ htmlstring|truncatehtml(500)|raw }}
*/
namespace Radley\TwigExtensionBundle\Extension;
class TruncateHtmlExtension extends \Twig_Extension
{
public function getName() {
return 'truncatehtml';
}
public function getFilters()
{
return array('truncatehtml' => new \Twig_Filter_Method($this, 'truncatehtml'));
}
public function truncatehtml($html, $limit, $elipsis = '')
{
return TruncateHtmlString::cut($html, $limit, $elipsis);
}
}
<?php
/*
* This file is part of the Twig Extension TruncateHtmlExtension.
*
* Author Leon Radley <[email protected]>
* Rewrite by Instabledesign
*
*/
namespace Radley\TwigExtensionBundle\Extension;
class TruncateHtmlString {
/**
* Return semantic truncate HTML
*
* @param string $html HTML code
* @param int $length The length of HTML truncate
* @param string $elipsis The elipsis string put at the end of last word
* @param string $encoding The encoding HTML
*
* @return string Return semantic truncate HTML string
*/
public static function cut($html, $length = 500, $elipsis = '', $encoding = 'UTF-8') {
$fromXML = new \DomDocument();
$fromXML->loadXML('<div>'.$html.'</div>');
$toXML = new \DomDocument();
self::searchEnd(
$fromXML->documentElement,
$toXML,
$toXML,
$length,
$elipsis,
$encoding
);
return $toXML->saveHTML();
}
/**
* Delete node child recursively
*
* @param mixed
*/
private static function deleteNodeChildren($node) {
while (isset($node->firstChild)) {
self::deleteNodeChildren($node->firstChild);
$node->removeChild($node->firstChild);
}
}
/**
* Search the HTML truncate point recursively
*
* @param DomElement $domElement
* @param mixed $domElementParent
* @param DomDocument $toXML
* @param integer $length
* @param string $elipsis
* @param integer &$charCount
* @param string $encoding
*
* @return boolean
*/
private static function searchEnd(\DomElement $domElement, $domElementParent, \DomDocument $toXML, $length, $elipsis, &$charCount = 0, $encoding = 'UTF-8') {
foreach ($domElement->childNodes as $child) {
if($child->nodeType != 3) {
$newElement = $toXML->importNode($child, true);
if (0 === count($child->childNodes)) {
$domElementParent->appendChild($newElement);
continue;
}
self::deleteNodeChildren($newElement);
$domElementParent->appendChild($newElement);
if (false === self::searchEnd($child, $newElement, $toXML, $length, $elipsis, $charCount)) {
continue;
}
return true;
}
if (mb_strlen($child->nodeValue, $encoding) + $charCount >= $length) {
$newElement = $toXML->importNode($child);
$newElement->nodeValue = substr($newElement->nodeValue, 0, $length - $charCount).$elipsis;
$domElementParent->appendChild($newElement);
return true;
}
$newElement = $toXML->importNode($child);
$domElementParent->appendChild($newElement);
$charCount += mb_strlen($newElement->nodeValue, $encoding);
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment