I have an ACF-field, that gives an output like this:
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p><img class="alignnone size-large wp-image-48" src=".jpg" alt="" width="1024" height="640" /></p>
<p>Sed lacinia enim a <strong>est aliquet</strong>, et accumsan ex pellentesque. </p>
<p>Adipiscing elit, lorem ipsum dolor sit amet, consectetur.</p>
... Both images and text.
With wp_html_excerpt I can remove all tags, so I get one long text-blurp.
But with WordPress' native excerpts, then it doesn't remove line-breaks or bold text, which I find nice.
How would I go about achieving, getting an excerpt like that, from my ACF-wysiwyg-field?
So ideally, I would call my function like this: create_neat_excerpt( $html, 15 );
and get an output like this (from above-given input):
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Sed lacinia enim a <strong>est aliquet</strong>, et accumsan...</p>
$project_desc = get_field( 'project_description' );
if( !empty( $project_desc ) ):
$trimmed_text = wp_html_excerpt( $project_desc, 800 );
$last_space = strrpos( $trimmed_text, ' ' );
$modified_trimmed_text = substr( $trimmed_text, 0, $last_space );
echo $modified_trimmed_text . '...';
endif;
I have an ACF-field, that gives an output like this:
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p><img class="alignnone size-large wp-image-48" src="http://example/wp-content/uploads/2019/01/foo-bar.jpg" alt="" width="1024" height="640" /></p>
<p>Sed lacinia enim a <strong>est aliquet</strong>, et accumsan ex pellentesque. </p>
<p>Adipiscing elit, lorem ipsum dolor sit amet, consectetur.</p>
... Both images and text.
With wp_html_excerpt I can remove all tags, so I get one long text-blurp.
But with WordPress' native excerpts, then it doesn't remove line-breaks or bold text, which I find nice.
How would I go about achieving, getting an excerpt like that, from my ACF-wysiwyg-field?
So ideally, I would call my function like this: create_neat_excerpt( $html, 15 );
and get an output like this (from above-given input):
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Sed lacinia enim a <strong>est aliquet</strong>, et accumsan...</p>
$project_desc = get_field( 'project_description' );
if( !empty( $project_desc ) ):
$trimmed_text = wp_html_excerpt( $project_desc, 800 );
$last_space = strrpos( $trimmed_text, ' ' );
$modified_trimmed_text = substr( $trimmed_text, 0, $last_space );
echo $modified_trimmed_text . '...';
endif;
You can provide your own implementation of wp_trim_excerpt
which is responsible for trimming and stripping HTML tags (it uses wp_strip_all_tags
),
By copying the function source code and applying the change that you want (which is keeping the <p>
and <strong>
tags (or any additional tags as you wish) and it will work nicely.
I copied the function for you and applied the change of allowing <p>
and <strong>
to be on your final excerpt. (You should put this code in your functions.php
file)
function wp_trim_excerpt_modified($text, $content_length = 55, $remove_breaks = false) {
if ( '' != $text ) {
$text = strip_shortcodes( $text );
$text = excerpt_remove_blocks( $text );
$text = apply_filters( 'the_content', $text );
$text = str_replace(']]>', ']]>', $text);
$num_words = $content_length;
$more = $excerpt_more ? $excerpt_more : null;
if ( null === $more ) {
$more = __( '…' );
}
$original_text = $text;
$text = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $text );
// Here is our modification
// Allow <p> and <strong>
$text = strip_tags($text, '<p>,<strong>');
if ( $remove_breaks )
$text = preg_replace('/[\r\n\t ]+/', ' ', $text);
$text = trim( $text );
if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
$text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
preg_match_all( '/./u', $text, $words_array );
$words_array = array_slice( $words_array[0], 0, $num_words + 1 );
$sep = '';
} else {
$words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
$sep = ' ';
}
if ( count( $words_array ) > $num_words ) {
array_pop( $words_array );
$text = implode( $sep, $words_array );
$text = $text . $more;
} else {
$text = implode( $sep, $words_array );
}
}
return $text;
}
Notice the line that is doing the stripping:
Line:22 $text = strip_tags($text, '<p>,<strong>');
And your code should be like this:
$project_desc = get_field( 'project_description' );
if( !empty( $project_desc ) ):
$trimmed_text = wp_trim_excerpt_modified( $project_desc, 15 );
$last_space = strrpos( $trimmed_text, ' ' );
$modified_trimmed_text = substr( $trimmed_text, 0, $last_space );
echo $modified_trimmed_text . '...';
endif;
For more information, you can checkout this answer on stackoverflow it is more detailed.
using apply_filters( 'the_excerpt', get_field( 'project_description' ) );
is close, but it's missing a vital step in getting you where you want. the core excerpt builder runs another filter before it hits the_excerpt
. it's get_the_excerpt
and on that filter is a call to wp_trim_excerpt()
which runs wp_trim_words()
. if you look at that function you will see it runs wp_strip_all_tags()
before trimming content to 55 words. This is the part you are missing to get your content to look like a regular excerpt without any images. I haven't tested the below but it should work without too much modification needed.
$raw_content = get_field( 'project_description' );
$trimmed_content = wp_trim_words($raw_content);
$clean_excerpt = apply_filters('the_excerpt', $trimmed_content);
echo $clean_excerpt;
Clean that up however you like, I spread it all out for readability.
EDIT: wp_trim_excerpt()
only runs all the fun filters if it's pulling from post content. replaced with wp_trim_words()
Use the_excerpt
filter (see Codex)
apply_filters( 'the_excerpt', get_field( 'my-wysiwyg-field' ) );
<strong>
-tags. – Zeth Commented Jan 15, 2019 at 13:55the_excerpt()
you provided, it actually says "An auto-generated excerpt will also have all shortcodes and tags removed." – Ibrahim Mohamed Commented Jan 17, 2019 at 5:54