ThemeShaper Forums » Thematic

[closed]

Set the excerpt length by sentence

(10 posts)
  • Started 3 years ago by helgatheviking
  • Latest reply from Chris
  • This topic is not resolved
  1. Is it possible to make the excerpt sentence aware w/o a plugin? I've seen the snippets for setting length based on words, but was wondering if it wouldn't be too hard to extrapolate out to sentences... which seems more logical to me.

    Posted 3 years ago #
  2. Hi,

    why don't you integrate Fancy Excerpt into your theme?

    :)

    Chris

    Posted 3 years ago #
  3. Hi Chris,

    I've toyed w/ just about every excerpt plugin there is. Fancy Excerpt is definitely the closest- b/c of the sentence-awareness - but I don't want it escaping images and other things that end up looking goofy w/ thumbnails, and there is no way to toggle that on/off like in Advanced Excerpts. If they could get together and have a child called Advanced Fancy Excerpt that would be brilliant.

    Posted 3 years ago #
  4. Mmmh .. would the Fancy Excerpts without the 'escaping' part be ok for you? Would add a few filters to control 'escaping' and 'number of sentences'. This could be integrated in your child theme.

    Chris

    Posted 3 years ago #
  5. That would be exactly what I am after.

    Posted 3 years ago #
  6. Check if this is working for you (needs to be copied into your child theme's functions.php):

    class fancy_excerpt {
    	/**
    	 * trim_excerpt()
    	 *
    	 * @param string $text
    	 * @return string $text
    	 **/
    
    	function trim_excerpt($text) {
    
    		$max_words = 30;
    		$max_words = apply_filters('fancy_excerpt_words', $max_words);
    
    		$text = trim($text);
    
    		if ( $text || !in_the_loop() )
    			return wp_trim_excerpt($text);
    
    		$more = sprintf(__('Read more on %s...', 'fancy-excerpt'), get_the_title());
    
    		$more = apply_filters('fancy_excerpt_more', $more);
    
    		$text = get_the_content($more);
    		$text = str_replace(array("\r\n", "\r"), "\n", $text);
    		#dump(esc_html($text));
    
    		if ( !preg_match("|" . preg_quote($more, '|') . "</a>$|", $text)
    			&& count(preg_split("~\s+~", trim(strip_tags($text)))) > $max_words
    		) {
    			global $escape_fancy_excerpt;
    			$escape_fancy_excerpt = array();
    
    			if (apply_filters('fancy_excerpt_escape', true)) {
    
    				$text = fancy_excerpt::escape($text);
    
    			}
    
    			$bits = preg_split("/(<(?:h[1-6]|p|ul|ol|li|dl|dd|table|tr|pre|blockquote)\b[^>]*>|\n{2,})/i", $text, null, PREG_SPLIT_DELIM_CAPTURE);
    			$text = '';
    			$length = 0;
    
    			foreach ( $bits as $bit ) {
    				$text .= $bit;
    				$bit_count = trim(strip_tags($bit));
    				if ( $bit_count === '' )
    					continue;
    				$count += count(preg_split("~\s+~", $bit_count));
    
    				if ( $count > $max_words )
    					break;
    			}
    
    			$text = fancy_excerpt::unescape($text);
    
    			$text = force_balance_tags($text);
    
    			$text .= "\n\n"
    				. '<p>'
    				. apply_filters('the_content_more_link',
    					'<a href="'. esc_url(apply_filters('the_permalink', get_permalink())) . '" class="more-link">'
    					. $more
    					. '</a>')
    				. '</p>' . "\n";
    		}
    
    		$text = apply_filters('the_content', $text);
    
    		return apply_filters('wp_trim_excerpt', $text, '');
    	} # trim_excerpt()
    
    	/**
    	 * escape()
    	 *
    	 * @param string $text
    	 * @return string $text
    	 **/
    
    	function escape($text) {
    		global $escape_fancy_excerpt;
    
    		if ( !isset($escape_fancy_excerpt) )
    			$escape_fancy_excerpt = array();
    
    		foreach ( array(
    			'blocks' => "/
    				<\s*(script|style|object|textarea)(?:\s.*?)?>
    				.*?
    				<\s*\/\s*\\1\s*>
    				/isx",
    			) as $regex ) {
    			$text = preg_replace_callback($regex, array('fancy_excerpt', 'escape_callback'), $text);
    		}
    
    		return $text;
    	} # escape()
    
    	/**
    	 * escape_callback()
    	 *
    	 * @param array $match
    	 * @return string $text
    	 **/
    
    	function escape_callback($match) {
    		global $escape_fancy_excerpt;
    
    		$tag_id = "----escape_fancy_excerpt:" . md5($match[0]) . "----";
    		$escape_fancy_excerpt[$tag_id] = $match[0];
    
    		return $tag_id;
    	} # escape_callback()
    
    	/**
    	 * unescape()
    	 *
    	 * @param string $text
    	 * @return string $text
    	 **/
    
    	function unescape($text) {
    		global $escape_fancy_excerpt;
    
    		if ( !$escape_fancy_excerpt )
    			return $text;
    
    		$unescape = array_reverse($escape_fancy_excerpt);
    
    		return str_replace(array_keys($unescape), array_values($unescape), $text);
    	} # unescape()
    } # fancy_excerpt
    
    remove_filter('get_the_excerpt', 'wp_trim_excerpt');
    add_filter('get_the_excerpt', array('fancy_excerpt', 'trim_excerpt'), 0);
    function my_words() {
    	return 20;
    }
    add_filter('fancy_excerpt_words', 'my_words');
    function no_escape() {
    	return false;
    }
    add_filter('fancy_excerpt_escape', 'no_escape');

    Chris

    Posted 3 years ago #
  7. Hi Chris,

    Thank you for your effort! What you have written seems to exactly replicate the FancyExcerpt plugin.. and the images are still included in the excerpt instead of being escaped. Am I supposed to have the fancyexcerpt plugin enabled? I tried that and it produced a fatal error.

    Posted 3 years ago #
  8. Sorry, my fault :)

    So .. the excerpt should have the look and feel of the standard excerpt, no markup, no images and so on? And it should have the 'sentence' functionality?

    Posted 3 years ago #
  9. No worries. I really appreciate your help. Yes, that is what I am going for. Very similar to the standard excerpt except that it doesn't cut off in the middle of a sentence with ... I guess the easiest answer is to always write custom excerpts and that is probably a good practice anyway.

    Posted 3 years ago #
  10. Let me see, what I can do with Thematic itself.

    As long as you don't use any fancy things like lists, quotes, or similar at the beginning of your post, we can handle this with some additional code. Otherwise you are right with using a manual excerpt.

    Chris

    Posted 3 years ago #

RSS feed for this topic

Topic Closed

This topic has been closed to new replies.