My custom get_the_excerpt() can't get excerpt by ID - php

On my single.php page I am trying to create a function to give me a custom length excerpt of a specific post by ID.
Below are my two functions I am running.
/* Custom get_the_excerpt to allow getting Post excerpt by ID */
function custom_get_the_excerpt($post_id) {
global $post;
$save_post = $post;
$post = get_post($post_id);
$output = get_the_excerpt($post);
$post = $save_post;
return $output;
}
/* Change Excerpt length */
function excerpt($num, $post_id = '') {
$limit = $num+1;
$excerpt = explode(' ', custom_get_the_excerpt($post_id), $limit);
array_pop($excerpt);
$excerpt = implode(" ",$excerpt)."&#8230";
echo $excerpt;
}
What I'm using to call the function.
<?php $previous = get_previous_post();
echo excerpt('30', $previous -> ID); ?>
The issue I am running into is $post is giving me the previous post information however when I pass that into get_the_excerpt it returns the current post excerpt rather than the previous post excerpt.
EDIT
Changed function to this after several people told me I can just pass the $post_id to get_the_excerpt()
/* Change Excerpt length */
function excerpt($num, $post_id = '') {
$limit = $num+1;
$excerpt = explode(' ', get_the_excerpt($post_id), $limit);
array_pop($excerpt);
$excerpt = implode(" ",$excerpt)."&#8230";
echo $excerpt;
}
Still no change.

Adding in setup_postdata($post); fixed my issue.
function custom_get_the_excerpt($post_id) {
global $post;
$save_post = $post;
$post = get_post($post_id);
setup_postdata($post);
$output = get_the_excerpt($post);
wp_reset_postdata();
$post = $save_post;
return $output;
}

the following function get two parmeters:
- $num : the number of character you would display
- $post_id: the ID of the post you want to get the content
and:
- if in the content there is the mark, return the text until it
- if $num is = 0 return the content until the first full stop
otherwise return a number of character specified on $num adding "..." at the end of the string
function my_custom_excerpt($num = 0,$post_id=''){
$post=get_post($post_id);
$content=$post->post_content;
if(strpos($content,'<!–more–>')>0){
return substr($content,0,strpos($content,'<!–more–>'));
}else{
if($num===0){
return substr($content,0,strpos($content,'.')+1);
}else{
return substr($content,0,$num).((strlen($content)>$num)?"...":"");
}
}
}

Related

End excerpts with a full sentence for specific post types

I am trying to make excerpts end with a sentence, for a specific post type on my website, but for some reason, it is also effecting page excerpts and I cannot understand why.
function vhr_variable_length_excerpt($text, $w_length, $finish_sentence){
global $post;
if ( $post->post_type == 'poi' ) {
//Word length of the excerpt. This is exact or NOT depending on your '$finish_sentence' variable.
$w_length = 20; /* Change the Length of the excerpt. The Length is in words. */
//1 if you want to finish the sentence of the excerpt (No weird cuts).
$finish_sentence = 1; // Put 0 if you do NOT want to finish the sentence.
$tokens = array();
$out = '';
$word = 0;
//Divide the string into tokens; HTML tags, or words, followed by any whitespace.
$regex = '/(<[^>]+>|[^<>\s]+)\s*/u';
preg_match_all($regex, $text, $tokens);
foreach ($tokens[0] as $t){
//Parse each token
if ($word >= $w_length && !$finish_sentence){
//Limit reached
break;
}
if ($t[0] != '<'){
//Token is not a tag.
//Regular expression that checks for the end of the sentence: '.', '?' or '!'
$regex1 = '/[\?\.\!]\s*$/uS';
if ($word >= $w_length && $finish_sentence && preg_match($regex1, $t) == 1){
//Limit reached, continue until ? . or ! occur to reach the end of the sentence.
$out .= trim($t);
break;
}
$word++;
}
//Append what's left of the token.
$out .= $t;
}
return trim(force_balance_tags($out));
}
}
function vhr_excerpt_filter($text){
global $post;
if ( $post->post_type == 'poi' ) {
//Get the full content and filter it.
$text = get_the_content('');
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
//If you want to Allow SOME tags:
$allowed_tags = '<p>,<a>,<strong>,<b>'; /* Here I am allowing p, a, strong tags. Separate tags by comma. */
$text = strip_tags($text, $allowed_tags);
//Create the excerpt.
$text = vhr_variable_length_excerpt($text, $w_length, $finish_sentence);
return $text;
}
}
//Hooks the 'vhr_excerpt_filter' function to a specific (get_the_excerpt) filter action.
add_filter('get_the_excerpt', 'vhr_excerpt_filter', 5);
It doesn't effect any of my other custom post types, just the one I specify in the function, and then all pages on the website. It still effects my pages, even if I change the logic to something like = poi && != page as well. Any ideas why this would also be effecting pages? Is there an easier way to make this happen?
Thanks!
There is a multitudes of ways we can approach it. Taking the time to write a custom excerpt instead on relying on Wordpress is one of them...
We can count sentences by targeting end-of-sentence period.
function get_sentence_tally_excerpt( $content = '', $tally = 2, $stitches = '' ) {
$buffer = array_slice( explode( '.', sanitize_text_field( $content ) ), 0, $tally );
$filter = array_filter( array_map( 'trim', $buffer ), 'strlen' );
$excerpt = join( '. ', $filter ) . '.';
return esc_attr( $excerpt . $stitches );
};
You can specify what type of content should be 'truncated' and by how many sentences. On the front-end we can call our function get_tally_excerpt() like so:
<?= get_sentence_tally_excerpt( get_the_content() ); ?> //... 2 sentences by DEFAULT
<?= get_sentence_tally_excerpt( get_the_content(), 1 ); ?> //... 1 sentences ONLY
<?= get_sentence_tally_excerpt( get_the_content(), 5, '[...]' ); ?> //... 5 sentences ONLY with stitches at the end.

