Creating a multi-day event calendar in WordPress using the Magic Fields Plugin

If you have ever used some of the event calendar plugins available for WordPress, you’ve probably noticed that most of them don’t handle multi-day events very well. Especially if the event has multiple day sessions lasting from 1PM – 5PM, for instance.

Strategy6 had this very problem last year for a WordPress website we developed for Dothan Magazine. We solved it then but didn’t document it very well. Now that a similar solution is needed for another client, I figured we’d document a how-to in a blog post for others that may need the same solution.

Install Magic Fields

The first step is to login to your WordPress site and install the Magic Fields plugin. Magic Fields, by Hunk and Gnuget, is a welcome improvement to the popular Flutter plugin.


Create the necessary categories

Now you will need to create your custom categories that will be used for the events. In our case, we needed a calendar of events for four types of classes, plus a global calendar that would include all the classes as well as anything non-class related that was going on. I ended up creating an Event category plus four child categories of Event. In our case those categories were Teen Relationships, Babies and Families, Relationships, and Marriage. Your child categories, if you need any, will most likely be different 🙂

Magic Fields custom write panelCreate a Custom Write Panel

The next step is to create a custom write panel using the Magic Fields plugin.  When Magic Fields is installed and activated, scroll down to the bottom of your browser and click the Magic Fields panel.  Then create a custom write panel for your event.  Here is how I created mine:

As you can see, this is for the global Event category that will essentially display everything. If you just have one type of event, you won’t have to worry about child categories. Just select the category you created for your events. In my case, I only selected that the standard Post/Page fields be displayed. I unchecked everything else to prevent the customer from a)getting confused when creating a new event and b)screwing anything up. When you are finished setting up your Custom Write Panel, click the Finish button.

Add a Group

I always like to create a Group to contain all my custom fields. I just clicked the “+Create a Group” button and named it Event Info.  Leave the two checkboxes unchecked and click Finish.

Custom Field Creation

Next, we need to create our custom fields for the Event Info group. If you need something to handle both multiple day events and single day events then this is critical you get it right.

First, create a field and Label it “Date.” Be sure to put something helpful in the Help Text field.  In my case I put “The day of the event. For multiple day events put the Start Day.” Make the field required, select Date as the Type, and click Continue. Change the date format if you need to, I just left it the way it was and pressed Finish.

Next, you need to create the ending date.  Create it the same way you did the Date field, but call it Ending Date and make it optional (this is important because not all events will be multiple days).

If you only have one event category then you are finished (unless you need more custom fields; in our case we did not).

Create two test events

You should now have a panel called “Events,” or whatever you named it when you created your custom write panel. Create a new Event, call it Test Event 1, put something in the post field, and select a beginning and ending date.

Next, create another event.  Call it Test Event 2, and leave the ending date blank.

Custom PHP Code to display the events

Now the real fun begins. Wherever in your WordPress theme you want your calendar to be displayed, you’ll have to place the following code to query for any upcoming events:

1.    $temp = $wp_query;    // pagefix
2.    $wp_query = null;        //pagefix
3.    $wp_query = new WP_Query();
4.    $wp_query->query('category_name=events&showposts=10&orderby=meta_value&meta_key=event_info_date&order=ASC&paged=' .$paged );

To break it down, lines 1 & 2 are necessary if there are other loops on the page that haven’t ran yet.  We’ll actually have to assign $wp_query the value of $temp once our custom loop is complete.

Line 3 creates a new WP_Query object and line 4 builds a query to get everything in the events category, paginated 10 at a time and ordered in ascending order by the start date. Note that event_info_date is the field MagicFields assigned for our start date variable. If it assigned something different from you then replace event_info_date in the line of code above with whatever that variable is. If you don’t, then it probably won’t work.

Now we need to loop through and display one date if it is a single day event or display a start and end date if it is a multiple day event.  Study this code to see how I pulled this off:

<?php if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
<div <?php post_class('clearfix') ?>>
$startdate = get('event_info_date');
$startstamp = strtotime($startdate);
$enddate = get('event_info_ending_date');
$endstamp = strtotime($enddate);
<h3 id="post-<?php the_ID(); ?>"><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h3>

<?php if(($endstamp > 0) && ($endstamp != $startstamp)){ ?>
<p><?php echo get('event_info_date'); ?> - <?php echo get('event_info_ending_date'); ?></p>
<?php }else{ ?>
<p><?php echo get('event_info_date'); ?></p>
<?php } ?>
<?php the_content(); ?>
</div><!-- End entry -->
</div><!-- End post-class -->
<?php endwhile; ?><?php endif; ?>

This block of code gets the beginning and ending date in a format that we can evaluate the length of a little later:

$startdate = get('event_info_date');
$startstamp = strtotime($startdate);
$enddate = get('event_info_ending_date');
$endstamp = strtotime($enddate);

Next, we go ahead and post the title of the event and make the title an link:

<h3><a href="<?php the_permalink() ?>" class="title" rel="bookmark" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h3>

(obviously you can change the markup to suit your needs).

Now let’s take another look at the remaining code:

1. <?php if(($endstamp > 0) && ($endstamp != $startstamp)){ ?>
2.   <p><?php echo get('event_info_date'); ?> - <?php echo get('event_info_ending_date'); ?></p>
3. <?php }else{ ?>
4. <p><?php echo get('event_info_date'); ?></p>
5.   <?php } ?>
6.     <div>
7.      <?php the_content(); ?>
8.     </div><!-- End entry -->
9.  </div><!-- End post-class -->
10. <?php endwhile; ?><?php endif; ?>

Line 1 is evaluating the length of the ending timestamp. If the length is greater than zero (in other words: the user selected an ending date) and the ending timestamp does not equal the starting timestamp, then we’ll display a begging and ending date for the event (line 2).

If this is not the case (line 3), then we simply display the beginning date (line 4).  Line 7 displays the content for the post data and line 10 closes our loop.

Viola! we have an event calendar that can display single or multiple day events!

One last thing to tidy it up.  You need to reset the value of $wp_query to the value we saved in the $temp variable at the very beginning:

<?php $wp_query = $temp; ?>

Be sure to place this last piece of code after the loop is closed.

Other improvements

I’m sure that some of the PHP code could be placed in functions.php to tidy things up even further. If you have questions or suggestions for improvements please leave a comment below.  Enjoy!

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply