So I have already been asked a couple of questions about the new deisgn; namely how do I make WordPress give me the entire commenting history for an individual commenter, and how am I doing my excerpts in the recent entries column.
I thought I would cover the second question first, since it is the easier of the two. I toyed with using the function the_excerpt(); built into WordPress, but after much deliberation I decided to roll my own so that I could have more control over the output.
Basically my excerpt function takes two variables, the ID of the post, and how many characters to display from that post. Not too complicated. I decided to create two seperate functions so that I could maximize flexibility.
Function one: recent()
So the first function hits the DB and find the most recent (n) posts, excluding our current post (which we pass to the function via $post->ID.):
function recent($current) {
global $wpdb;
$posts = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID != '$current' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 5");
if(is_array($posts)) {
return $posts;
} else {
return array();
}
}
So let’s take a quick look at what we are doing with our recent() function. First off we of course are globalling the WordPress database object… kind of hard to retrieve data without it.
Next we move onto our SQL query. Let’s take a look at the query on its own, for this example lets assume that we passed our function a post id of 789:
$posts = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID != '789' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 5");
Nothing too complex going on here either; we are grabbing all the data from our post table except for our newest post (the WHERE clause), making sure that the posts we are retrieving have been published (the AND) and finally limiting the number of posts that are being returned to 5; oh, we are also saying give them to us in descending order (the ORDER BY bit.).
So by this point we should have all the data we need from the database; since we are requesting multiple pieces of data we will be expecting an array to be returned.
The next bit of code is just some error checking that I do as a rule to make sure that I have an array before I move on; the code we will be using to interact with our retrieved data expects an array to be passed to it, even if it is an empty one (return array() will create an empty array):
if(is_array($posts)) {
return $posts;
} else {
return array();
}
}
So now we have all of our recent post data, so now we need to create the function that we will call to create our excerpt text.
Function 2: excerpt()
Now getting on to the fun part, making our excerpt. One of the things I wanted to be able to do with this function was call it from any number of possible locations, not just from the recent posts area. To make it as flexible as possible, I decided it would accept two variables: $text and $chars:
function excerpt($text, $chars) {
$text = $text . " ";
$text = strip_tags($text);
$text = substr($text,0,$chars);
$text = substr($text,0,strrpos($text,' '));
$text = $text . "...";
echo $text;
}
What the above function allows us to do is to give it a text stream, and a number of characters to limit that text stream to. For instance I could call it like so: excerpt('This is my great text', '3');, which would give me:
Thi
Or I could call excerpt('This is my great text', '10'); which would give me:
This is my
I think you get the idea. So now all that is left is to throw the two functions together in a class file:
class posts {
function recent($current) {
global $wpdb;
//$today = gmdate("Y-m-d G:i:s");
$posts = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID != '$current' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 5");
if(is_array($posts)) {
return $posts;
} else {
return array();
}
}
function excerpt($text, $chars) {
$text = $text . " ";
$text = strip_tags($text);
$text = substr($text,0,$chars);
$text = substr($text,0,strrpos($text,' '));
$text = $text . "..";
echo $text;
}
}
Now that we have created our posts class, it is time to switch to our front end code. For this example we are going to be adding this code to our sidebar.php template file, so that when you the root of your site is being viewed (index.php with no arguments) your most recent 5 posts will be shown.
Our code would look something like this:
<?php if (is_home()) { ?>$recent = posts::recent($post->ID); ?><ol><?php foreach ( $recent as $item ) { ?><li><p><a href="<?php echo $item->guid; ?>"><?php echo $item->post_title; ?>. <?php posts::excerpt($item->post_content, '125'); ?>.
</p></li><?php } ?></ol><php } ?>
So as you can see from the above code, we are calling our recent function, and then passing the array off to our foreach loop for processing. Here in the loop is where we call our second function, excerpt().
In this example we are passing the post_content for each item in our array to our excerpt() function and limiting the returned content to 125 characters. Not too difficult.
And that is all she wrote.
For the most part this is the exact code I am running to power my recent entries section. Let me know via the comments if anything wasn’t clear, and I will try to update this post to improve it.
As I said at the beginning, you could easily combine these two functions into one, but I seperated them to allow for using them in unexpected, or unanticipated ways later. To each his own.

