How do you display only the first paragraph of an advanced custom field.
<?php the_field('lyrics'); ?>
Above is what i use to display the full text.
add_filter( 'wp_trim_excerpt', 'my_custom_excerpt', 10, 2 );
function my_custom_excerpt($text, $raw_excerpt) {
if( ! $raw_excerpt ) {
$content = apply_filters( 'the_content', get_the_content() );
$text = substr( $content, 0, strpos( $content, '</p>' ) + 4 );
}
return $text;
}
try this code will help you to show first 55 character of your first paragraph.
Grab the first paragraph of each post
second option:
function custom_field_excerpt() {
global $post;
$text = get_field('news');
if ( '' != $text ) {
$start = strpos($text, '<p>'); // Locate the first paragraph tag
$end = strpos($text, '</p>', $start); // Locate the first paragraph closing tag
$text = substr($text, $start, $end-$start+4); // Trim off everything after the closing paragraph tag
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
}
return $text;}
third option :
You can use this function:
function get_first_paragraph(){
global $post;
$str = wpautop( get_the_content() );
$str = substr( $str, 0, strpos( $str, '</p>' ) + 4 );
$str = strip_tags($str, '<a><strong><em>');
return '<p>' . $str . '</p>';}
and then use in it in your loop with:
<?php echo get_first_paragraph(); ?>
Related
I have a problem with getting the first form the_excerpt();
Function acutally works but only for first post. I added in functions.php
function get_first_paragraph(){
global $post;
$str = wpautop( get_the_content() );
$str = substr( $str, 0, strpos( $str, '</p>' ) + 4 );
$str = strip_tags($str, '<a><strong><em>');
return '<p>' . $str . '</p>';
}
I'm calling this funcion in index.php inside The Loop <?php echo get_first_paragraph(); ?>
I have no idea why it pulls only for first post...
you can put this code in function.php file in your theme,
Get first paragraph
function awesome_excerpt($text, $raw_excerpt) {
if( ! $raw_excerpt ) {
$content = apply_filters( 'the_content', get_the_content() );
$text = substr( $content, 0, strpos( $content, '</p>' ) + 4 );
}
return $text;
}
add_filter( 'wp_trim_excerpt', 'awesome_excerpt', 10, 2 );
For more information, you can follow the reference link WORDPRESS THE_EXCERPT SHOW ONLY FIRST PARAGRAPH
That code didn't work for me in Gutenberg times. So I've used part of that code and did some searching and come up with this solution. Hope it helps.
function get_paragraph_content($paragraph_number){
global $post;
$i = 0;
$paragraph = '';
if ( has_blocks( $post->post_content ) ) {
$blocks = parse_blocks( $post->post_content );
foreach( $blocks as $block ) {
if( 'core/paragraph' === $block['blockName']){
$paragraph = render_block($block);
if (++$i == $paragraph_number) break;
}
}
$paragraph = substr( $paragraph, 0, strpos( $paragraph, '</p>' ) + 4 );
$paragraph = strip_tags($paragraph, '<a><strong><em>');
}
return $paragraph;
}
I have created two categories within a WordPress site with one post in each category. I am pulling in and excerpt from each category post on different pages.
I am showing the post excerpt like so on each page and adding a read more link manually.
<?php query_posts('cat=4&showposts=1'); ?>
<?php while (have_posts()) : the_post(); ?>
<h3><?php the_title(); ?></h3>
<?php the_excerpt(); ?>
Read More
<?php endwhile; ?>
The following code will then end the excerpt after the first paragraph.
function post_single_paragrapgh($text, $raw_excerpt) {
if( ! $raw_excerpt ) {
$content = apply_filters( 'the_content', get_the_content() );
$text = substr( $content, 0, strpos( $content, '</p>' ) + 4 );
}
return $text;
}
add_filter( 'wp_trim_excerpt', 'post_single_paragrapgh', 10, 2 );
What I would like to do is tell it to cut off after a second paragraph or, in fact an image and a paragraph.
It will pull in an image if there is one at the top of post but then I also want a further paragraph after the image or just two paragraphs of text. Either or.
I used this site for reference but method C1 throws up errors.
https://www.bybe.net/wordpress-the_excerpt-show-first-paragraph/
Thanks in advance!
Are you open to a solution with regex? Look for <p>(Anything)</p> and merge the two first occurrence. The code is not tested but should work.
function post_single_paragrapgh($text, $raw_excerpt) {
if( ! $raw_excerpt ) {
$content = apply_filters( 'the_content', get_the_content() );
preg_match_all( '~<p>(.*?)</p>~', $content, $matches );
if( isset( $matches[0][0] ) && isset( $matches[0][1] ) ) {
$text = $matches[0][0] . $matches[0][1];
} else {
$text = $matches[0][0];
}
}
return $text;
}
I managed to figure out what I needed with this code, posted the question too hastily I guess.
function awesome_excerpt($awesomeness_excerpt) {
global $post;
$raw_excerpt = $awesomeness_excerpt;
if ( '' == $awesomeness_excerpt ) {
$awesomeness_excerpt = get_the_content('');
$awesomeness_excerpt = strip_shortcodes( $awesomeness_excerpt );
$awesomeness_excerpt = apply_filters('the_content', $awesomeness_excerpt);
$awesomeness_excerpt = "<p>$awesomeness_excerpt</p>";
$wanted_number_of_paragraph = 2;
$tmp = explode ('</p>', $awesomeness_excerpt);
for ($i = 0; $i < $wanted_number_of_paragraph; ++$i) {
if (isset($tmp[$i]) && $tmp[$i] != '') {
$tmp_to_add[$i] = $tmp[$i];
}
}
$awesomeness_excerpt .= $excerpt_end;
return $awesomeness_excerpt;
}
return apply_filters('awesome_excerpt', $awesomeness_excerpt, $raw_excerpt);
}
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'awesome_excerpt');
Just took out the end if at the bottom - must have been left there in error. Hopefully it can help others.
Im trying to modify the wp_trim_words function to return the left over words as well as the first part, any help much appreciated.
function wp_trim_words_new( $text, $num_words = 55, $more = null ) {
if ( null === $more )
$more = __( '…' );
$original_text = $text;
$text = wp_strip_all_tags( $text );
/* translators: If your word count is based on single characters (East Asian characters),
enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
if ( 'characters' == _x( 'words', 'word count: words or characters?' ) && 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 );
}
/**
* Filter the text content after words have been trimmed.
*
* #since 3.3.0
*
* #param string $text The trimmed text.
* #param int $num_words The number of words to trim the text to. Default 5.
* #param string $more An optional string to append to the end of the trimmed text, e.g. ….
* #param string $original_text The text before it was trimmed.
*/
return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text );
}
It seems to me that you simply copied the trim_words() function of Wordpress. You could have done better. Your desired output is unclear.
Supposing that you would be happy with the simple tag-less string of left-over words returned together with the output of the original function, you could use something like this (untested):
function wp_trim_words_2( $text, $num_words = 55, $more = null ) {
if ( null === $more )
$more = __( '…' );
$original_text = $text;
$text = wp_strip_all_tags( $text );
/* translators: If your word count is based on single characters (East Asian characters),
enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
if ( 'characters' == _x( 'words', 'word count: words or characters?' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
$text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
preg_match_all( '/\X/u', $text, $match_array );
$split_array = $match_array[0];
$sep = '';
} else {
$split_array = preg_split( "/[\n\r\t ]+/", $text, -1, PREG_SPLIT_NO_EMPTY );
$sep = ' ';
}
$words_array = array_slice( $split_array, 0, $num_words + 1 );
if ( count( $words_array ) > $num_words ) {
array_pop( $words_array );
$text = implode( $sep, $words_array );
$text = $text . $more;
$rest = implode( $sep, array_slice( $split_array, $num_words ) );
} else {
$text = implode( $sep, $words_array );
$rest = '';
}
/**
* Filter the text content after words have been trimmed.
*
* #since 3.3.0
*
* #param string $text The trimmed text.
* #param int $num_words The number of words to trim the text to. Default 5.
* #param string $more An optional string to append to the end of the trimmed text, e.g. ….
* #param string $original_text The text before it was trimmed.
*/
return array( apply_filters( 'wp_trim_words_2', $text, $num_words, $more, $original_text ), $rest );
}
to be called like this:
list($trimmed, $rest) = wp_trim_words_2($text);
I'm not sure about apply_filters(), though. Should it be passed the $rest too? It's too time-consuming for me to study this one, sorry.
If, on the other hand, you wanted the $rest before tag removal (i.e., before the call to wp_strip_all_tags()), then things are much more complicated, because the original functions splits the input into words after that, and I can think only of inefficient ways to keep the correspondence between the input and the output of wp_strip_all_tags().
BTW, the original code by WordPress contains a bug: words for East Asian languages are wrongly counted (and potentially split!) as single Unicode characters instead of Unicode graphemes. The fix is to use '/\X/u' instead of '/./u' (read here for an explanation).
Not sure you need to tweak that function at all, this code does what you ask:
$trimmed_text = wp_trim_words($text, $wordlength, '');
// Measure full and trimmed widths for comparison
$fw = mb_strwidth($text);
$tw = mb_strwidth($trimmed_text);
if( $fw != $tw ){
$clipped_text = mb_strimwidth($text, $tw, $fw - $tw, '');
// Text has been cut
} else {
// Text has NOT been cut
}
or wrap it in a function behaving as you wanted initially
function wp_trim_words_new($text, $length, $delimiter=''){
$trimmed_text = wp_trim_words($text, $length, $delimiter);
$fw = mb_strwidth($text);
$tw = mb_strwidth($trimmed_text);
if( $fw != $tw ){
return [$trimmed_text, mb_strimwidth($text, $tw, $fw - $tw, $delimiter)];
} else {
return [$text, null];
}
}
You can accomplish this without the wp_trim_words function.
$sentence = "This is a sample sentence";
$words = explode(" ", $sentence);
$half = count($words) / 2;
$first_half = implode(" ", array_slice($words, 0, $half));
$second_half = implode(" ", array_slice($words, $half));
echo $first_half . "\n";
echo $second_half;
I am using <?php echo wp_trim_words(get_the_content(), 100); ?> in my template file to control amount of words to be displayed on a page and also have a link below it for taking user to the next page to read entire content but this function removes all the formatting of content on preview page.
I can't use wordpress default excerpt function here as it is being used elsewhere and i need this to be of different length than that. Is there a way to retain formatting while using this ?
Thanks
I found a solution to this may be it can help others as well.
function content_excerpt($excerpt_length = 5, $id = false, $echo = true) {
$text = '';
if($id) {
$the_post = & get_post( $my_id = $id );
$text = ($the_post->post_excerpt) ? $the_post->post_excerpt : $the_post->post_content;
} else {
global $post;
$text = ($post->post_excerpt) ? $post->post_excerpt : get_the_content('');
}
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
if ( count($words) > $excerpt_length ) {
array_pop($words);
$text = implode(' ', $words);
$text = $text . $excerpt_more;
} else {
$text = implode(' ', $words);
}
if($echo)
echo apply_filters('the_content', $text);
else
return $text;
}
function get_content_excerpt($excerpt_length = 5, $id = false, $echo = false) {
return content_excerpt($excerpt_length, $id, $echo);
}
// Call function in template file via
<?php content_excerpt(50); // 50 is amount to words ?>
To anyone else facing similar issues, I took the default wp_trim_words() function directly out of core, and altered it to not strip tags:
function wp_trim_words_retain_formatting( $text, $num_words = 55, $more = null ) {
if ( null === $more )
$more = __( '…' );
$original_text = $text;
/* translators: If your word count is based on single characters (East Asian characters),
enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
if ( 'characters' == _x( 'words', 'word count: words or characters?' ) && 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 );
}
/**
* Filter the text content after words have been trimmed.
*
* #since 3.3.0
*
* #param string $text The trimmed text.
* #param int $num_words The number of words to trim the text to. Default 5.
* #param string $more An optional string to append to the end of the trimmed text, e.g. ….
* #param string $original_text The text before it was trimmed.
*/
return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text );
}
Try:
echo apply_filters( 'the_content', wp_trim_words( get_the_content(), 100 ) );
I've changed my excerpt link in wordpress from "[...]" to "Read More" with the code below. I want to know if there is a way to use more than one link for the excerpt. Let's say for posts in one category have "Read More" for their excerpt, and then posts in another category have "See Photos" for their excerpt link. is this possible?
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'custom_trim_excerpt');
function custom_trim_excerpt($text) { // Fakes an excerpt if needed
global $post;
if ( '' == $text ) {
$text = get_the_content('');
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$text = strip_tags($text);
$excerpt_length = 24;
$words = explode(' ', $text, $excerpt_length + 1);
if (count($words) > $excerpt_length) {
array_pop($words);
array_push($words, '...<br />Read More');
$text = implode(' ', $words);
}
}
return $text;
}
yes you can do it. use excerpt_more filter to change the "[...]" and in_category function to check the category for read more text.
try this code.
function custom_excerpt_more( $more ) {
$read_more_txt = 'Read More..';
if (in_category('cat_slug'))
$read_more_txt = 'See Photos..';
else if (in_category('cat_slug2'))
$read_more_txt = 'Something else..';
return ' <a title="'. $read_more_txt .'" href="'. get_permalink( get_the_ID() ) .'">'. $read_more_txt .'</a>';
}
add_filter( 'excerpt_more', 'custom_excerpt_more' );