» Who knew that Mister T was such a fashion maven? (0)

» "And right then," Knox said, "I heard, 'Excuse me, would it be OK if we carried her around and she touched each bag?'" Sportsmanship defined. (0)

» Web-based sequence diagram generator. Whoda thunk? Next thing you know you'll be able to buy stuff online. (0)

WordPress Asides, ColdForged-styleWordPress Asides, ColdForged-style

UPDATE: I’ve changed templates since this was written. This stuff is still effective, it’s just not displayed here.

As you can see, I’ve gotten my “asides” in place here. Note that you’ll have to go to the main page to see them. I used to maintain something I called the “sideblog” that was over in the sidebar and had links to things I found interesting but that didn’t merit a full post. I’ve missed my sideblog but have also been contemplating something more integral. Matt’s asides are more of what I had in mind as people are able to comment on his asides, but the thing that I don’t like about them is that his tend to gather up between posts, such that you often have to scroll down to get to the meat. I wanted my asides to be more “quick takes” that are almost ephemeral, they don’t take up a lot of room, and they’re definitely subservient to the main content (as rich as it is :D ).

The solution that I’ve come up with accomplishes my goals. Now I can post to a separate category cunningly called “Asides”. These posts are not included in the posts that are displayed on the main page, or in the “Last Five Entries” in the sidebar, or in the “More Recent Entries” at the bottom of the index. They appear in groups of 3 (if there are enough, a condition that only exists now as I haven’t generated 9 asides to fill all the spaces) between main posts. As I add asides, they redistribute themselves between the posts so that the 3 most recent appear at the top of the index, the next three appear between the first and second posts and so on. People can comment on these asides and see how many comments exist on the aside. Going to the comments also shows that you can view the archives of asides. There’s even an RSS feed for people that want to subscribe to the nutty asides.

So, how was this done?

Fairly straightforward but with some customization of plugins. I started off with Scott Reilly’s Customizable Post Listings plugin. This is a plugin that makes it pretty easy to generate lists of posts in various ways. However, it didn’t have quite the functionality that I needed for a couple of things — I wanted to replace my plugin with his, so I needed it to be able to do the things I needed for my “Last Five Entries”, my “More Recent Entries”, and my Asides. Here are the things I added:

  • Most importantly was the ability to exclude categories in post listings. This way I can leave my Asides posts out of the “Most Recent” lists. I want those lists reserved for “real” posts like this one. I have to be able to support multiple exclusions as well — my “Currently Reading” section is a separate exclusion all its own — so that required a bit of adjustment of the code.
  • To support the lists I already had, I needed some additional format specifiers. I added specifiers for providing links to the category archives of posts and links to the comments section using the “fancy comments” text (ie. “No Comments”, “1 Comment”, “2 Comments”, etc.).
  • For the asides I needed the ability to display the number of comments as a link to the comments sections.
  • For the way I wanted to do asides, I needed to know the number of posts actually generated in the list. That way, I can accurately offset into the asides posts for the subsequent asides lists.
  • In addition to these changes I wanted a way to track the most viewed post. Hence, I added a call to increment a new field in the posts table upon command, and now we can order by that field as well as have a format specifier to show the number of views of that post. It’s up to the user when to determine a post is “viewed”… insert it in the main loop and anytime the home page is looked at the posts on that page are determined to be “viewed”. I’m currently only defining a post as being viewed when the single entry page is viewed.

Installing the plugin

Scott may work some of this functionality into his plugin, but until then those of you wishing to have similar functionality can use my version of his plugin. Install as usual — unzip, stick file in your wp-content/plugins directory, activate from the WordPress control panel. Now, to get the view count functionality — and bear in mind that this is optional… if you never use the view_count orderby list type or try to use the %post_view_count% format specifier you’ll never have problems — you’ll need to update the database. Run the following MySQL command against your database.

ALTER TABLE wp_posts ADD post_view_count INT UNSIGNED NOT NULL

Now it’s up to you to decide how you want to have your posts tracked. Wherever you view a post you’re welcome to have that tracked… from within your index, from only the single post view page, it’s totally up to you. Insert the following code in the loop wherever you wish. The only requirement is that the global variable $post be available.

<?php c2c_increment_post_view_count();?>

This simply increments the view count for the current post.

Getting a list of asides