Stroll on over and visit Michele
March 1, 2007
Just a quick thought: wouldn’t it be better to strip tags before calling substr? This way tags wouldn’t count in the total chars count.
Thanks for sharing! :)
Stroll on over and visit Chris J. Davis
March 1, 2007
Excellent point Michele.
I have made that change to the code in the article.
Stroll on over and visit Bharath Kumar
March 1, 2007
Thx Chris for sharing this with all. But I still had problems to make it work with K2. I will give it a try again anyways.
I am really looking forward for ur post on the commenting history for an individual commenter. I have been using this plugin from the Believe theme u released before. I got a couple of qn’s on that
1. If there is a link to the comment author like on comments template, can we assign that link to the author name here too ?. I tried but cant make it work.
2. Instead of showing like ‘100 comments’ and ‘all comments’ seperately, can we assign that comment history link to the total comments. Clicking on that 100 comments will give that authors entire commenting history.
I did make some changes to the code, like showing the post title. you can see it on my blog sidebar.
Stroll on over and visit Joshua
March 1, 2007
Hmm, what happened if the post has fewer characters than what you pass to the excerpt()?
Stroll on over and visit Jeremy
March 1, 2007
Hey there Chris!
Thanks for addressing this in your post! Are you bringing back the Silly University? I really appreciate how clear you write your tutorials.
There is one aspec that I really dont understand though… Where do I put the first function? Do I put it in the loop?
In your index.php, do you have the first function there?
other than that, it all makes sense. It will be nice to see it in action. :)
thank you!
Stroll on over and visit Chris J. Davis
March 1, 2007
Hey Jeremy,
Thanks for the kind words, I miss writing these tutorials and it is nice to see someone out there appreciates them.
As for your question, yes this would need to be placed within the loop somewhere. A way to divine that in the future is to look for things like
$post->IDIf that is called in the code you are looking at, it would have to reside within the loop.
Also I do have plans to bring back the University; I am just not sure how or when yet.
Stroll on over and visit danithew
March 1, 2007
The “see all comments” by a specific commenter function is not working for me. I’m getting some kind of error message.
Stroll on over and visit Gordon
March 1, 2007
Liking this a lot. Clever stuff indeed. Although, at this precise visit, your avatar is repeated five times as the top commenter… it’s a bit freaky (and I mean that in the nicest possible way… )
Stroll on over and visit Mark
March 1, 2007
Great interface!
Stroll on over and visit Chris J. Davis
March 1, 2007
Thanks for the catch danithew. I changed my site to use PHP 5’s magic instantiation-foo and forgot to update that file.
All fixed up now.
Stroll on over and visit Jeremy
March 1, 2007
Hey there Chris,
So I have been reviewing multiple ways of achieving a similar result on my front page (that should launch soon!)
I happen like the way you are dong things there because you are making your own excerpts. All other methods that I have been lookng into, use a method of calling a particular category, and pulling it in. What you are doing also cuts down on calls to the server. All things that I am very imterested in.
However, I cannot get your bit to work for me. The reason, is that I dont understand where you put the class file. I get the the second part needs to go within the loop, but as for the first part, I am stumped.
I thought maybe you could shed some light.
Stroll on over and visit Chris J. Davis
March 1, 2007
Hey Jeremy,
I just wanted to let you know that I am not ignoring you mate. I am backed up against a wall of deadlines; I am planning on responding to you at length tomorrow. I will take a look at the code in pastebin tomorrow as well.
Sorry for the slow response.
Stroll on over and visit Chris J. Davis
March 1, 2007
Hey Jeremy,
This took forever for me to respond to eh? Your question about where does the code go is easy enough to answer. Wherever you want it to go.
What I mean by this is that it can go in your functions.php file in your theme dir, or you could make a plugin out of it and activate it through the Plugin page.
I have opted to store my classes in an app dir within my theme dir and use PHP 5’s auto-instantiation foo to load the files as they are called.
I am going to write a quick tutorial on how to do this soon.
Stroll on over and visit Jeremy
March 1, 2007
Hey there Chris… That was more helpful in that I understand that the functions need to be separated out. I found functions.php in wp-includes and I also tried creating a functions.php file within my theme. I need to play around with it some more before I get it working. I have a feeling that it is simple, but there is something that I am not getting.
Thank you for the reply. I really appreciate it.
Stroll on over and visit Martijn
March 1, 2007
Nice work and thanks for scharing. A quick thought: might be nice to count words instead of characters and always break off the excerpt at a complete word.