multiple excerpt length in wordpress - wordpress

I'm using the following function for an excerpt in Wordpress.
<?php
// Excerpt - end of sentence
function custom_wp_trim_excerpt($text) {
$raw_excerpt = $text;
if ('' == $text) {
// Retrieve the post content.
$text = get_the_content('');
// Delete all shortcode tags from the content.
$text = strip_shortcodes($text);
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$allowed_tags = '<i>,<strong>';
$text = strip_tags($text, $allowed_tags);
$excerpt_word_count = 40;
$excerpt_length = apply_filters('excerpt_length', $excerpt_word_count);
$excerpt_end = '...' . '<div class="read-more"><a class="button" href="' . get_permalink($post->ID) . '">' . 'Read More' . '</a></div>';
$excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end);
$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);
}
}
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'custom_wp_trim_excerpt');
I want to add a second word count to use on the blog page. The above word count is being used on the front page. Advice, please? Thanks.

Try this piece of code
function custom_wp_trim_excerpt($text) {
if ( is_front_page() || is_home() ) {
// Excerpt for front page or home page
} else {
// Excerpt for rest of the site
}
}
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'custom_wp_trim_excerpt');
By using this piece of code you have more control over the excerpt that is outputted on different pages.
If that worked mark your question as solved.

Related

Functions.php to set all external links with rel:="nofollow"

when i use the code:
add_filter('the_content', 'my_nofollow');
add_filter('the_excerpt', 'my_nofollow');
function my_nofollow($content) {
return preg_replace_callback('/<a[^>]+/', 'my_nofollow_callback', $content);
}
function my_nofollow_callback($matches) {
$link = $matches[0];
$site_link = get_bloginfo('url');
if (strpos($link, 'rel') === false) {
$link = preg_replace("%(href=\S(?!$site_link))%i", 'rel="nofollow" $1', $link);
} elseif (preg_match("%href=\S(?!$site_link)%i", $link)) {
$link = preg_replace('/rel=\S(?!nofollow)\S*/i', 'rel="nofollow"', $link);
}
return $link;
}
only in the_content and the_excerpt the links get a nofollow attribute. How i can edit the code, that the whole wordpress site use this functions (footer, sidebar...)
Thank you
a good script which allows to add nofollow automatically and to keep the other attributes
function nofollow(string $html, string $baseUrl = null) {
return preg_replace_callback(
'#<a([^>]*)>(.+)</a>#isU', function ($mach) use ($baseUrl) {
list ($a, $attr, $text) = $mach;
if (preg_match('#href=["\']([^"\']*)["\']#', $attr, $url)) {
$url = $url[1];
if (is_null($baseUrl) || !str_starts_with($url, $baseUrl)) {
if (preg_match('#rel=["\']([^"\']*)["\']#', $attr, $rel)) {
$relAttr = $rel[0];
$rel = $rel[1];
}
$rel = 'rel="' . ($rel ? (strpos($rel, 'nofollow') ? $rel : $rel . ' nofollow') : 'nofollow') . '"';
$attr = isset($relAttr) ? str_replace($relAttr, $rel, $attr) : $attr . ' ' . $rel;
$a = '<a ' . $attr . '>' . $text . '</a>';
}
}
return $a;
},
$html
);
}
The idea is to add your action in the full html buffer, once everything is loaded and filtered, not only in the 'content' area.
BE VERRY CAREFULL WITH THIS !!!! This action is verry RAW and low-level... You can really mess up everything with theses buffer actions. But it's also very nice to know ;-)
It works like this :
add_action( 'wp_loaded', 'buffer_start' ); function buffer_start() { ob_start( "textdomain_nofollow" ); }
add_action( 'shutdown', 'buffer_end' ); function buffer_end() { ob_end_flush(); }
Then do the replace action and setup the callback :
Juste imagine the $buffer variable as your full site in HTML, as it will load.
function textdomain_nofollow( $buffer ) {
return preg_replace_callback( '/<a[^>]+/', 'textdomain_nofollow_callback', $buffer );
}
Here is how I do the href checking (read my comments) :
function textdomain_nofollow_callback( $matches ) {
$link = $matches[0];
// if you need some specific external domains to exclude, just use :
//$exclude = '('. home_url() .'|(http|https)://([^.]+\.)?(domain-to-exclude.org|other-domain-to-exclude.com)|/)';
// By default, just exclude your own domain, and your relative urls that starts by a '/' (if you use relatives urls)
$exclude = '('. home_url() .'|/)';
if ( preg_match( '#href=\S('. $exclude .')#i', $link ) )
return $link;
if ( strpos( $link, 'rel=' ) === false ) {
$link = preg_replace( '/(?<=<a\s)/', 'rel="nofollow" ', $link );
} elseif ( preg_match( '#rel=\S(?!nofollow)#i', $link ) ) {
$link = preg_replace( '#(?<=rel=.)#', 'nofollow ', $link );
}
return $link;
}
It works well in my experience...
Q