An important note about asides. If you’re dealing with one category of exclusions, that’s pretty simple. WordPress supports one category of exclusions pretty handily with one simple change to the main index.php. Simply insert a line in the following location of the main index.php at your blog’s root. Note that it is the “$cat =…” line that we added.

/* Don't remove this line. */
$cat ="-27";
require('./wp-blog-header.php');
include(ABSPATH . '/wp-header.php');

That tells WordPress to leave out all posts in the category whose ID is 27 from the main processing loop. It’s only when you want more that one category excluded that you’ll have trouble. To do that you have to modify WP itself. It’s not hard, but some people may be skittish. First, change that line to be a space-delimited list of categories preceded with dashes that you want excluded, like so:

/* Don't remove this line. */
$cat ="-27 -28";
require('./wp-blog-header.php');
include(ABSPATH . '/wp-header.php');

Now, edit your $ROOT/wp-includes/classes.php.

You’re looking for the following code:

$q['cat'] = ''.urldecode($q['cat']).'';
$q['cat'] = addslashes_gpc($q['cat']);
if (stristr($q['cat'],'-')) {
        // Note: if we have a negative, we ignore all the positives. It must
        // always mean 'everything /except/ this one'. We should be able to do
        // multiple negatives but we don't
        $eq = '!=';
        $andor = 'AND';
        $q['cat'] = explode('-',$q['cat']);
        $q['cat'] = intval($q['cat'][1]);
} else {
        $eq = '=';
        $andor = 'OR';
}
$join = " LEFT JOIN $wpdb->post2cat ON ($wpdb->posts.ID = $wpdb->post2cat.post_id) ";
$cat_array = explode(' ',$q['cat']);
$whichcat .= ' AND (category_id '.$eq.' '.intval($cat_array[0]);
$whichcat .= get_category_children($cat_array[0], ' '.$andor.' category_id '.$eq.' ');
for ($i = 1; $i < (count($cat_array)); $i = $i + 1) {
        $whichcat .= ' '.$andor.' category_id '.$eq.' '.intval($cat_array[$i]);
        $whichcat .= get_category_children($cat_array[$i], ' '.$andor.' category_id '.$eq.' ');
}
$whichcat .= ')';
if ($eq == '!=') {
        $q['cat'] = '-'.$q['cat']; // Put back the knowledge that we are excluding a category.
}

and we’re going to change it to this:

$q['cat'] = ''.urldecode($q['cat']).'';
$q['cat'] = addslashes_gpc($q['cat']);
if (stristr($q['cat'],'-')) {
        // Note: if we have a negative, we ignore all the positives. It must
        // always mean 'everything /except/ this one'. We should be able to do
        // multiple negatives but we don't
        $eq = '!=';
        $andor = 'AND';
} else {
        $eq = '=';
        $andor = 'OR';
}
$join = " LEFT JOIN $wpdb->post2cat ON ($wpdb->posts.ID = $wpdb->post2cat.post_id) ";
$cat_array = explode(' ',$q['cat']);
$whichcat .= ' AND (category_id '.$eq.' '.abs(intval($cat_array[0]));
$whichcat .= get_category_children($cat_array[0], ' '.$andor.' category_id '.$eq.' ');
for ($i = 1; $i < (count($cat_array)); $i = $i + 1) {
        $whichcat .= ' '.$andor.' category_id '.$eq.' '.abs(intval($cat_array[$i]));
        $whichcat .= get_category_children($cat_array[$i], ' '.$andor.' category_id '.$eq.' ');
}
$whichcat .= ')';

My asides are interspersed between main posts only on the index. Therefore, my list function invocation is in the main loop, right before any actual post output. Note that I keep track of the return value so as to be able to automatically increment through the asides. That way, for instance, if I ever choose to have a different number of posts on my front page the asides will be correctly handled as opposed to hard-coding any numbers in. The $asides_offset variable controls this and starts at zero before the invocation. Each time through the loop it is incremented by the number of posts actually processed and then passed as the offset parameter into the function. 27 is the category ID for my asides, so that is the only category I want in this list.

$asides_offset += c2c_get_recent_posts( 
     3, '<p>&raquo; %post_content% (%comments_count_url%)', '27', 
     'date','DESC',$asides_offset);

My “Currently Reading” section on the main page is a separate case but similar to an aside. It’s not included in the main flow of posts and not included in various lists, just like the asides. For completeness’ sake, here’s that invocation. Note that 28 is the category for “Currently Reading”.

