Show excerpt on front page using the_content(); and ACF - php

I need to show a excerpt on my home page. I have standard post and a custom post type 'webinar'. The CPT 'webinar' has a custom field, using ACF 'webinar_description' that is a an equivalent of 'description' in normal posts.
I am able to display both, by adding a filter for the 'webinar_description' like this:
add_filter('the_content','add_my_custom_field');
function add_my_custom_field($data) {
$data .= get_field('webinar_description');
return $data;
}
Now I have both post types displaying, but it displays the entire 'description' or 'webinar_description' field. I need to trim it at 40 words and add a '... Read More' with 'Read More' being a link to the article.
I have tried this, but it only works on the normal 'post' type field 'description' it doesn't work on my 'webinar' custom post type -> custom field 'webinar-description'
<?php $content = get_the_content(); echo mb_strimwidth($content, 0, 400, '[Read more]');?>
How can I create a filter or function that will limit both to 400 (or whatever) characters and add the link?

Not sure if this will help anyone in a similar situation, but this is how I solved it. First, in functions.php make the custom post type available
function cpt_get_excerpt(){
$excerpt = get_field('webinar_description');
$excerpt = preg_replace(" (\[.*?\])",'',$excerpt);
$excerpt = strip_shortcodes($excerpt);
$excerpt = strip_tags($excerpt);
$excerpt = substr($excerpt, 0, 400);
$excerpt = substr($excerpt, 0, strripos($excerpt, " "));
$excerpt = trim(preg_replace( '/\s+/', ' ', $excerpt));
$excerpt = $excerpt.'... <a class="c-drkGold" href="'.get_permalink($post->ID).'">Read More</a>';
return $excerpt;
}
Then where you want to display it, use a if/else statement based on the post type and display accordingly (this example is from static front page).
<?php
if( get_post_type() == 'post' ) {
?><p class="l-nmb"><?php
$content = get_the_content(); echo mb_strimwidth($content, 0, 400, '... Read more'); ?> </p>
<?php } else {
?><p class="l-nmb"><?php
$content = cpt_get_excerpt(); echo mb_strimwidth($content, 0, 400, '... Read more'); ?> </p>
<?php } ?>

Related

Hide after X characters in php?

I have a Wordpress site, and I want to set up a paywall for certain content.
I would like to show some intro of each such article for Google index and users as well, but rest of it would be hidden for guests and available for logged in (in my case paid users).
I successfully implemented is_user_logged_in() PHP statement from Wordpress, but I am not finding PHP code anywhere online about hiding everything after n-characters, or words.
My intended workflow is:
<?php
if ( is_user_logged_in() ) {
the_content();
} else {
echo 'show only 200 characters or words of the content code should be here';
}
?>
You can use WordPress default function wp_trim_words.
<?php
if ( is_user_logged_in() ) {
the_content();
} else {
$content = get_the_content(); // $content is whatever your content field.
echo wp_trim_words( $content, 200, ' ' );
}
?>
<?php
if ( is_user_logged_in() ) {
the_content();
} else {
$content = get_the_content();
//If your template has some other way of getting the post content then use that variable.
echo substr($content, 0, strpos($content, ' ', 200));
}
?>

Shortened excerpt function only working properly on posts that have excerpt

I am using the following to shorten the excerpt if it exceeds a certain amount of characters, whilst also not cutting the last word.
ob_start();
the_excerpt();
$excerpt = ob_get_clean();
if (strlen($excerpt) < 200) {
echo $excerpt;
} else {
$new = wordwrap($excerpt, 200);
$new = explode("\n", $new);
$new = $new[0] . '...';
echo $new;
}
The problem is that this only works if an excerpt is set, if not the excerpt only displays the first line or first sentence - see photo. I understand that the_excerpt pulls the_content if no excerpt is present, but do not understand why the wordwrap doesnt work properly when content is used instead of the excerpt?
Can you run this experiment:
ob_start();
the_excerpt();
$excerpt = ob_get_clean();
if (strlen($excerpt) < 200) {
echo $excerpt;
} else {
$i = strpos($excerpt, ' ');
$new = wordwrap($excerpt, 200);
$new = explode("\n", $new);
$j = count($new);
$new = $new[0] . '...';
echo "<div style=\"border:3px solid red;\">first space at $i<br>count is $j</div>";
echo $new;
}
I think your code is correct. It seems the only way it can fail is wordwrap() cannot find any spaces or wordwrap() doesn't insert "\n" - neither of which seems reasonable but something isn't right. After reading Alberto Marin's comment I think the problem is your code is either not running or being completely replaced by an enclosing output buffer. In this case the red div will not appear.
So I ended up using a slightly different way to shorten the excerpt and that worked. The other code was definitely working and only in the above example was it showing 7 words, the character count basically only worked until there was a line break and then it would cut the rest of the content off.
I have additionally added a "filter" to get rid of line html tags, so that there are no line breaks in the excerpt, since the clean output buffering removes the wpautop filter.
<?php ob_start();
the_excerpt();
$excerpt = ob_get_clean();
$excerpt = preg_replace('/<.*?>/', '', $excerpt);;
?>
<?php
if ( strlen( $excerpt ) > 320 ) {
$cut = substr( $excerpt, 0, 320 );
$excerpt = substr( $cut, 0, strrpos( $cut, ' ' ) ) . '...';
echo $excerpt;
} else {
echo $excerpt;
}