Display the Last Updated Date of a Posts in WordPress

I want to display the last update date of a post in WordPress, i can find this code and i must put it in function.php
function wpb_last_updated_date( $content ) {
$u_time = get_the_time('U');
$u_modified_time = get_the_modified_time('U');
if ($u_modified_time >= $u_time + 86400) {
$updated_date = get_the_modified_time('F jS, Y');
$updated_time = get_the_modified_time('h:i a');
$custom_content .= '<p class="last-updated">Last updated on '. $updated_date . ' at '. $updated_time .'</p>';
}
$custom_content .= $content;
return $custom_content;
}
add_filter( 'the_content', 'wpb_last_updated_date' );
It's working but the problem that i also have update date displayed on pages, portfolios, ....
How can i limit the display of updated date just on post for the blog ?
Thanks for helping.
Just add a condition to check the post type:
function wpb_last_updated_date( $content ) {
$u_time = get_the_time('U');
$u_modified_time = get_the_modified_time('U');
if ($u_modified_time >= $u_time + 86400 && is_singular('post')) {
$updated_date = get_the_modified_time('F jS, Y');
$updated_time = get_the_modified_time('h:i a');
$custom_content .= '<p class="last-updated">Last updated on '. $updated_date . ' at '. $updated_time .'</p>';
}
$custom_content .= $content;
return $custom_content;
}
add_filter( 'the_content', 'wpb_last_updated_date' );
is_singular() queries for a single post and takes the post type as an argument.

Place ads before last paragraph in wordpress

Here is the code for place ads after 1st, 2nd, 3d paragraph. but i want to place ad just before last paragraph of my wordpress post. is there any way to do this ?
<?php
add_filter( 'the_content', 'prefix_insert_post_ads' );
function prefix_insert_post_ads( $content ) {
$ad_code = '<div>Ads code goes here</div>';
if ( is_single() && ! is_admin() ) {
return prefix_insert_after_paragraph( $ad_code, 1, $content );
}
return $content;
}
// Parent Function that makes the magic happen
function prefix_insert_after_paragraph( $insertion, $paragraph_id, $content ) {
$closing_p = '</p>';
$paragraphs = explode( $closing_p, $content );
foreach ($paragraphs as $index => $paragraph) {
if ( trim( $paragraph ) ) {
$paragraphs[$index] .= $closing_p;
}
if ( $paragraph_id == $index + 1 ) {
$paragraphs[$index] .= $insertion;
}
}
return implode( '', $paragraphs );
}
?>
add_filter('the_content', 'ad_signal');
function ad_signal($content)
{
if (!is_single()) return $content;
$tent = get_the_content();
$content = explode("</p>", $content);
$ss = count($content);
$ns = $ss-1; //**before last paragraph in wordpress **
$new_content = '';
for ($i = 0; $i < count($content); $i++) {
if ($i == $ns ) {
$new_content.= ' <div style="text-align:center;">';
$new_content.= '<h1> Your ads Here ! </h1>';
$new_content.= '</div>';
}
$new_content.= $content[$i] . "</p>";
}
return $new_content;
}
I have set Adsense code by this Code in my sites named All BD Results and etunescafe. You just add this code in your sites functions.php N.B. Before adding the code please replace your or add your adsense code. It will be good enough to go through this post. How to Set Adsense Ads Right Before The Last Paragraph
function ads_added_above_last_p($text) {
if( is_single() ) :
$ads_text = '<div class="a" style="text-align: center;">Your Adsense Code</div>';
if($pos1 = strrpos($text, '<p>')){
$text1 = substr($text, 0, $pos1);
$text2 = substr($text, $pos1);
$text = $text1 . $ads_text . $text2;
}
endif;
return $text;
}
add_filter('the_content', 'ads_added_above_last_p');
Hey guys so I ran into the same problem and managed to solve it incorporating your answers into one.
The function that does all the processing is changed so that is counts all the paragraphs created by the explode method. Then another if statement is added to evaluate when you are at the desired location.
function prefix_insert_after_paragraph( $insertion, $paragraph_id, $content ) {
$closing_p = '</p>';
$paragraphs = explode( $closing_p, $content );
$last_paragraph_index = count($paragraphs);
foreach ($paragraphs as $index => $paragraph) {
if ( trim( $paragraph ) ) {
$paragraphs[$index] .= $closing_p;
}
if ( $paragraph_id == $index + 1 ) {
$paragraphs[$index] .= $insertion;
}
else if( $last_paragraph_index + $paragraph_id == $index + 1){
$paragraphs[$index] .= $insertion;
}
}
return implode( '', $paragraphs );
}
in order to use the new functionality you must call it with a negative number.
Think of the function this way, if you want to go from the top of the content you use a positive number, if you want to go from the bottom of the content you use a negative number.
Remember that even though the evaluation is for your decided spot such as before the last paragraph the condition that adds to the array uses the index which we all know is zero based.
This just means that to get after paragraph 1 you must use the number 2 when calling the function and to get to before the last paragraph you have to use -2 and so on.
Here is my example to add the a read the next post if it exists to the article
add_filter( 'the_content', 'prefix_insert_next_article_banner' );
function prefix_insert_next_article_banner( $content ) {
if ( is_single() && ! is_admin() && get_next_post_link() ) {
$next_banner = '<div class="next-banner"> <span> Read Next </span>';
$next_banner .= ' ' . get_the_title(get_adjacent_post(false,'',false)) .' ';
$next_banner .= '</div>';
return prefix_insert_after_paragraph( $next_banner, -2, $content );
}
return $content;
}