How to properly call a function from a different file?

So I have this code here in my main file.
require_once(plugin_dir_path(__FILE__) . 'load_functions.php');
add_shortcode( 'ccss-show-recipes', 'ccss_show_tag_recipes' );
function ccss_show_tag_recipes() {
global $post;
global $wp;
$html = '';
$url = home_url( $wp->request );
$path = parse_url($url, PHP_URL_PATH);
$pathFragments = explode('/', $path);
$currentPage = end($pathFragments);
// $html.= '<p>'.$currentPage.'</p>';
if ($currentPage == 'recipes') {
ccss_load_all_recipes();
} elseif ( in_array( $currentPage ,["cleanse","combine","commence","commit","complete","consolidate"] ) ) {
//load_phases();
} elseif ( in_array( $currentPage ,["basic-marinades","basic-stock-recipes"] ) ) {
// load_recipe_type();
}
return $html;
// Restore original post data.
wp_reset_postdata();
}
and I have function here in load_functions.php
function ccss_load_all_recipes() {
//code here that wont return
$html .= '<p>test</p>'; //--> It wont display this
echo 'test'; //---> This will be displayed
}
The problem when I call ccss_load_all_recipes() it won't return anything, any ideas on what error I made? But when I try an echo statement it returns it
Thanks,
Carl
your function css_load_all_recipes() does not know the variable $html. In order to achieve that you should pass the $html variable into the function and return it again at the end.
// in your main file
$html = ccss_load_all_recipes($html);
// in load_functions.php
function ccss_load_all_recipes($html = '') {
$html .= '<p>test</p>';
return $html;
}
Edit: other possibilities are: declaring $html as a global variable, or passing $html as reference so you don't have to return the altered html back to the main file. But I would advise against both of these options, unless you run into the exact same problem many times within your application.

wordpress custom excerpt length not working