Wordpress Outputting Excerpt as link not working correctly?

I need to output a custom 'read more' button for every post.
I use the following function that I've made:
function the_excerpt_more_link( $excerpt ){
$post = get_post();
$url = 'https:/www.vierenzestig.nl/';
$postslug = $post->post_name;
$link = $url . $postslug;
$excerpt = 'Lees meer!';
return $link;
}
This is working as expected and it outputs the following :
https:/www.vierenzestig.nl/interior-car-wash-and-detailing-service
When I try to wrap the above output inside an element. It also displays the home url from the website. Using this code (see the replacement of $link with $excerpt):
function the_excerpt_more_link( $excerpt ){
$post = get_post();
$url = 'https:/www.vierenzestig.nl/';
$postslug = $post->post_name;
$link = $url . $postslug;
$excerpt = 'Lees meer!';
return $excerpt;
}
This outputs the following :
An link with the text: 'Lees Meer'. But the link is navigating to the following :
https://HOMEURLHERE/https:/www.vierenzestig.nl/interior-car-wash-and-detailing-service
Why is the same use of code resulting in a different output of code?

Replacing <?php the_content(); ?> in content-single.php with output from custom content code in functions.php

I have a slight issue. I have managed, with the help of someone one stackoverflow to write a code to add dynamic content to all my wordpress posts. The code is now in my functions.php file and is as follows.
function add_after_post_content($content) {
global $post;
if(!is_feed() && !is_home() && is_singular() && is_main_query()) {
$post_categories = wp_get_post_categories( $post->ID );
$cats = array();
foreach($post_categories as $c){
$cat = get_category( $c );
$cats[] = array( 'name' => $cat->name, 'slug' => $cat->slug );
}
$content .= '<strong>'. $post->post_title . '</strong> is a <strong>wallpaper</strong> posted in the ';
foreach($cats as $c){
$content .= $c['name'];
}
$content .= ' category by <strong>Free Wallpapers</strong> on '. $post->post_date . '. <br /><br />';
}
return $content;
}
add_filter('the_content', 'add_after_post_content');
The issue is that some of my older posts already have content in them and hence both the old content as well as the new are displayed beneath them. whereas I would like this to be the new content/description for all posts. Currently in my content-single.php I believe this is the line which calls the original post content plus the code I have mentioned above.
<?php the_content(); ?>
I would like to wither remove or modify my content-single.php/code added to functions.php file so that only the new code displays the dynamic description, and the original post content is not displayed. i.e. putting it simply if the entire new code could be labeled content2 and the content-single.php code will output this content2 only. I have tried simply moving the code from functions.php to replace
<?php the_content(); ?>
in the content-single.php but this gives me all kinds of errors.
Any help on this issue would be greatly appreciated.
Best Regards
Remove the dot after $content.
$content .= '<strong>'. $post->post_title . '</strong> is a <strong>wallpaper</strong> posted in the ';
Replace above line with following
$content = '<strong>'. $post->post_title . '</strong> is a <strong>wallpaper</strong> posted in the ';

How to set character limit on the_content() and the_excerpt() in wordpress

