Creating a custom upcoming events page in WordPress

We were recently tasked with creating an upcoming events-type system for the Victor Valley Shooters. They needed to keep their users updated on shooting class schedules.

Admin Page

Our requirements

  • List of upcoming classes and status
  • Past events are archived and hidden from the list
  • Custom URL for each class with additional information
  • Super-simple way to mark classes Sold Out or Available through the administration section
  • Custom method to display each class as a flyer

The default WordPress data set isn’t robust enough to handle this, so we had to do some digging. After testing at least 20 different plugins, here’s what we came up with.

Container Page

Plugins used

  • More Fieldsallows us to configure all of the metadata fields that we need for each event: pricing, time, location, requirements, etc.  This plugin has since become one of our favorites to extend WordPress’s default functionality.
  • Duplicate Postallows an admin to recreate a past event with a single click.  We had to update this plugin to work with 2.7.1 which was actually quite simple (I believe the plugin has since been “officially” updated by the author).
  • No Future Postschanges the status of our entries to allow future dated entries to be displayed to normal users.

Our templates are really where this all comes together to make the solution viable.  We’re using two templates; the first displays all upcoming events in a single list and the second displays details for each event.

First things first, we need to get our classes from the database using get_posts().

<?php
$classes = get_posts(array(
'post_type' => 'page',
'numberposts' => -1,
'post_parent' => 12,
'orderby' => 'date',
'order' => 'ASC'
));

This tells our template to pull all pages that are a child of page id 12 and order by date.

Next, we need to start a loop and then check to ensure our event hasn’t past.

foreach ($classes as $class) {
// check for past dates!
if (strcmp(date('Y-m-d'), $class->post_date) > 0) continue;

Once we’re here, we can assume we have a good event and it’s just a matter of pulling our custom fields, displaying everything, then closing the loop up.  Here’s what the completed template excerpt looks like.

<?php
$classes = get_posts(array(
'post_type' => 'page',
'numberposts' => -1,
'post_parent' => 12,
'orderby' => 'date',
'order' => 'ASC'
));

foreach ($classes as $class) {

// check for past dates!
if (strcmp(date('Y-m-d'), $class->post_date) > 0) continue;

// get ze custom fields!
$custom_fields = get_post_custom($class->ID);

?>
<div class="class">
<div class="class_date">

<?php echo date('l', strtotime($class->post_date)); ?>

<?php echo date('M j', strtotime($class->post_date)); ?>

<?php echo $custom_fields['time']['0']; ?></div>
<h3><a href="<?php echo $class->post_name; ?>"><?php echo $class->post_title; ?></a></h3>
<?php
// only display what's before the 'more' comment, then run some filters and output
$content = substr($class->post_content, 0, strpos($class->post_content, '<!--more-->'));
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
$content = str_replace('
', '
', $content);
echo $content;
?>
<div class="class_status">
<?php
if ($custom_fields['status']['0'] == "Seats Available") echo '
<span class="status_text">Seats still available: '.$custom_fields['cost']['0'].'</span>
Call to book this class: 760-242-2399

';
elseif ($custom_fields['status']['0'] == "Sold Out") echo '
<span class="status_text">Sold out</span>

';
?></div>
</div>
<?php
} // end foreach
?>

Detail PageNow, we have a nice top level page for our events!  Don’t get too excited just yet; we still need to display our detail page.

The detail page uses our custom fields to create a useful layout.

First, we start the standard WordPress output, get our custom fields, and set a date variable for later use.

<?php
if (have_posts()) : while (have_posts()) : the_post();
$custom_fields = get_post_custom();

$my_date = the_date('', '', '', FALSE);
?>

We have a mini-sidebar that includes all the event details.

<div id="classDetails">

<?php echo nl2br($custom_fields['registration']['0']); ?>
<div><?php echo apply_filters('the_content', $custom_fields['requirements']['0']); ?></div>
</div>

nl2br is a neat little function that takes new lines and converts them into
tags.  We didn’t want to give full WYSIWYG control on this field, so running this ensures we output well formatted text.

The “requirements” field DID have WYSIWYG control, so running the WordPress filter here will add paragraph tags and such as needed.

Now, we need to display a couple of specially formatted dates and the time of the event.

<div class="class_date">

<?php echo date('l', strtotime($my_date)); ?>

<?php echo date('M j', strtotime($my_date)); ?>

<?php echo $custom_fields['time']['0']; ?></div>

Finally, we’ll look at the status variable and display some useful information to our users.

<div class="class_status">
<?php
if ($custom_fields['status']['0'] == "Seats Available") echo '
<span class="status_text">Seats still available: '.$custom_fields['cost']['0'].'</span>
Call to book this class: 760-242-2399

';
elseif ($custom_fields['status']['0'] == "Sold Out") echo '
<span class="status_text">Sold out</span>

';
?></div>

When we put it all together, we have:

<?php
if (have_posts()) : while (have_posts()) : the_post();
$custom_fields = get_post_custom();

$my_date = the_date('', '', '', FALSE);
?>
<h2><?php the_title(); ?></h2>
<div id="classDetails">

<?php echo nl2br($custom_fields['registration']['0']); ?>
<div><?php echo apply_filters('the_content', $custom_fields['requirements']['0']); ?></div>
<?php
if (is_user_logged_in()){
?>

<a href="/pdf/pdf.php?ID=<?php echo $post->ID; ?>"><img src="/wp-content/themes/shooters-theme/images/pdf.png" alt="pdf" />  Printable PDF</a>
<?php
}
?></div>
<div class="class_date">

<?php echo date('l', strtotime($my_date)); ?>

<?php echo date('M j', strtotime($my_date)); ?>

<?php echo $custom_fields['time']['0']; ?></div>
<?php the_content(__('(more...)')); ?>
<div class="class_status">
<?php
if ($custom_fields['status']['0'] == "Seats Available") echo '
<span class="status_text">Seats still available: '.$custom_fields['cost']['0'].'</span>
Call to book this class: 760-242-2399

';
elseif ($custom_fields['status']['0'] == "Sold Out") echo '
<span class="status_text">Sold out</span>

';
?></div>
<?php endwhile; else: ?>

<?php _e('Sorry, no posts matched your criteria.'); ?>
<?php endif; ?>

Our final requirement, Custom method to display each class as a flyer, goes beyond the scope of this writeup.  You can view our PDF solution that uses mPDF and a bunch of custom programming.

To get this running on your site, first create your HTML and then replace the static values with your custom fields from WordPress.  It may sound a little complex now, but once you have it up and running, you’ll see how simple it actually is.

If we were going to be displaying all past events, we would need some type of pagination plugin for pages… We’ll hold off on that for a future post. ;)

Questions? Bugs? Leave them in the comments.

2 Responses to Creating a custom upcoming events page in WordPress

  1. April 9, 2010 George

    Thanks useful tutorial :)

  2. June 3, 2010 Dave Leach

    Thanks so much for this easy to understand writeup! I was looking for a way to display a list of upcoming movies on my website and your solution worked like a charm. I really appreciate your taking the time to explain it for the benefit of others.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.