Creating events in WordPress has become second nature to us. But it wouldn’t have been so clear were it not for the incredible brain of Noel Tock. He wrote a tremendous tutorial series covering creating a calendar system that is actually usable by clients. Best of all, it doesn’t suffer from the bloat we typically see in other event calendar wordpress plugins.
Getting WordPress To Jive with CPT Events and exported into iCal
If you’re new to creating events via custom post types, Noel Tock’s series is well worth the read. He breaks down each section bit by bit. The sheer amount of other developers chiming in within the comments is enough to shed a tear.
Part 1 – Custom Post Types Events
Part 2 – Custom Post Types Events
Part 3 – Integrating iCal with Custom Post Type Events
Part three of this series was a revelation in how to get events to spit out into a format that’s usable by calendars such as Google Calendar, Outlook Cal, or iCalendar. Unfortunately, a few errors were preventing the calendar from working properly for me. Fortunately, like-minded developers gathered in his comments section to try to piece it back together.
My Minor Fixes to Noel Tocks Masterpiece
I compiled those fixes, and included a few of my own into this:
<?php // see: http://www.noeltock.com/web-design/wordpress/how-to-ical-with-custom-post-types/ for more info //add to functions.php: load_template( dirname( __FILE__ ) . '/lib/cpt-events-ical.php' ); function tf_events_ical() { // - start collecting output - ob_start(); // - file header - header('Content-type: text/calendar'); header('Content-Disposition: attachment; filename="ical.ics"'); // - content header - ?> BEGIN:VCALENDAR VERSION:2.0 PRODID:-//<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>//NONSGML Events //EN X-WR-CALNAME:<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?> – Events X-ORIGINAL-URL:<?php echo esc_url( home_url( '/' ) ); ?>/?feed=tf-events-ical X-WR-CALDESC:<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?> – Upcoming Events CALSCALE:GREGORIAN <?php // - grab date barrier - $today6am = strtotime('today 6:00') + ( get_option( 'gmt_offset' ) * 3600 ); //removed $limit in $querystr and set to 500 for the time being (originally: $limit = get_option('pubforce_rss_limit');) // - query - global $wpdb; $querystr = " SELECT * FROM $wpdb->posts wposts, $wpdb->postmeta metastart, $wpdb->postmeta metaend WHERE (wposts.ID = metastart.post_id AND wposts.ID = metaend.post_id) AND (metaend.meta_key = 'event_end' ) AND metastart.meta_key = 'event_end' AND wposts.post_type = 'base_events' AND wposts.post_status = 'publish' ORDER BY metastart.meta_value ASC LIMIT 500 "; $events = $wpdb->get_results($querystr, OBJECT); // - loop - if ($events): global $post; foreach ($events as $post): setup_postdata($post); // - custom variables - $custom = get_post_custom(get_the_ID()); $sd = $custom["event_start"][0]; $ed = $custom["event_end"][0]; // - grab gmt for start - $gmts = date('Y-m-d H:i:s', $sd); $gmts = get_gmt_from_date($gmts); // this function requires Y-m-d H:i:s $gmts = strtotime($gmts); // - grab gmt for end - $gmte = date('Y-m-d H:i:s', $ed); $gmte = get_gmt_from_date($gmte); // this function requires Y-m-d H:i:s $gmte = strtotime($gmte); // - Set to UTC ICAL FORMAT - $stime = date('Ymd\THis\Z', $gmts); $etime = date('Ymd\THis\Z', $gmte); // - item output - ?> BEGIN:VEVENT DTSTART:<?php echo $stime . "\n";?> DTEND:<?php echo $etime . "\n";?> SUMMARY:<?php echo the_title() . "\n"; ?> DESCRIPTION:<?php echo substr(get_the_excerpt(), 0,50) . "\n"; ?> END:VEVENT <?php endforeach; else : endif; ?> END:VCALENDAR <?php // - full output - $tfeventsical = ob_get_contents(); ob_end_clean(); echo $tfeventsical; } function add_tf_events_ical_feed () { // - add it to WP RSS feeds - add_feed('tf-events-ical', 'tf_events_ical'); } add_action('init','add_tf_events_ical_feed'); ?>
The Calendar fixes included:
- Changing the iCal title to pull the site title
- Use get_the_excerpt() to grab the excerpt without any markup
- Remove the $limit from the Querystr as I wasn’t using this custom meta field. A limit of 500 should suffice, but that can be changed if need be.
- Added the appropriate line breaks to ensure the ical file is formatted properly to work with Calendar programs.
When ran on my local machine, my .ICS file looks like this. (Feel free to open it in iCal to test it)
BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Test//NONSGML Events //EN X-WR-CALNAME:Test – Events X-ORIGINAL-URL:http://corbins-macbook-pro-2.local:5757//?feed=tf-events-ical X-WR-CALDESC:Test – Upcoming Events CALSCALE:GREGORIAN BEGIN:VEVENT DTSTART:20141002T060000Z DTEND:20141011T060000Z SUMMARY:Past event DESCRIPTION:Cras mattis consectetur purus sit amet fermentum. END:VEVENT BEGIN:VEVENT DTSTART:20141219T113000Z DTEND:20141015T230000Z SUMMARY:Test Event DESCRIPTION:Curabitur blandit tempus porttitor. Aenean eu leo END:VEVENT BEGIN:VEVENT DTSTART:20141115T060000Z DTEND:20141019T060000Z SUMMARY:Business Conference DESCRIPTION:Aenean eu leo quam. Pellentesque ornare sem lacini END:VEVENT BEGIN:VEVENT DTSTART:20141030T150000Z DTEND:20141101T050000Z SUMMARY:Country Music Festival DESCRIPTION:Aenean eu leo quam. Pellentesque ornare sem lacini END:VEVENT BEGIN:VEVENT DTSTART:20141031T150000Z DTEND:20141102T020000Z SUMMARY:Cross Month Event DESCRIPTION:Fusce dapibus, tellus ac cursus commodo, tortor ma END:VEVENT BEGIN:VEVENT DTSTART:20141209T060000Z DTEND:20141212T000000Z SUMMARY:A Food Festival DESCRIPTION:Aenean eu leo quam. Pellentesque ornare sem lacini END:VEVENT BEGIN:VEVENT DTSTART:20150102T000000Z DTEND:20150102T020000Z SUMMARY:Next Year Event DESCRIPTION:Cras mattis consectetur purus sit amet fermentum. END:VEVENT END:VCALENDAR
A huge thank you to Noel and the folks in the comments of part 3 for sharing this. It’s going to be a tremendous help in some upcoming event based projects!