How do I set a character limit on the_content() and the_excerpt() in wordpress? I have only found solutions for the word limit - I want to be able to set an exact amount characters of outputted.
Or even easier and without the need to create a filter: use PHP's mb_strimwidth to truncate a string to a certain width (length). Just make sure you use one of the get_ syntaxes.
For example with the content:
<?php $content = get_the_content(); echo mb_strimwidth($content, 0, 400, '...');?>
Update 2022
mb_strimwidth breaks the HTML if the comment tag is used. use official wordpress wp_trim_words functions
<?php $content = get_the_content(); echo wp_trim_words( get_the_content(), 400, '...' );?>
This will cut the string at 400 characters and close it with ....
Just add a "read more"-link to the end by pointing to the permalink with get_permalink().
Read more
Of course you could also build the read more in the first line. Than just replace '...' with '[Read more]'
You could use a Wordpress filter callback function. In your theme's directory, locate or create a file called functions.php and add the following in:
<?php
add_filter("the_content", "plugin_myContentFilter");
function plugin_myContentFilter($content)
{
// Take the existing content and return a subset of it
return substr($content, 0, 300);
}
?>
The plugin_myContentFilter() is a function you provide that will be called each time you request the content of a post type like posts/pages via the_content(). It provides you with the content as an input, and will use whatever you return from the function for subsequent output or other filter functions.
You can also use add_filter() for other functions like the_excerpt() to provide a callback function whenever the excerpt is requested.
See the Wordpress filter reference docs for more details.
wp_trim_words This function trims text to a certain number of words and returns the trimmed text.
Example:-
echo wp_trim_words( get_the_content(), 40, '...' );
This also balances HTML tags so that they won't be left open and doesn't break words.
add_filter("the_content", "break_text");
function break_text($text){
$length = 500;
if(strlen($text)<$length+10) return $text;//don't cut if too short
$break_pos = strpos($text, ' ', $length);//find next space after desired length
$visible = substr($text, 0, $break_pos);
return balanceTags($visible) . " […]";
}
For Using the_content() functions (for displaying the main content of the page)
$content = get_the_content();
echo substr($content, 0, 100);
For Using the_excerpt() functions (for displaying the excerpt-short content of the page)
$excerpt= get_the_excerpt();
echo substr($excerpt, 0, 100);
Replace <?php the_content();?> by the code below
<?php
$char_limit = 100; //character limit
$content = $post->post_content; //contents saved in a variable
echo substr(strip_tags($content), 0, $char_limit);
?>
php substr() function refrence
php strip_tags() function refrence
wp_trim_words() This function trims text to a certain number of words and returns the trimmed text.
$excerpt = wp_trim_words( get_the_content(), 40, 'More Link');
Get truncated string with specified width using mb_strimwidth() php function.
$excerpt = mb_strimwidth( strip_tags(get_the_content()), 0, 100, '...' );
Using add_filter() method of WordPress on the_content filter hook.
add_filter( "the_content", "limit_content_chr" );
function limit_content_chr( $content ){
if ( 'post' == get_post_type() ) {
return mb_strimwidth( strip_tags($content), 0, 100, '...' );
} else {
return $content;
}
}
Using custom php function to limit content characters.
function limit_content_chr( $content, $limit=100 ) {
return mb_strimwidth( strip_tags($content), 0, $limit, '...' );
}
// using above function in template tags
echo limit_content_chr( get_the_content(), 50 );
just to help, if any one want to limit post length at home page .. then can use below code to do that..
the below code is simply a modification of #bfred.it Sir
add_filter("the_content", "break_text");
function limit_text($text){
if(is_front_page())
{
$length = 250;
if(strlen($text)<$length+10) return $text; //don't cut if too short
$break_pos = strpos($text, ' ', $length); //find next space after desired length
$visible = substr($text, 0, $break_pos);
return balanceTags($visible) . "... <a href='".get_permalink()."'>read more</a>";
}else{
return $text;
}
}
<?php
echo apply_filters( 'woocommerce_short_description', substr($post->post_excerpt, 0, 500) )
?>
I know this post is a bit old, but thought I would add the functions I use that take into account any filters and any <![CDATA[some stuff]]> content you want to safely exclude.
Simply add to your functions.php file and use anywhere you would like, such as:
content(53);
or
excerpt(27);
Enjoy!
//limit excerpt
function excerpt($limit) {
$excerpt = explode(' ', get_the_excerpt(), $limit);
if (count($excerpt)>=$limit) {
array_pop($excerpt);
$excerpt = implode(" ",$excerpt).'...';
} else {
$excerpt = implode(" ",$excerpt);
}
$excerpt = preg_replace('`\[[^\]]*\]`','',$excerpt);
return $excerpt;
}
//limit content
function content($limit) {
$content = explode(' ', get_the_content(), $limit);
if (count($content)>=$limit) {
array_pop($content);
$content = implode(" ",$content).'...';
} else {
$content = implode(" ",$content);
}
$content = preg_replace('/\[.+\]/','', $content);
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
return $content;
}

Categories