uɐʎɹ ррoʇ uɐʎɹ bio photo

uɐʎɹ ррoʇ uɐʎɹ

Hello. Is is me you're looking for?
僕は猿ーロボット。
robotic life signs.
makes noise, hears sounds, intafon.
affe auf deux roues.

Email Twitter Github Github Gist Last.fm Soundcloud Flickr

I recently started getting back into looking around at WordPress coding, as I finally upgraded after quite a while and noted the new available features (including tagging, which I know has been there for quite a while now), which got me started thinking about designing the site a little. In doing so, I was again wanting to do some more interesting stuff with the entry “excerpts” that you can use on index pages. In my search I came across a nice simple plugin called Advanced Excerpt.

The problem with the out of the box excerpt in WordPress mainly is that it is fairly restrictive. Without digging in to the code, you can’t change the number of words displayed, and I believe by default it still strips any extra html markup (i.e. bye-bye flickr thumbnails). However, Advanced Excerpt allows you to easily designate how many words to use, allows you to use html markup (and choose accepted tags), and allows you to specify a custom ellipses for the end of the blurb (which is I think by default […], can’t recall now). Go download Advanced Excerpt.

However, Advanced Excerpt is still missing something that I really wanted. You still can’t click the […] at the end of the article to “read more.” I jumped into the plugin code and fixed that in the code you see below. I have not included the entire plugin code, so what you need to do is copy the code here and replace the function called “filter” in the original code; this is the guts of the text replacement. Basically, all I have done is wrapped the ellipses with a permalink to the article, which is the same as the link attached to the excerpt article title. I also added in a title for the link as well. Enjoy!

function filter($text)
{
	global $id, $post;

	// Only make the excerpt if it does not exist
	if('' == $text) {
		$length = get_option($this->name . '_length');
		$use_words = get_option($this->name . '_use_words');
		$ellipsis = get_option($this->name . '_ellipsis');
		$perm_link = get_permalink();
		$elps_link = '<a href="' . $perm_link . '" rel="bookmark" title="Read all of ' . the_title('','',false) . '">' . $ellipsis . '</a>';

		$allowed_tags = implode('><',get_option($this->name . '_allowed_tags'));
		$allowed_tags = '<' . $allowed_tags . '>';

		$text = get_the_content('');

		// WP does this to excerpts for a reason that I don't know, better be sure and do it, too, though
		$text = str_replace(']]>', ']]>', $text);
		$text = strip_tags($text, $allowed_tags);

		if(1 == $use_words)
		{
			// Count words, not HTML tags
			// Sometimes, the solution is easy
			if($length > count(preg_split('/[\s]+/', strip_tags($text), -1)))
				return $text;

			// Now we start counting
			$text_bits = preg_split('/([\s]+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
			$in_tag = false;
			$n_words = 0;
			$text = '';
			foreach($text_bits as $chunk)
			{
				// Determine whether a tag is opened (and not immediately closed) in this chunk
				if(0 < preg_match('/<[^>]*$/s', $chunk))
					$in_tag = true;
				elseif(0 < preg_match('/>[^<]*$/s', $chunk))
					$in_tag = false;

				// This should check if there is a word before the tag. I haven't thought of a reliable way to do this, though, so it's left out for now.
				//if($in_tag && substr($chunk, 0, 1) != '<')
					//$n_words++;

				// Is there a word?
				if(!$in_tag && '' != trim($chunk) && substr($chunk, -1, 1) != '>')
					$n_words++;

				$text .= $chunk;

				if($n_words >= $length && !$in_tag)
					break;
			}
			$text = $text . $elps_link;
		}
		else
		{
			// Count characters, not whitespace, not those belonging to HTML tags
			// Sometimes, the solution is easy
			if($length > strlen(strip_tags($text)))
				return $text;

			$n_chars = 0;
			for($i = 0; $n_chars < $length || $in_tag; $i++)
			{
				// Is the character worth counting (ie. not part of an HTML tag)
				if(substr($text, $i, 1) == '<')
					$in_tag = true;
				elseif(substr($text, $i, 1) == '>')
					$in_tag = false;
				elseif(!$in_tag && '' != trim(substr($text, $i, 1)))
					$n_chars++;
			}
			$text = substr($text, 0, $i) . $elps_link;
		}
		$text = force_balance_tags($text);
	}
	return $text;
}