WP+jMonthCalendar=Fancy

I'm developing a website in WordPress for a "tourist destination" that has a few types of content -- webpages, blog posts, events, and business listings. After learning a few things about using WordPress as CMS, I decided at the beginning that everything (except for webpages) would need to be some kind of Post. Using Freshout's Flutter plugin, I'm making "post-types" for events and business listings. These custom post-types are basically souped-up Posts with fancy custom fields. (For more info, visit the Flutter Support & Usage pages.) Now, to get to the reason for this blog post: I have a two major requirements for the my "Events Calendar." I want it to:
  1. start by showing events happening this month, and show events in the future very easily (without reloading the page), or to look at an archive of events if you really want to (could require reloading the page or going to a different page); and
  2. use "Progressive Enhancement" (such that it's a cool-looking calendar if you've got JavaScript & CSS enabled, and just a list of events listed chronologically if you're a search engine spider, using a screen reader, an ancient browser, or just like your websites text-only-please-and-thank-you).
Here comes the magic: Byte Cyclist's jMonthCalendar jQuery plugin & Multiple Loops. In a custom plugin I have declared a function this_month_and_future that makes a custom SQL query, only returning posts in the "events" category that occur this month or in the future. (Remember to enable the plugin.) Code below:
<?php
/*
Plugin Name: Custom Calendar Query
Author: Esther S White
*/
function this_month_and_future() {
   global $wpdb;
   $querystr = 'SELECT * FROM $wpdb->posts
      LEFT JOIN $wpdb->postmeta AS eventdate ON($wpdb->posts.ID = eventdate.post_id)
      WHERE $wpdb->posts.post_status = 'publish'
      AND eventdate.meta_key = 'event_date'
      AND YEAR(eventdate.meta_value) >= YEAR(CURDATE())
      AND MONTH(eventdate.meta_value) >= MONTH(CURDATE())
      ORDER BY eventdate.meta_value ASC
   ';
   $pageposts = $wpdb->get_results($querystr, OBJECT);
   return $pageposts;
} ?>
On my calendar.php template page, inside of the regular WordPress loop, I've got the following code printing this month and future events as list items in ol#calendar:
<?php $temp_wp_query = wp_clone( $wp_query );
$temp_post = wp_clone( $post );
$posts = this_month_and_future(); ?>

<ol id='calendar'>
   <?php if ($posts): foreach ($posts as $post): setup_postdata($post); ?>
   <li class='event' id='<?php the_ID(); ?>'>
   <?php echo '<a class='event-link' title=''.get_the_title().'' href=''.get_permalink().''>'; the_title('<h3>', '</h3>'); ?></a>
      <span class='date' id='<?php echo get_post_meta(get_the_ID(), 'event_date', true); ?>T00:00:00.0000000'><?php echo get('event_date'); ?></span>,
      <?php echo get('event_location'); ?><br />
      <span class='description'><?php the_excerpt(); ?></span>
   </li>
<?php endforeach; endif;
$post = wp_clone( $temp_post );
$wp_query = wp_clone( $temp_wp_query ); ?>
</ol>

<div id='jMonthCalendar'></div>
And in my theme's common.js file, I've got the following code hiding the original ol#calendar and parsing those list items:
$(document).ready(function() {
$('ol#calendar').hide();

var my_events = new Array;
$('ol#calendar li').each(function(i) {
   my_events[i] = {
     'EventID': i,
     'Date': $('.date', this).attr('id'),
     'Title': $('.event-link', this).attr('title'),
     'URL': $('.event-link', this).attr('href'),
     'Description': $('.description', this).html(),
   };
});

var options = {
   height: 500,
   width: '20em',
   navHeight: 25,
   labelHeight: 25,
   firstDayOfWeek: 0,
   navLinks: {
   p:'Prev',
   n:'Next',
   t:'Today'
},
};

$.jMonthCalendar.Initialize(options, my_events);
});
Viola! Now I have a calendar that only shows this month and future events as a nicely-formatted monthly calendar if you've got JavaScript & CSS enabled, and as an ordered list if you don't. It's easy to customize and quick to load. What's left? This example doesn't go into using tooltips (jQuery BeautyTips are my favorite) to display the event.Description or handle events with duration or a start time other than 00:00:00.0000000, but once this is done, that part should be easy, right?!
This entry was posted in wordpress and tagged , , , , , . Bookmark the permalink. Comments are closed, but you can leave a trackback: Trackback URL.

2 Comments

  1. Kyle LeNeau
    Posted March 19, 2009 at 2:52 pm | Permalink

    Sweet!!! I like it. I like seeing my calendar used in various ways. Nice work. Multi-day events are in the works too.

  2. oxana
    Posted March 2, 2010 at 8:33 am | Permalink

    Great post! Thanks for ideas!