c2c_get_recent_posts( '1',"<p>%post_content% 
(%comments_count_url%)</p>",'28');

Customizable “recent posts” lists

Now for the sidebar “Five Most Recent” and the index’s “More Recent Entries” the syntax is slightly different. Here’s both of those calls, with the exclusions needed to leave out the asides and “Currently Reading” stuff. First the “Five Most Recent”. The most interesting thing about this invocation is the multiple category exclusions (the ‘-27 -28′ to exclude category numbers 27 and 28):

c2c_get_recent_posts('5',"<li>%post_URL%
%post_date%</li>",
'-27 -28','date','DESC',0,'F d,Y');

Now for the slightly fancier “More Recent Entries”. Note that I’m excluding the same categories but using some different formatting options, all from one call. In this case I want to start my posts from the last post on the index, so I utilize the existing “$posts_per_page” variable which tells WP how many posts to display on the index. It handily doubles into the amount of posts to offset for the “Most Recent Entries”.

$comment_icon = '<img src="' . get_bloginfo('template_url') . 
    '/images/comments.gif">';
c2c_get_recent_posts( 9, '<p>%post_URL%&lt;br />Posted on 
%post_date% in %post_categories_url% | '.$comment_icon.'&nbsp;
%comments_fancy_url%</p>', '-27 -28', 'date','DESC',
$posts_per_page,'F d, Y' );

The final invocation is for my “most viewed posts” list. The only thing different about this is the “order by” parameter. In this case I want to order by the “view_count” field in descending order, meaning that the most viewed post is listed first.

<?php c2c_get_recent_posts('5',"<li>%post_URL%
%post_date%</li>",'-27 -28','view_count','DESC',0,'F d,Y');?>

Hope this helps someone. Note that this post has been around for about a week in various stages, but with the code section screwups it was too ugly to post. It still isn’t perfect, but it’s better than nothing.

If you like it…

Please note, if you find this or any of my plugins useful and feel the need to express your appreciation, I accept donations with a difference. Click the banner below to learn more.

Digg!

84 Responses to “WordPress Asides, ColdForged-style”

Pages: « 9 ... 5 4 [3] 2 1 » (Show All)

  1. 30

    ColdForged Says:

    Glad it was helpful, Ashwin, nice work.

  2. 29

    Ashwin Says:

    I’ve been meaning to implement something like this on my website for a long time but never really found the time or the plugin that did it for me. Gotta thank you for doing all the hardwork for me. :)

    I implemented all but your “Recent Entries” on my site without much hassle. Thanks once again.

  3. 28

    ColdForged Says:

    Can you please explain how I can do that?

    Sure. First, go to the Options -> Writing page and look for the “When starting a post, show:” setting under “Writing Options” and set your editing mode to the “Advanced controls.” This will allow you to see the excerpt field. Now, go back and edit your asides posts and cut the content that you had in the big text area (the “Post” section) and paste it into the “Excerpt” area, then save.

    Now, go to your template editor and edit the Main Template. Find where you put the asides code and change the '%post_content%' to be '%post_excerpt%' instead. Save the template. Now you should be good to go!

  4. 27

    Derek Says:

    I’m pretty new at this. Can you please explain how I can do that? Sorry, I’m just figuring PHP and WP out.

  5. 26

    ColdForged Says:

    Derek, try putting the content that you want for your asides in the excerpt and displaying the_excerpt instead of the_content. This has to do with the way WP styles the_content.

  6. 25

    Derek Says:

    I’m using a modified Kubrick theme, and for some reason it’s putting a line break between each of the percent tags. Why would it be doing that?

  7. 24

    chenu Says:

    Actually, I figured it out, I just put 2 instances of
    %postcontent% (%commentscounturl%)’, ‘19′,’date’,'DESC’,$asidesoffset);?> one without the line code and one with.

  8. 23

    chenu Says:

    Thanks a lot, I got it figured out almost completely. The only thing I need to do now is to add the line that I have under all posts under the asides. How would I add it so that it is only included once under each asides block.

  9. 22

    ColdForged Says:

    Oops. You mean this index?

  10. 21

    chenu Says:

    Hmm, you don’t seem to have linked to your index file. You just have empty a tags.

Pages: « 9 ... 5 4 [3] 2 1 » (Show All)