Skip to content

Commit ee1c9eb

Browse files
Enhance wp_trim_excerpt: Add support for allowed HTML tags and character-based trimming
1 parent e2d6d2b commit ee1c9eb

1 file changed

Lines changed: 98 additions & 1 deletion

File tree

src/wp-includes/formatting.php

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4017,7 +4017,104 @@ function wp_trim_excerpt( $text = '', $post = null ) {
40174017
* @param string $more_string The string shown within the more link.
40184018
*/
40194019
$excerpt_more = apply_filters( 'excerpt_more', ' ' . '[…]' );
4020-
$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
4020+
4021+
/**
4022+
* Filters the HTML tags allowed in an auto-generated post excerpt.
4023+
*
4024+
* @since 7.0.0
4025+
*
4026+
* @param string $allowed_tags Allowed HTML tags. Default empty string (strip all tags).
4027+
*/
4028+
$excerpt_allowed_tags = apply_filters( 'excerpt_allowed_tags', '' );
4029+
4030+
if ( '' !== $excerpt_allowed_tags ) {
4031+
$text_to_trim = strip_tags( $text, $excerpt_allowed_tags );
4032+
4033+
$plain_text = wp_strip_all_tags( $text_to_trim );
4034+
4035+
if ( str_starts_with( wp_get_word_count_type(), 'characters' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
4036+
$plain_text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $plain_text ), ' ' );
4037+
preg_match_all( '/./u', $plain_text, $chars );
4038+
$needs_trim = count( $chars[0] ) > $excerpt_length;
4039+
4040+
if ( $needs_trim ) {
4041+
$char_count = 0;
4042+
$cut_pos = strlen( $text_to_trim );
4043+
$remaining = $text_to_trim;
4044+
$offset = 0;
4045+
4046+
while ( '' !== $remaining ) {
4047+
if ( '<' === $remaining[0] ) {
4048+
$tag_end = strpos( $remaining, '>' );
4049+
if ( false === $tag_end ) {
4050+
break;
4051+
}
4052+
$offset += $tag_end + 1;
4053+
$remaining = substr( $remaining, $tag_end + 1 );
4054+
continue;
4055+
}
4056+
4057+
if ( preg_match( '/^./us', $remaining, $m ) ) {
4058+
++$char_count;
4059+
if ( $char_count > $excerpt_length ) {
4060+
$cut_pos = $offset;
4061+
break;
4062+
}
4063+
$offset += strlen( $m[0] );
4064+
$remaining = substr( $remaining, strlen( $m[0] ) );
4065+
} else {
4066+
break;
4067+
}
4068+
}
4069+
4070+
$text = force_balance_tags( substr( $text_to_trim, 0, $cut_pos ) ) . $excerpt_more;
4071+
} else {
4072+
$text = $text_to_trim;
4073+
}
4074+
} else {
4075+
$words = preg_split( "/[\n\r\t ]+/", $plain_text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY );
4076+
4077+
if ( count( $words ) > $excerpt_length ) {
4078+
$word_count = 0;
4079+
$cut_pos = strlen( $text_to_trim );
4080+
$remaining = $text_to_trim;
4081+
$offset = 0;
4082+
4083+
while ( '' !== $remaining ) {
4084+
if ( '<' === $remaining[0] ) {
4085+
$tag_end = strpos( $remaining, '>' );
4086+
if ( false === $tag_end ) {
4087+
break;
4088+
}
4089+
$offset += $tag_end + 1;
4090+
$remaining = substr( $remaining, $tag_end + 1 );
4091+
continue;
4092+
}
4093+
4094+
if ( preg_match( '/^(\S+)/', $remaining, $m ) ) {
4095+
++$word_count;
4096+
if ( $word_count > $excerpt_length ) {
4097+
$cut_pos = $offset;
4098+
break;
4099+
}
4100+
$offset += strlen( $m[0] );
4101+
$remaining = substr( $remaining, strlen( $m[0] ) );
4102+
} elseif ( preg_match( '/^(\s+)/', $remaining, $m ) ) {
4103+
$offset += strlen( $m[0] );
4104+
$remaining = substr( $remaining, strlen( $m[0] ) );
4105+
} else {
4106+
break;
4107+
}
4108+
}
4109+
4110+
$text = force_balance_tags( substr( $text_to_trim, 0, $cut_pos ) ) . $excerpt_more;
4111+
} else {
4112+
$text = $text_to_trim;
4113+
}
4114+
}
4115+
} else {
4116+
$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
4117+
}
40214118

40224119
}
40234120

0 commit comments

Comments
 (0)