bp_create_excerpt

Truncate text.

Description

(string) bp_create_excerpt( (string) $text, (int) $length = 225, (array) $options = array() ); 

Cuts a string to the length of $length and replaces the last characters with the ending if the text is longer than length.

This function is borrowed from CakePHP v2.0, under the MIT license. See http://book.cakephp.org/view/1469/Text#truncate-1625

Returns (string)

Trimmed string.

Parameters (3)

0. $text (string)
String to truncate.
1. $length — Optional. (int) => 225
Length of returned string, including ellipsis. Default: 225.
2. $options — Optional. (array) => array()
An array of HTML attributes and options. Each item is optional.

Options

  • ending (string) => ''

    The string used after truncation. Default: […]..

  • exact (bool) => null

    If true, $text will be trimmed to exactly $length. If false, $text will not be cut mid-word. Default: false.

  • html (bool) => null

    If true, don't include HTML tags when calculating excerpt length. Default: true.

  • filter_shortcodes (bool) => null

    If true, shortcodes will be stripped. Default: true.

  • strip_tags (bool) => null

    If true, HTML tags will be stripped. Default: false. Only applicable if $html is set to false.

array(

    /**
     * The string used after truncation. Default: ' […]'.
     *
     * @type string
     * @default ''
     */
    'ending' => '',

    /**
     * If true, $text will be trimmed to exactly $length. If false, $text will not be cut mid-word.
     * Default: false.
     *
     * @type bool
     * @default null
     */
    'exact' => null,

    /**
     * If true, don't include HTML tags when calculating excerpt length. Default: true.
     *
     * @type bool
     * @default null
     */
    'html' => null,

    /**
     * If true, shortcodes will be stripped. Default: true.
     *
     * @type bool
     * @default null
     */
    'filter_shortcodes' => null,

    /**
     * If true, HTML tags will be stripped. Default: false. Only applicable if $html is set to false.
     *
     * @type bool
     * @default null
     */
    'strip_tags' => null
);        