I have this code in my functions.php
function custom_excerpt_length() {
return 15;
}
add_filter('excerpt_length', 'custom_excerpt_length');
but it doesn't work as it gives me the full text and not the 15 words I specified. And the grid I have set up on my website is not right because of this.
my movie grid
Thanks in advance
Also use this code for multiple type of getting 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;
}
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;
}
then in your template code you just use..
<?php echo excerpt(25); ?>
Add third parameter and also you have not mention function parameter it will be worked
function custom_excerpt_length( $length ) {
return 15;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
I've faced this problem too, your code is right.
To solve this just go to Wordpress dashboard > posts > all posts then click edit in the post that has the problem, in the editor make sure that the excerpt is empty then click update.
Click here to see the image

Shortcodes function

Here the problem:
I have two div #post-playlist-list and post-playlist-description
I want to use two shortcodes [texte-article] and [playlist-article]
I need a function which get all the content between[texte-article][/texte-article] to put in #post-playlist-list
and another function which get the [playlist-article][/playlist-article] content into #post-playlist-description
I began to learn at preg_replace but the syntax is not that easy to learn.
I you can help me on this, it would be great.
Ok i tried the function i don't have error but it doesn't seems to return anything
Don't i need to escape the second ] ion the Regexp? like "/[texte-article](.*)[/texte-article]/"
Here's the code in my single.php :
<div id="post-playlist-list" class="box">
<?php
$id = get_the_ID();
$post = get_post($id);
$content = apply_filters('the_content', $post->post_content);
$content = str_replace( ']]>', ']]>', $content );
echo $content;
?>
</div>
<div id="post-playlist-description" >
<?php
echo $content;
?>
</div>
Here's the code in my single.php:
function texte_article_function() {
preg_replace_callback("/\[texte-article\](.*)\[\/texte-article\]/", function($matches) {
//$matches contains an array of all matches
//$matches[0] stores the full pattern match: \[texte-article](.*)\[\/texte-article]
//$matches[1] stores the first subpattern match: (.*)
//Do whatever text parsing you need to do here and return the result.
$content = $matches[0];
return $content;
}, $postdata);
}
function playlist_article_function() {
preg_replace_callback("/\[playlist-article\](.*)\[\/playlist-article\]/", function($matches) {
//$matches contains an array of all matches
//$matches[0] stores the full pattern match: \[texte-article](.*)\[\/texte-article]
//$matches[1] stores the first subpattern match: (.*)
//Do whatever text parsing you need to do here and return the result.
$content = $matches[0];
return $content;
}, $postdata);
}
function register_shortcodes(){
add_shortcode('texte-article', 'texte_article_function');
add_shortcode('playlist-article', 'playlist_article_function');
}
add_action( 'init', 'register_shortcodes');
Thanks for all the answers :) here's the solution, using regex:
functions.php
function texte_article_function($content_texte_article) {
//Get [texte-article] content
$content_texte_article = preg_replace('#.*\[texte-article\](.*)\[\/texte-article\].*#s', '$1', $content_texte_article);
return $content_texte_article;
}
function playlist_article_function($content_playlist_article) {
//get [fap_playlist] content
$content_playlist_article = preg_replace('#.*\[playlist-article\](.*)\[\/playlist-article\].*#s', '$1', $content_playlist_article);
return $content_playlist_article;
}
Callback functions:
<?php
$id = get_the_ID();
$post = get_post($id);
$content_playlist_article = $content;
$btn_play_index_id = $content;
echo playlist_article_function($content_playlist_article);
// echo $content;
?>
<?php
$content_texte_article = $content;
echo texte_article_function($content_texte_article);
?>
If it can help someone.

Multiple excerpt lengths in wordpress