Wordpress excerpt by second paragraph

How to limit the excerpt length by paragraph, not word/char count? For example, excerpt shows only first two paragraphs, no matter how long the paragraphs are.
Thanks in advance.
Here is a function that keeps HTML tags in tact, adds a "Read More" link at the end of the excerpt and trims the excerpt after the first paragraph.
if ( ! function_exists( 'wpse0001_custom_wp_trim_excerpt' ) ) :
function wpse0001_custom_wp_trim_excerpt($wpse0001_excerpt) {
global $post;
$raw_excerpt = $wpse0001_excerpt;
if ( '' == $wpse0001_excerpt ) {
$wpse0001_excerpt = get_the_content('');
$wpse0001_excerpt = strip_shortcodes( $wpse0001_excerpt );
$wpse0001_excerpt = apply_filters('the_content', $wpse0001_excerpt);
// Here we choose how many paragraphs do we want to cutthe excerpt at, This part thanks to Clément Malet
$wpse0001_excerpt = "<p>$wpse0001_excerpt</p>";
$wanted_number_of_paragraph = 2;
$tmp = explode ('</p>', $wpse0001_excerpt);
for ($i = 0; $i < $wanted_number_of_paragraph; ++$i) {
if (isset($tmp[$i]) && $tmp[$i] != '') {
$tmp_to_add[$i] = $tmp[$i];
}
}
$wpse0001_excerpt = implode('</p>', $tmp_to_add) . '</p>';
$wpse0001_excerpt = str_replace(']]>', ']]>', $wpse0001_excerpt);
$excerpt_end = ' ' . ' » ' . sprintf(__( 'Read more about: %s »', 'pietergoosen' ), get_the_title()) . '';
$excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end);
//$pos = strrpos($wpse0001_excerpt, '</');
//if ($pos !== false)
// Inside last HTML tag
//$wpse0001_excerpt = substr_replace($wpse0001_excerpt, $excerpt_end, $pos, 0);
//else
// After the content
$wpse0001_excerpt .= $excerpt_end;
return $wpse0001_excerpt;
}
return apply_filters('wpse0001_custom_wp_trim_excerpt', $wpse0001_excerpt, $raw_excerpt);
}
endif;
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'wpse0001_custom_wp_trim_excerpt');
EDIT
Thanks to the help from #ClementMalet, I was able to tweak my function to make you choose the amount of paragraphs where you want to cut the excerpt. Please check his great answer here

Preg_split screws up the BR tag?

I am struggling with this one for half a day now and i can't seem to get it right. I have a custom function in my wordpress site, that automatically creates an excerpt. This all goes well, but for some (i guess logical) reason it also cuts off the <br /> tag, since it has a space.
How to fix this? This has to do with the preg_split function right?
Below is my code:
function custom_wp_trim_excerpt($text) {
$raw_excerpt = $text;
if ( '' == $text ) {
//Retrieve the post content.
$text = get_the_content('');
//Delete all shortcode tags from the content.
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$allowed_tags = '<p>,<br>,<br/>,<br />,<a>,<em>,<strong>,<img>'; /*** MODIFY THIS. Add the allowed HTML tags separated by a comma.***/
$text = strip_tags($text, $allowed_tags);
$excerpt_word_count = 40; /*** MODIFY THIS. change the excerpt word count to any integer you like.***/
$excerpt_length = apply_filters('excerpt_length', $excerpt_word_count);
$excerpt_end = ' ' . '...' . '';
$excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end);
$words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
if ( count($words) > $excerpt_length && $words ) {
array_pop($words);
$text = implode(' ', $words);
$text = $text . $excerpt_more;
} else {
$text = implode(' ', $words);
}
}
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'custom_wp_trim_excerpt');
Thanks!
You can add this to make all of the HTML break characters the same:
$text = preg_replace('!<br ?/>!i','<br>',$text);
Before these lines:
$allowed_tags = '<p>,<br>,<a>,<em>,<strong>,<img>'; /*** MODIFY THIS. Add the allowed HTML tags separated by a comma.***/
$text = strip_tags($text, $allowed_tags);
When you're doing preg_split("/[\n\r\t ]+/",$text) you're splitting the space in the break <br /> character.
You can also simplify the regex in the preg_split() statement:
$words = preg_split("!\s+!", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
Since you're allowing the other tags they probably contain spaces too though.

Resources