Usage

  1. if ( !function_exists( 'bp_create_excerpt' ) ) { 
  2. require_once ABSPATH . PLUGINDIR . 'buddypress/bp-core/bp-core-template.php'; 
  3.  
  4. // String to truncate. 
  5. $text = ''; 
  6.  
  7. // Optional. Length of returned string, including ellipsis. 
  8. // Default: 225. 
  9. $length = 225; 
  10.  
  11. // An array of HTML attributes and options. Each item is optional. 
  12. $options = array( 
  13. 'ending' => '', 
  14. 'exact' => null, 
  15. 'html' => null, 
  16. 'filter_shortcodes' => null, 
  17. 'strip_tags' => null 
  18. ); 
  19.  
  20. // NOTICE! Understand what this does before running. 
  21. $result = bp_create_excerpt($text, $length, $options); 
  22.  

Defined (1)

The function is defined in the following location(s).

/bp-core/bp-core-template.php  
  1. function bp_create_excerpt( $text, $length = 225, $options = array() ) { 
  2.  
  3. // Backward compatibility. The third argument used to be a boolean $filter_shortcodes. 
  4. $filter_shortcodes_default = is_bool( $options ) ? $options : true; 
  5.  
  6. $r = bp_parse_args( $options, array( 
  7. 'ending' => __( ' […]', buddypress ),  
  8. 'exact' => false,  
  9. 'html' => true,  
  10. 'filter_shortcodes' => $filter_shortcodes_default,  
  11. 'strip_tags' => false,  
  12. 'remove_links' => false,  
  13. ), 'create_excerpt' ); 
  14.  
  15. // Save the original text, to be passed along to the filter. 
  16. $original_text = $text; 
  17.  
  18. /** 
  19. * Filters the excerpt length to trim text to. 
  20. * @since 1.5.0 
  21. * @param int $length Length of returned string, including ellipsis. 
  22. */ 
  23. $length = apply_filters( 'bp_excerpt_length', $length ); 
  24.  
  25. /** 
  26. * Filters the excerpt appended text value. 
  27. * @since 1.5.0 
  28. * @param string $value Text to append to the end of the excerpt. 
  29. */ 
  30. $ending = apply_filters( 'bp_excerpt_append_text', $r['ending'] ); 
  31.  
  32. // Remove shortcodes if necessary. 
  33. if ( ! empty( $r['filter_shortcodes'] ) ) { 
  34. $text = strip_shortcodes( $text ); 
  35.  
  36. // When $html is true, the excerpt should be created without including HTML tags in the 
  37. // excerpt length. 
  38. if ( ! empty( $r['html'] ) ) { 
  39.  
  40. // The text is short enough. No need to truncate. 
  41. if ( mb_strlen( preg_replace( '/<.*?>/', '', $text ) ) <= $length ) { 
  42. return $text; 
  43.  
  44. $totalLength = mb_strlen( strip_tags( $ending ) ); 
  45. $openTags = array(); 
  46. $truncate = ''; 
  47.  
  48. // Find all the tags and HTML comments and put them in a stack for later use. 
  49. preg_match_all( '/(<\/?([\w+!]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER ); 
  50.  
  51. foreach ( $tags as $tag ) { 
  52. // Process tags that need to be closed. 
  53. if ( !preg_match( '/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2] ) ) { 
  54. if ( preg_match( '/<[\w]+[^>]*>/s', $tag[0] ) ) { 
  55. array_unshift( $openTags, $tag[2] ); 
  56. } elseif ( preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag ) ) { 
  57. $pos = array_search( $closeTag[1], $openTags ); 
  58. if ( $pos !== false ) { 
  59. array_splice( $openTags, $pos, 1 ); 
  60.  
  61. $truncate .= $tag[1]; 
  62. $contentLength = mb_strlen( preg_replace( '/&[0-9a-z]{2, 8};|&#[0-9]{1, 7};|&#x[0-9a-f]{1, 6};/i', ' ', $tag[3] ) ); 
  63.  
  64. if ( $contentLength + $totalLength > $length ) { 
  65. $left = $length - $totalLength; 
  66. $entitiesLength = 0; 
  67. if ( preg_match_all( '/&[0-9a-z]{2, 8};|&#[0-9]{1, 7};|&#x[0-9a-f]{1, 6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE ) ) { 
  68. foreach ( $entities[0] as $entity ) { 
  69. if ( $entity[1] + 1 - $entitiesLength <= $left ) { 
  70. $left--; 
  71. $entitiesLength += mb_strlen( $entity[0] ); 
  72. } else { 
  73. break; 
  74.  
  75. $truncate .= mb_substr( $tag[3], 0 , $left + $entitiesLength ); 
  76. break; 
  77. } else { 
  78. $truncate .= $tag[3]; 
  79. $totalLength += $contentLength; 
  80. if ( $totalLength >= $length ) { 
  81. break; 
  82. } else { 
  83. // Strip HTML tags if necessary. 
  84. if ( ! empty( $r['strip_tags'] ) ) { 
  85. $text = strip_tags( $text ); 
  86.  
  87. // Remove links if necessary. 
  88. if ( ! empty( $r['remove_links'] ) ) { 
  89. $text = preg_replace( '#^\s*(https?://[^\s"]+)\s*$#im', '', $text ); 
  90.  
  91. if ( mb_strlen( $text ) <= $length ) { 
  92. /** 
  93. * Filters the final generated excerpt. 
  94. * @since 1.1.0 
  95. * @param string $truncate Generated excerpt. 
  96. * @param string $original_text Original text provided. 
  97. * @param int $length Length of returned string, including ellipsis. 
  98. * @param array $options Array of HTML attributes and options. 
  99. */ 
  100. return apply_filters( 'bp_create_excerpt', $text, $original_text, $length, $options ); 
  101. } else { 
  102. $truncate = mb_substr( $text, 0, $length - mb_strlen( $ending ) ); 
  103.  
  104. // If $exact is false, we can't break on words. 
  105. if ( empty( $r['exact'] ) ) { 
  106. // Find the position of the last space character not part of a tag. 
  107. preg_match_all( '/<[a-z\!\/][^>]*>/', $truncate, $_truncate_tags, PREG_OFFSET_CAPTURE ); 
  108.  
  109. // Rekey tags by the string index of their last character. 
  110. $truncate_tags = array(); 
  111. if ( ! empty( $_truncate_tags[0] ) ) { 
  112. foreach ( $_truncate_tags[0] as $_tt ) { 
  113. $_tt['start'] = $_tt[1]; 
  114. $_tt['end'] = $_tt[1] + strlen( $_tt[0] ); 
  115. $truncate_tags[ $_tt['end'] ] = $_tt; 
  116.  
  117. $truncate_length = mb_strlen( $truncate ); 
  118. $spacepos = $truncate_length + 1; 
  119. for ( $pos = $truncate_length - 1; $pos >= 0; $pos-- ) { 
  120. // Word boundaries are spaces and the close of HTML tags, when the tag is preceded by a space. 
  121. $is_word_boundary = ' ' === $truncate[ $pos ]; 
  122. if ( ! $is_word_boundary && isset( $truncate_tags[ $pos - 1 ] ) ) { 
  123. $preceding_tag = $truncate_tags[ $pos - 1 ]; 
  124. if ( ' ' === $truncate[ $preceding_tag['start'] - 1 ] ) { 
  125. $is_word_boundary = true; 
  126. break; 
  127.  
  128. if ( ! $is_word_boundary ) { 
  129. continue; 
  130.  
  131. // If there are no tags in the string, the first space found is the right one. 
  132. if ( empty( $truncate_tags ) ) { 
  133. $spacepos = $pos; 
  134. break; 
  135.  
  136. // Look at each tag to see if the space is inside of it. 
  137. $intag = false; 
  138. foreach ( $truncate_tags as $tt ) { 
  139. if ( $pos > $tt['start'] && $pos < $tt['end'] ) { 
  140. $intag = true; 
  141. break; 
  142.  
  143. if ( ! $intag ) { 
  144. $spacepos = $pos; 
  145. break; 
  146.  
  147. if ( $r['html'] ) { 
  148. $bits = mb_substr( $truncate, $spacepos ); 
  149. preg_match_all( '/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER ); 
  150. if ( !empty( $droppedTags ) ) { 
  151. foreach ( $droppedTags as $closingTag ) { 
  152. if ( !in_array( $closingTag[1], $openTags ) ) { 
  153. array_unshift( $openTags, $closingTag[1] ); 
  154.  
  155. $truncate = rtrim( mb_substr( $truncate, 0, $spacepos ) ); 
  156. $truncate .= $ending; 
  157.  
  158. if ( !empty( $r['html'] ) ) { 
  159. foreach ( $openTags as $tag ) { 
  160. $truncate .= '</' . $tag . '>'; 
  161.  
  162. /** This filter is documented in /bp-core/bp-core-template.php */ 
  163. return apply_filters( 'bp_create_excerpt', $truncate, $original_text, $length, $options );