Hi there! This may help folks needing to add times to startDate and endDate and also timezone offset to get accurate local times in Google events when using the plugin, Events Manager. There are some errors and omissions in this file regarding this. Here’s our updated code section in event-schema/includes/class-event-schema-em.php:
date_default_timezone_set('America/Toronto');
$time_zone_offset = date("P");
$start_datetime = $start_date.'T'.$start_time.$time_zone_offset;
$end_datetime = $end_date.'T'.$end_time.$time_zone_offset;
$centralize_event = array(
"ID" => $event_id,
"name" => $name,
"description"=> $description,
"url" => $event_url,
"start_date" => $start_datetime,
"end_date" => $end_datetime,
"is_all_day" => $is_all_day,
"image" => $image_url,
);
]]>
Hi, Events Manager 6.4.2 now includes “Event Status” for Active and Cancelled events — will you be able to update the plugin to include this in the schema?
Regards,
David
Does this plugin work for recurring events?
When I am using it with Event Organiser, Google schema debug is only detecting schema info of the first occurrence of recurring events when I visit the event URL
]]>Hi,
I was wondering if plugin is compatible with The Events Calendar PRO.
Thanks!
]]>Hi,
When I open an event from the EventON calender, I get all the information I want.
But when an event shows up in Google, clicking on it results in opening the event itself, as shown in the link above. Title and description are not visible there.
How to solve this?
Best regards,
Marjon Warmerdam
Hi!
Could you extend the class for Events Manager for the event list using the following code?
<?php
/**
* Class for Events Manager
*
* @link https://xylusthemes.com/
* @since 1.0.0
*
* @package Event_Schema
* @subpackage Event_Schema/includes
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Event_Schema_EM {
// The Events Calendar Event Taxonomy
protected $taxonomy;
// The Events Calendar Event Posttype
protected $event_posttype;
// The Events Calendar Venue Posttype
protected $venue_posttype;
/**
* Initialize the class and set its properties.
*
* @since 1.0.0
*/
public function __construct() {
if ( defined( 'EM_POST_TYPE_EVENT' ) ) {
$this->event_posttype = EM_POST_TYPE_EVENT;
} else {
$this->event_posttype = 'event';
}
if ( defined( 'EM_TAXONOMY_CATEGORY' ) ) {
$this->taxonomy = EM_TAXONOMY_CATEGORY;
} else {
$this->taxonomy = 'event-categories';
}
if ( defined( 'EM_POST_TYPE_LOCATION' ) ) {
$this->venue_posttype = EM_POST_TYPE_LOCATION;
} else {
$this->venue_posttype = 'location';
}
$schema_options = get_option( ES_OPTIONS , array() );
if( !in_array( 'event_organizer', $schema_options ) ){
add_action( 'wp_footer', array( $this, 'render_event_structured_data' ) );
add_filter( 'em_events_output', array( $this, 'render_event_list_structured_data' ), 10, 2 );
}
}
/**
* Get Posttype and Taxonomy Functions
*
* @return string
*/
public function get_event_posttype(){
return $this->event_posttype;
}
public function get_venue_posttype(){
return $this->venue_posttype;
}
public function get_taxonomy(){
return $this->taxonomy;
}
/**
* Render ld+json schema for Event.
*
* @since 1.0.0
*/
public function render_event_structured_data($ao_event = null){
if( is_singular( $this->event_posttype ) || is_object($ao_event)){
global $event_schema, $wpdb, $post;
$event_id = is_object($ao_event) ? $ao_event->post_id : get_the_ID();
$start_date = get_post_meta( $event_id, '_event_start_date', true );
if( $start_date == '' ){
return;
}
$name = is_object($ao_event) ? get_the_title($ao_event->post_id) : get_the_title();
$description = is_object($ao_event) ? '' : $post->post_excerpt;
if( trim( $description ) == '' ){
$description = addslashes( preg_replace('/((\w+\W*){54}(\w+))(.*)/', '${1}', is_object($ao_event) ? $ao_event->post_content : $post->post_content) );
}
$event_url = is_object($ao_event) ? get_permalink($ao_event->post_id) : get_permalink();
$image_url = "";
if( has_post_thumbnail( $event_id ) ){
$image_url = get_the_post_thumbnail_url( $event_id , 'full' );
}
$is_all_day = get_post_meta( $event_id, '_event_all_day', true );
$start_date = get_post_meta( $event_id, '_event_start_date', true );
$end_date = get_post_meta( $event_id, '_event_end_date', true );
$start_time = get_post_meta( $event_id, '_event_start_time', true );
$end_time = get_post_meta( $event_id, '_event_end_time', true );
if( $is_all_day ){
$start_time = '00:00';
$end_time = '23:59';
}
$start_datetime = $start_date.'T'.$start_time;
$start_datetime = $end_date.'T'.$end_time;
$centralize_event = array(
"ID" => $event_id,
"name" => $name,
"description"=> $description,
"url" => $event_url,
"start_date" => $start_date,
"end_date" => $end_date,
"is_all_day" => $is_all_day,
"image" => $image_url,
);
$is_location_enabled = get_option( 'dbem_locations_enabled', false );
if( $is_location_enabled ){
$location_id = get_post_meta( $event_id, '_location_id', true );
$event_location = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix. "em_locations WHERE location_id = %d", $location_id ) );
if( ! empty( $event_location ) ){
$centralize_event['location'] = array(
"name" => isset( $event_location->location_name ) ? esc_attr( $event_location->location_name ) : '',
"telephone" => '',
"url" => '',
);
$address = array();
$address['street_address'] = isset( $event_location->location_address ) ? esc_attr( $event_location->location_address ) : '';
$address['address_locality'] = isset( $event_location->location_town ) ? esc_attr( $event_location->location_town ) : '';
$address['address_region'] = isset( $event_location->location_state ) ? esc_attr( $event_location->location_state ) : '';
$address['address_country'] = isset( $event_location->location_country ) ? esc_attr( $event_location->location_country ) : '';
$address['postal_code'] = isset( $event_location->location_postcode ) ? esc_attr( $event_location->location_postcode ) : '';
$centralize_event['location']['address'] = $address;
$event_lat = isset( $event_location->location_latitude ) ? esc_attr( $event_location->location_latitude ) : '';
$event_lon = isset( $event_location->location_longitude ) ? esc_attr( $event_location->location_longitude ) : '';
if( $event_lat != '' && $event_lon != '' ){
$centralize_event['location']['geo'] = array(
"latitude" => $event_lat,
"longitude" => $event_lon,
);
}
}
}
if( get_post_meta( $event_id, '_event_rsvp', true ) && get_option( 'dbem_rsvp_enabled', false ) ){
$emevent_id = get_post_meta( $event_id, '_event_id', true );
$event_tikets = $wpdb->get_row( $wpdb->prepare( "SELECT MAX(ticket_price) AS max_ticket, MIN(ticket_price) AS min_ticket FROM " . $wpdb->prefix. "em_tickets WHERE event_id = %d", $emevent_id ) );
if( !empty( $event_tikets ) ){
$offers = array();
$offers['url'] = $event_url;
if( $event_tikets->max_ticket == $event_tikets->min_ticket ){
$offers['high_price'] = $event_tikets->max_ticket;
$offers['price'] = $event_tikets->max_ticket;
}else{
$offers['price'] = $event_tikets->min_ticket;
$offers['low_price'] = $event_tikets->min_ticket;
$offers['high_price'] = $event_tikets->max_ticket;
}
$offers['price_currency'] = get_option( 'dbem_bookings_currency' );
$centralize_event['offers'] = $offers;
}
}
// Render it.
echo $event_schema->common->generate_ldjson( $centralize_event );
}
}
/**
* Render ld+json schema for Event-List.
*/
public function render_event_list_structured_data($as_output, $aa_events){
foreach($aa_events as $lo_event){
$this->render_event_structured_data($lo_event);
}
return $as_output;
}
}
Regards!
]]>Nothing in settings tab. Please see this image: https://imgur.com/vTQAEIH
I’ve used WordPress 5.4 and Yoast SEO
Hi
Now I’m moving to a new calendar plugin from Timely Calendar.
Currently I’m using Event SEO as well.
I’ve checked your plugin works with EventOn but not with Modern Event Calendar plugin.
Why?
Does it mean EventOn has worse Schema integration?
Please, give me a reason. It’s really important for my decision.
Thank you
]]>Hi, I’ve been using the plugin for a while with a site that lists a lot of local events and wondered if you would be adding support for the (optional) eventStatus, eventAttendanceMode, and previousStartDate.
I’m using Events Manager to manage the events and will be adding ‘custom event attributes’ (not sure if Events Manager will add native support) which might make matching the attributes and properties difficult, but I guess it would be easy to create a short tutorial (happy to help with this if required).
Details of the new properties can be found on Google https://developers.google.com/search/docs/data-types/event
Kind regards, David
]]>Hi I use Eventon but google test does not work. It says “,” o “}” is missing…
]]>When we pass Single quote in the location getting error Bad escape sequence in string.
]]>Hello Xylus,
I have test my event url https://halloweeneventsco.com/events/the-historic-stanley-day-tour-2019-07-29/ on Structured Data Testing Tool and i have got error https://search.google.com/structured-data/testing-tool?utm_campaign=devsite&utm_medium=jsonld&utm_source=event#url=https%3A%2F%2Fhalloweeneventsco.com%2Fevents%2Fmagic-fest%2F
can you please check and help me.Also i have used your plugin and how many days it takes to event show on google console?
Thanks
]]>Hi, just wondering if you’ve got any updates in regards to integration with Yoast’s new schema functionality.
]]>includes/class-event-schema-em.php, lines 110 and 111 have typos (they should be referencing start_datetime and end_datetime which are preventing times from being generated in the Events Manager case.
]]>I installed the Event Schema plugin 2 days ago. I’ve got an Eventon events calendar on my home page at https://www.karenlucasphoto.com/school, but my events are not showing on Google Search. However, the events calendar on https://karenlucasphoto.com/school/beginners-advanced-digital-photography-course/ does show the upcoming events in a Google Search.
How can I get the search to list events when it finds my home pgae?
How do you add location schema to events
]]>Plugin seems not to be functioning; does it need write permissions?
]]>I was able to successfully import 3 events from our Facebook Page, and Event Schema seems to see that I have installed “Import Facebook Events”, but I’m not sure how to verify that the event schema is being generated and published.
Where would I find the schema located?
Do I need to post it to Google using a tool of some kind so it gets indexed?
Maybe create a “How to use Event Schema for SEO” or something like that would be a helpful article.
]]>I’m not needing support, but I am waiting for the next version. So see this comment as a motivation to keep on programming! ?? I’m especially interested in AI1EC-support for all the different designs!
]]>Will this plugin work with your Import Facebook Events plugin?
]]>Hi there! Thanks for the great plugin. I use it with All-In-One Event Calender. It works well with the event-links, but the markup doesn’t show up on our start-page with the monthly view: https://bonn.jetzt. Is this expected behavior?
]]>Any plans to add support for Eventum?
]]>I installed and activated both Import Facebook Events and Event Schema / Structured Data: Google Rich Snippet Schema for Event plugins. After successfully importing a Facebook event, the event structured data is missing. Tested using the Google Structured Data Testing Tool.
The paid version shows the same screen shots as the free version. Is this a paid feature only? If so, what does the free plugin do?
]]>Hi! Beautiful plug-in!
Question: When I view the plugin in my plugin list it says: “Event Schema allows you to import Facebook ( facebook.com ) events into your WordPress site.” in the description. It doesn’t look like your plugin actually does that (I use Time.ly events). And I’d love for it to do that!! Is it just a typo?
Great job on the plugin!
]]>