As it says in the title, I'm looking for multiple excerpt lengths in WordPress.
I understand you can do this in functions.php:
function twentyten_excerpt_length( $length ) {
return 15;
}
add_filter( 'excerpt_length', 'twentyten_excerpt_length' );
What I want to know is how you can have multiple of these each returning different numerical values so I can get short excerpts for sidebar loops, longer excerpts for featured loops, and the longest excerpt for the main article.
Something like using these in the templates:
<?php the_excerpt('length-short') ?>
<?php the_excerpt('length-medium') ?>
<?php the_excerpt('length-long') ?>
Cheers,
Dave
How about...
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;
}
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;
}
then in your template code you just use..
<?php echo excerpt(25); ?>
from: http://bavotasan.com/tutorials/limiting-the-number-of-words-in-your-excerpt-or-content-in-wordpress/
As for now, you can upgrade Marty's reply:
function excerpt($limit) {
return wp_trim_words(get_the_excerpt(), $limit);
}
You can also define custom 'read more' link this way:
function custom_read_more() {
return '... <a class="read-more" href="'.get_permalink(get_the_ID()).'">more »</a>';
}
function excerpt($limit) {
return wp_trim_words(get_the_excerpt(), $limit, custom_read_more());
}
This is what I came up with.
Add this to your functions.php
class Excerpt {
// Default length (by WordPress)
public static $length = 55;
// So you can call: my_excerpt('short');
public static $types = array(
'short' => 25,
'regular' => 55,
'long' => 100
);
/**
* Sets the length for the excerpt,
* then it adds the WP filter
* And automatically calls the_excerpt();
*
* #param string $new_length
* #return void
* #author Baylor Rae'
*/
public static function length($new_length = 55) {
Excerpt::$length = $new_length;
add_filter('excerpt_length', 'Excerpt::new_length');
Excerpt::output();
}
// Tells WP the new length
public static function new_length() {
if( isset(Excerpt::$types[Excerpt::$length]) )
return Excerpt::$types[Excerpt::$length];
else
return Excerpt::$length;
}
// Echoes out the excerpt
public static function output() {
the_excerpt();
}
}
// An alias to the class
function my_excerpt($length = 55) {
Excerpt::length($length);
}
It can be used like this.
my_excerpt('short'); // calls the defined short excerpt length
my_excerpt(40); // 40 chars
This is the easiest way that I know of to add filters, that are callable from one function.
I was looking for this feature as well and most of the functions here are good and flexible.
For my own case I was looking for a solution that shows a different excerpt length only on specific pages. I'm using this:
function custom_excerpt_length( $length ) {
return (is_front_page()) ? 15 : 25;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
Paste this code inside the themes functions.php file.
You can add to your functions.php file this function
function custom_length_excerpt($word_count_limit) {
$content = wp_strip_all_tags(get_the_content() , true );
echo wp_trim_words($content, $word_count_limit);
}
Then call it in your template like this
<p><?php custom_length_excerpt(50); ?>
The wp_strip_all_tags should prevent stray html tags from breaking the page.
Documentation on functions
get_the_content
wp_trim_words
wp_strip_all_tags
Going back to Marty's reply:
I know it's been well over a year since this reply got published, but it's better late than never. For this to work with limits of over the WordPress default of 55, you need to replace this line:
$excerpt = explode(' ', get_the_excerpt(), $limit);
with this line:
$excerpt = explode(' ', get_the_content(), $limit);
Otherwise, the function only works with an already trimmed-down piece of text.
I think we can now use wp_trim_words see here.
Not sure what extra data escaping and sanitization needed to use this function, but it looks interesting.
Here an easy way to limit the content or the excerpt
$content = get_the_excerpt();
$content = strip_tags($content);
echo substr($content, 0, 255);
change get_the_excerpt() by get_the_content() if you want the contents.
Regards
I would do like this :
function _get_excerpt($limit = 100) {
return has_excerpt() ? get_the_excerpt() : wp_trim_words(strip_shortcodes(get_the_content()),$limit);
}
Usage :
echo _get_excerpt(30); // Inside the loop / query
Why ?
If has_excerpt should return given excerpt
It not, So trim words / strip shortcodes from the_content
I thing it is possible to create a short code , i did not try it but i wrote for you the main idea about its structure
function twentyten_excerpt_length($atts,$length=null){
shortcode_atts(array('exlength'=>'short'),$atts);
if(!isset($atts['exlength']) || $atts['exlength'] == 'short') {
return 15;
}elseif( $atts['exlength'] == 'medium' ){
return 30; // or any value you like
}elseif( $atts['exlength'] == 'long' ){
return 45; // or any value you like
}else{
// return nothing
}
}
add_shortcode('the_excerpt_sc','twentyten_excerpt_length');
so you can use it like so
[the_excerpt_sc exlength="medium"]
I know this is a really old thread, but I just struggled with this problem and none of the solutions I found online worked properly for me. For one thing my own "excerpt_more"-filter was always cut off.
The way I solved it is ugly as hell, but it's the only working solution I could find. The ugliness involves modifying 4 lines of WP core(!!) + the use of yet another global variable (although WP already does this so much I don't feel too bad).
I changed wp_trim_excerpt in wp-includes/formatting.php to this:
<?php
function wp_trim_excerpt($text = '') {
global $excerpt_length;
$len = $excerpt_length > 0 ? $excerpt_length : 55;
$raw_excerpt = $text;
if ( '' == $text ) {
$text = get_the_content('');
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$excerpt_length = apply_filters('excerpt_length', $len);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[…]');
$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
}
$excerpt_length = null;
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
The only new stuff is the $excerpt_length and $len bits.
Now if I want to change the default length I do this in my template:
<?php $excerpt_length = 10; the_excerpt() ?>
Changing core is a horrible solution so I'd love to know if someone comes up with something better.
Be careful using some of these methods. Not all of them strip the html tags out, meaning if someone inserts a link to a video (or url) in the first sentence of their post, the video (or link) will show up in the excerpt, possibly blowing up your page.
I wrote an article about using custom excerpt length in WordPress.
There area a number of ways to limit & control post excerpt length.
Limit post excerpt length or post content length using number of words.
Limiting excerpt length to a number of characters.
Limit post summary by adding ‘read more’ tag.
Enabling custom excerpt to write your own summary for each post.
Control Excerpt Length using Filters
I hope this will help you a lot.

Categories