is now an archive and is no longer updated, you can find new writings at →

03 22 2009

Visualizing data is a difficult task, but it does allow for some very interesting design elements. The problem with such visualizations however, results from a less usable result than had the data been formatted normally. Displaying statistics is an obvious example of situations where data visualization is necessary and important in order to grasp trends and analyze such data.

The trickier part comes when handling data that users will interact with. For example, the archives here on Astheria are presented in a timeline format. It provides a visual cue to relevance of a post by how old it is, but also maintains a list format that is relatively easy to digest and use. Although the growing number of posts here may demand an alternative format.

This post will be written from the perspective of doing something similar in WordPress, although the concept and the bulk of the code is applicable to any content management system, or in fact, anything that stores dates with items that are comparable! Granted, I’m not a PHP programmer, and I’m sure some of this could be done differently. However, I’ve received a number of requests via e-mail about how this was done, and thought I would share the code.

Please note that I’m providing this code ‘as is’ and am not offering any support or installation assistance. What this script will do is print an ordered list for each year of posts you have, along with a title for that year. Each list item will be vertically separated from its peers based on the time that has passed between the two. You can adjust the $distance_multiplier variable to adjust the scale of the gaps. Enjoy!

I had a bit of help fixing some hiccups in the code from my coworker and friend, Matt Gray.

<?php get_header(); query_posts('posts_per_page=-1');
	$dates_array 			= Array();
	$year_array 			= Array();
	$i 				= 0;
	$prev_post_ts    		= null;
	$prev_post_year  		= null;
	$distance_multiplier 	        = 2;

	<?php while (have_posts()) : the_post();

		$post_ts    =  strtotime($post->post_date);
		$post_year  =  date( 'Y', $post_ts );

		/* Handle the first year as a special case */
		if ( is_null( $prev_post_year ) ) {
			<h3 class="archive_year"><?=$post_year?></h3>
			<ol class="archives_list">
		else if ( $prev_post_year != $post_year ) {
			/* Close off the OL */

			$working_year  =  $prev_post_year;

			/* Print year headings until we reach the post year */
			while ( $working_year > $post_year ) {
				<h3 class="archive_year"><?=$working_year?></h3>

			/* Open a new ordered list */
			<ol class="archives_list">

		/* Compute difference in days */
		if ( ! is_null( $prev_post_ts ) && $prev_post_year == $post_year ) {
			$dates_diff  =  ( date( 'z', $prev_post_ts ) - date( 'z', $post_ts ) ) * $distance_multiplier;
		else {
			$dates_diff  =  0;
		<li style="margin-top:<?=$dates_diff?>px"><span class="date"><?php the_time('F j'); ?><sup><?php the_time('S') ?></sup></span> <a href="<?php the_permalink() ?>"><?php the_title(); ?></a></li>
		/* For subsequent iterations */
		$prev_post_ts    =  $post_ts;
		$prev_post_year  =  $post_year;

	/* If we've processed at least *one* post, close the ordered list */
	if ( ! is_null( $prev_post_ts ) ) {
	<?php } ?>


  1. Top stuff. Thanks for sharing this Kyle. Archiving has been one part of my site I’m not particularly happy with.

    I think this approach definitely lends itself to a site like yours (in terms of post frequency etc).

    Personally I’m trying to keep the large gaps between my postings under wraps. :D

  2. Brilliant post. Your timeline looks so elegant and much more friendly than the normal list of posts.

  3. Great post. Your timeline looks really good and elegant. You have done a good job there.

  4. Lovely archive format it has to be said, thanks for sharing your technique mate :)

  5. I just discovered your site the other day, and the archive page is the part that stood out to me the most. Great work.

  6. Love it. That is a great way to visualize the posting frequency. Nice work.

  7. Love the design of this site, particularly the Archives page, so it is good to see this example.
    I have a question though - how would I go about adapting this to be separated by month instead of year?

  8. Great! Was waiting for that article :)

  9. I have a question though - how would I go about adapting this to be separated by month instead of year?

    You would need to add extra loops and a month counter; essentially you’d just end up nesting more loops within each year, using the same type of logic.

  10. Great execution. Infrequent bloggers could benefit from a nifty trick like this.

  11. Beautiful!

  12. I have been thinking of ways of doing this exact thing.

    Thanks for sharing!

  13. wow..thank you so much for this awesome archive page.
    this is what i need for my new website. :)

  14. Amazing!, i love it!, (claps! claps!)

  15. I’ve been a fan of your archive for a long time, and the rest of the site too, of course. Thank you so much for sharing this!

  16. Thanks for sharing this Kyle! Have started using it on my site Have used some of your CSS to style, happy to remove and recreate if you object.

  17. Thank you for sharing this archive ! Excellent work.
    I have added the_excerpt in hidden span , so when roll over a title you see a few lines from article displayed on the left.

  18. Fantastic idea, simple and effective. I’ll be applying this concept to one of my future projects! Great work.

  19. for those who try this code .
    There were some changes in PHP since this code was posted.
    if it does not work for you ( you run php 5.3 )

    replace: ‘<?='
    with: '<?php echo '

    then it should work