Google Calendar Query Loop in Bricks

This Pro tutorial provides the steps to pull events from a specified public Google Calendar and output their names, dates & times and descriptions via a Bricks query loop.

This is yet another showcase of how powerful querying abilities of Bricks are.

Step 1

There are three ways in which authentication for Google Calendar API can be provided:

  • API key
  • OAuth 2.0
  • Service Account Key

In this tutorial, we shall use the API key method.

Go to the Google Cloud Platform Console and create an API key for the Google Calendar API.

The general outline is that you’d first create a Project, switch to it, go to “APIs and services”, click “Enable APIs and Services” button, search for calendar, click “Google Calendar API”, enable it, go to Credentials, create a credential of API key type to get the API key.

Step 2

Go to Google Calendar and create a new calendar named say, “Public Calendar”.

Add some events.

Go to calendar’s settings and make it public.

Note the calendar ID.

Step 3

Edit the Page where you would like to show the events with Bricks.

Add a Section and a Code element inside its Container.

This is a temporary step so you can see all the calendar data that’s in the response sent by Google Calendar API after we issue a request to it.

Paste this in the Code element:

<?php

$calendarId = 'c162eefe7d9ccc39b55bacf3c893b6d6244968a54e92fb16b01104e11ecf2e18@group.calendar.google.com';

$apiKey = 'AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe';

$request = wp_remote_get( "https://www.googleapis.com/calendar/v3/calendars/{$calendarId}/events?key={$apiKey}" );

$response = wp_remote_retrieve_body( $request );

$event_array = json_decode( $response, true );

print( "<pre>" . print_r( $event_array['items'], true ) . "</pre>" );

?>

Replace c162eefe7d9ccc39b55bacf3c893b6d6244968a54e92fb16b01104e11ecf2e18@group.calendar.google.com with your calendar ID.

Replace AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe with your API key.

If everything is alright, you should see the events info from the response data.

Ex.:

This should help you understand the code in the next step and tweak it to add any other data you may want to show in the query loop besides the event name, date and time and description.

You can delete this Section now (after perhaps taking a screenshot of the output) or later once you are done with the tutorial.

Step 4

Add the following in child theme‘s functions.php (w/o the opening PHP tag) or a code snippets plugin:

<?php 

/* Add new query type control to query options */
add_filter( 'bricks/setup/control_options', function ( $control_options ) {
    /* Adding a new option in the dropdown */
    $control_options['queryTypes']['google_calendar_events'] = esc_html__( 'Google Calendar' );

    return $control_options;
} );

/* Run new query if option selected */
add_filter( 'bricks/query/run', function ( $results, $query_obj ) {
    if ( $query_obj->object_type !== 'google_calendar_events' ) {
        return $results;
    }
    
    /* If option is selected, run our new query */ 
    if ( $query_obj->object_type === 'google_calendar_events' ) {
        $results = bl_run_new_gcal_query();
    }
    
    return $results;
}, 10, 2 );

/* Return results from our Google Calendar API */
function bl_run_new_gcal_query() {
    // Set your calendar ID here
    $calendarId = 'c162eefe7d9ccc39b55bacf3c893b6d6244968a54e92fb16b01104e11ecf2e18@group.calendar.google.com';

    // Set your API key here
    $apiKey = 'AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe';

    $request = wp_remote_get( "https://www.googleapis.com/calendar/v3/calendars/{$calendarId}/events?key={$apiKey}" );

    if ( is_wp_error( $request ) ) {
        return []; // Bail early on request error.
    }

    $response = wp_remote_retrieve_body( $request );

    $events_array = json_decode( $response, true );

    if ( empty( $events_array['items'] ) ) {
        return []; // Bail if no events found.
    }

    $event_objects = [];
    
    foreach ( $events_array['items'] as $event ) {
        $startDateTime = isset( $event['start']['dateTime'] ) ? $event['start']['dateTime'] : '';
        $endDateTime = isset( $event['end']['dateTime'] ) ? $event['end']['dateTime'] : '';

        // Create DateTime objects from the datetime string
        $start_datetime = new DateTime( $startDateTime );
        $end_datetime = new DateTime( $endDateTime );

        // Extract the date and time components
        $start_date = $start_datetime->format( 'l, j M Y' ); // Ex: Monday, 12 Feb 2024
        $start_time = $start_datetime->format( 'g:i a' ); // Ex: 6:30 pm

        $end_date = $end_datetime->format( 'l, j M Y' ); // Ex: Monday, 12 Feb 2024
        $end_time = $end_datetime->format( 'g:i a' ); // Ex: 6:30 pm

        // Is it a multi day event?
        $multi_day_event = $start_date !== $end_date;

        // Is it an all day event?
        $all_day_event = isset( $event['start']['date'] ) && isset( $event['end']['date'] );

        if ( $all_day_event ) {
            $time_string = 'All day event';
        } else {
            $time_string = "{$start_time} - {$end_time}";
        }

        if ( $multi_day_event ) {
            $datetime_string = "{$start_date} @ {$start_time} - {$end_date} @ {$end_time}";
        } else {
            $datetime_string = "{$start_date} . {$time_string}";
        }

		$event_objects[] = [
			'id' => isset( $event['id'] ) ? $event['id'] : '',
			'title' => isset( $event['summary'] ) ? $event['summary'] : '',
			'content' => isset( $event['description'] ) ? $event['description'] : '',
			'startdate' => $start_date,
            'starttime' => $start_time,
            'enddate' => $start_date,
            'endtime' => $start_time,
            'datetimestring' => $datetime_string,
			// ... Add other properties you need
		];
	}
    
    return $event_objects;
};

// Function to get the current looping object.
if ( ! function_exists( 'bl_get_loop_object' ) ) {
    function bl_get_loop_object(): array {
        $looping_query_id = BricksQuery::is_any_looping();

        if ( $looping_query_id ) {
            return BricksQuery::get_loop_object( $looping_query_id );
        }

        // fallback, this won't be the one that's output
        return [];
    }
}

Replace c162eefe7d9ccc39b55bacf3c893b6d6244968a54e92fb16b01104e11ecf2e18@group.calendar.google.com with your calendar ID.

Replace AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe with your API key.

We are setting each query loop object to have these properties with corresponding values pulled from the API response:

  • id
  • title
  • content
  • startdate
  • starttime
  • enddate
  • endtime
  • datetimestring

Step 5

Back in the Bricks editor, add a Section and inside its Container, set up a query loop.

Set the query type to Google Calendar.

For showing the event name:

{echo:bl_get_loop_object:array_value|title}

Event date:

{echo:bl_get_loop_object:array_value|datetimestring}

Event description:

{echo:bl_get_loop_object:array_value|content}

References

https://developers.google.com/calendar/api/v3/reference/events/list

https://wordpress.org/documentation/article/customize-date-and-time-format/