Author’s Note: I wrote a revised version of this post which explains a better way to manage and query event posts. Read it here.
The following was written right after WordPress 3.0 had come out and advanced meta data queries weren’t yet possible. This post explains how to create an events post by making the event date mirror the actual post date, which might still be useful to some folks.
You can download a child theme of Twenty Ten with all the code that has the code I describe here.
Warning: This code is a bit experimental. It’s more of a guide for developers and I can’t guarantee it will work in all situations. Please read the comments at the bottom to see issues other folks have had.
Explanation
First, you’ll need to set up an event post type (and, as always, I’ll send you to Justin Tadlock’s post if you want to learn more about how this works):
/**
* Enable Custom Post Types for Events
*/
// Registers the new post type and taxonomy
function devinsays_event_posttype() {
register_post_type( 'events',
array(
'labels' => array(
'name' => __( 'Events' ),
'singular_name' => __( 'Event' ),
'add_new' => __( 'Add New Event' ),
'add_new_item' => __( 'Add New Event' ),
'edit_item' => __( 'Edit Event' ),
'new_item' => __( 'Add New Event' ),
'view_item' => __( 'View Event' ),
'search_items' => __( 'Search Event' ),
'not_found' => __( 'No events found' ),
'not_found_in_trash' => __( 'No events found in trash' )
),
'public' => true,
'supports' => array( 'title', 'editor', 'thumbnail', 'comments' ),
'capability_type' => 'post',
'rewrite' => array("slug" => "events"), // Permalinks format
'menu_icon' => get_bloginfo('stylesheet_directory') . '/images/calendar-icon.gif', // Icon Path
'menu_position' => '5'
)
);
}
add_action( 'init', 'devinsays_event_posttype' );
Altering the “Publish Date” text
We’ll need to filter the text on the event custom post type edit page. So, instead of saying “Publish immediately” in the upper right- it’ll say “Event Date: [the current date]“. You also need a conditional, so this text only gets filtered on your new event post type.
Props to Peter Westwood for posting his code and explaining how to do this.
// Change the "Scheduled for" text on Event post types changing the translation
// http://blog.ftwr.co.uk/archives/2010/01/02/mangling-strings-for-fun-and-profit/
function devinsays_translation_mangler($translation, $text, $domain) {
global $post;
if ($post->post_type == 'events') {
$translations = &get_translations_for_domain( $domain);
if ( $text == 'Scheduled for: <b>%1$s</b>') {
return $translations->translate( 'Event Date: <b>%1$s</b>' );
}
if ( $text == 'Published on: <b>%1$s</b>') {
return $translations->translate( 'Event Date: <b>%1$s</b>' );
}
if ( $text == 'Publish <b>immediately</b>') {
return $translations->translate( 'Event Date: <b>%1$s</b>' );
}
}
return $translation;
}
add_filter('gettext', 'devinsays_translation_mangler', 10, 4);
Displaying Scheduled Posts
You should now have a working post type that allows you to set up events. However, I assume you’ll want to post events that are upcoming rather than ones that have already occurred. Since a future date will make the event post “scheduled”, we’ll need to add a bit of code to make scheduled posts appear instead of giving a 404 error to non logged in users. Here’s the code for that:
// Show Scheduled Posts
function devinsays_show_scheduled_posts($posts) {
global $wp_query, $wpdb;
if(is_single() && $wp_query->post_count == 0) {
$posts = $wpdb->get_results($wp_query->request);
}
return $posts;
}
add_filter('the_posts', 'devinsays_show_scheduled_posts');
Displaying Events in a Template
Everything should now be set up to create new events and view the posts separately. But what if you want to query those events from different page template AND only show the events that are coming up, rather than ones that have already expired? Well, simple. You just query your future event posts:
$args = array( 'post_type' => 'events', 'posts_per_page' => '10', 'post_status' => 'future', 'order' => 'DESC'); query_posts($args);
You can see the full code for this in the type-events.php template in the Events TwentyTen theme.
What do you think?
I know a lot of people are working on ways to do events well. Ideally a terrific plugin will come along that makes this all very easy. I just wanted to spur the process. If anyone has any comments or improvement for the code, please let me know.
And again, my sample Events TwentyTen theme can be downloaded here.
Does anybody know how to use something like this and include a link for save to calendar?
Very useful indeed !
I have a big issue on using it though : the custom taxonomies I registered, like “artists” or “location” tags, only lead to empty archive page when clicked, because they match unpublished/future custom posts (i.e. upcoming events). The “show_scheduled_posts” function works fine for displaying single posts, but how can I take care of the taxonomies results ?
Few lines of code which solved my problem :
add_action( 'pre_get_posts', 'on_pre_get_posts' );function on_pre_get_posts() {
global $wp_query;
if ( is_tax( array( 'artiste', 'salle' ) ) )
$wp_query->set( 'post_status', 'future' );
}
Slightly derived from there :
http://core.trac.wordpress.org/ticket/16233
Is there any chance you’ve had a go with the post rehaul? Or could you at least explain in short what to do with the date meta tag method?
How can I get my future events (only) to show up in the RSS feed?
Thanks a lot for this post! exactly what i was looking for.
greeting from berlin :)
Hi Devin,
I’m fairly certain it was yours & Bruce’s work on a symphony site that provided the insights needed when I was developing a calendar solution for a site last summer. I used the No Future Posts plugin and created posts for individual events, using the post date for the calendar date. Since the site was for a movie theater, there could be multiple instances of a post on a given day, so rather than use the post time I simply assigned a custom field to contain show time data. This didn’t solve the issue of multiple occurrences over several days, but given that the theater’s bookings were mainly single day programs or at most a week run, the problem was readily solved by making multiple posts with the same information, differing only in the data for the show time custom field.
For the home page, I modified the loop to only display posts that matched the current date, and there was a get_posts(); function to grab a limited number of future events that were tagged with ‘featured’ for display in a Coming Soon section. Multiple category-based events lists were created by duplicating and modifying the category page template.
I admit to not being a PHP master, so these workarounds have a bit of a drawback in that they need to managed, but a little more code refinement could help clean up the rough edges. Beyond editing the ‘featured’ tag, site maintenance is kept to a minimum, and the solution has the benefit of being very light on the query side.
Thanks for the inspiration and the plugin links! I too am looking forward to reading any further insights you have to offer on calendaring work.
Brandon
I have a need for reoccurence of the events. We have theatre webpage with repertoire. I’d like to have posts for performance description and events features for upcomming dates.
Two views are needed: 1) to view the dates and short descriptions of different events. 2) view of performance description and a list of all the dates of it in the future.
Very interesting method, thanks for sharing it.
The translation won’t work if you change the publish date since the “Scheduled for…” text is placed through AJAX. After a lot of trial and error, this snippet works for me:
add_action('admin_head', 'ilc_admin_head');function ilc_admin_head() {
global $wp_scripts;
//var_dump($wp_scripts); //had to check if this boy had the translation
$wp_scripts->localize('post', 'postL10n', array(
'publishOn' => __('Event date:'),
'publishOnFuture' => __('Event date:'),
'publishOnPast' => __('Event date:')
));
}
Your devinsays_translation_mangler function is still required. Otherwise, when the post editing screen first launches the text is not translated.
The long journey to find out about the translated strings went like this: I checked which function was triggered for .timestamp, the box with the date, and turned out to be updateText(), located in post.dev.js, which uses publishOn = postL10n.publishOnFuture; so it was a matter of finding out postL10n definition, which is located in script-loader.php, line 332 in WP 3.2.1. Finally, the global object is $wp_scripts, initialized in load-scripts.php, line 120. Damn that was long, I deserve a steak now.
Thanks for this man, it is very helpful.
Thanks for sharing this!
Hi all. I finally was able to make an update for this post. It takes a completely different strategy and makes use of the advanced meta queries that came out in WordPress 3.1. Read it here.