Featured: Pink for October

Sillyness, werd


Entry: Custom Excerpts for WordPress


 

Meta & Errata


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.

 

Comments & Pontifications


  1. personal avatar Michele
    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! :)


  2. personal avatar Chris J. Davis
    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.


  3. personal avatar Bharath Kumar
    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.


  4. personal avatar Joshua
    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()?


  5. personal avatar Jeremy
    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!


  6. personal avatar Chris J. Davis
    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->ID

    If 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.


  7. personal avatar danithew
    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.


  8. personal avatar Gordon
    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… )


  9. personal avatar Mark
    Stroll on over and visit Mark
    March 1, 2007

    Great interface!


  10. personal avatar Chris J. Davis
    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.


  11. personal avatar Jeremy
    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.


  12. personal avatar Chris J. Davis
    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.


  13. personal avatar Chris J. Davis
    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.


  14. personal avatar Jeremy
    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.


  15. personal avatar Martijn
    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.

Pingbacks & Trackbacks


  1. Customize your excerpts at renet@web » [...] Before, I press this post, I should also point out that Chris J. Davis has written a wonderful post where he explains how to customize post excerpt using a more sophisticated method. [...]
  2. MacManX.com » Blogroll Dive: 5/8/06 » [...] Chris revealed the secrets behind his latest design. [...]
  3. Customize your Wordpress Excerpts - Bharath Kumar » [...] Chris J. Davis has written a wonderful article where he shares his tricks on how to customize post excerpt in a simple way. Check it out. Basically my excerpt function takes two variables, the ID of the post, and how many characters two display from that post. Not too complicated. I decided to create two seperate functions so that I could maximize flexibility. [...]
  4. » the_excerpt() i wordpress poster - Weblog at bo-k dot dk » [...] Der er mulighed for kun at vise et uddrag af en post i Wordpress. Men: funktionen the_excerpt() kan ikke rigtigt tilpasses. F.eks. afsluttes de viste uddrag ganske simpelt med […] :-( Chris J. Davis viser i sin weblog et par funktioner der klarer sagen Custom Excerpts for WordPress, men ikke lige som jeg vil ha’ det. John Wrana peger på et plugin som laver excerpts med alle mulige parametre: the_excerpt_reloaded, men giver også en idé til et hurtigt hack: Åben filen functions-formatting.php (ligger i wp-includes mappen), find funktionen wp_trim_excerpt():og tilpas linien array_push($words, '[...]'); [...]
  5. Mastering Your WordPress Theme Hacks and Techniques » ...ck around. A simple solution to accommodate both sides is to use the
  6. ??Wordpress????- 1: ??Wordpress??Hacks??? | ???? » ...????????????????????????????more??? 3)Custom Excerpts for WordPress/???Wordperss??? 4)...

Leave a Reply