- 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
- 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).
<?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?!
2 Comments
Sweet!!! I like it. I like seeing my calendar used in various ways. Nice work. Multi-day events are in the works too.
Great post! Thanks for ideas!