/ wordpress

Google Calendar Wordpress theme Steps by Steps

Introduction

This blog describes how to build a Wordpress theme which the frontend displays a calendar (using jQuery FullCalendar). The Wordpress as backend which the PHP codes communicate with Google Calendar (via Google API service account) to perform loading/saving event(s).

15-seconds short demo outcome video (no sounds):

System diagram of this tutorial:
Architecture

Note: Unlike other common tutorials, this tutorial choose Server-to-Server communication approach. This does NOT require users to authenticate and consent.

The Source Codes

You can download the source codes from this Github repo

Prerequisite

  1. WordPress 4.9+
  2. PHP 7.0+
  3. Composer 1.6+
  4. A Google Account

Initialize the backend project

First of all, you'll need to create the project directory. Link the directory to your WordPress theme directory (assume the WordPress is installed in /var/www/html). The Linux command:

$ mkdir google-calendar-wordpress
$ cd google-calendar-wordpress
$ ln -s $(pwd) /var/www/html/wp-content/themes/google-calendar-wordpress

From now on, the directory google-calendar-wordpress is the project root directory. Change to the directory and download the Google Calendar API via Composer:

$ cd google-calendar-wordpress
$ composer require google/apiclient:^2.0

Obtain the Google API Key

To access the Google Calendar, we need to obtain the API key from Google Developer console. Below are the steps-by-steps screenshots to do that:

Create a demo Google Calendar

As this blog title says, we'll manipulate the Google Calendar in our codes. So you'll need to create a new Google Calendar which can be accessed from our codes. To create a new calendar, below are the steps-by-steps screenshots:

Create Wordpress project

Follow the WordPress theme standard to create three files: style.css, functions.php and index.php. Mine style.css content is:

/*
Theme Name: Google Calendar Wordpress Theme
Theme URI: http://blog.simonho.net/
Author: the Simon Ho
Author URI: http://www.simonho.net/
Description: This is a Wordpress theme which provide simple booking. The frontend displays a full page of calendar using (jQuery FullCalendar). It allows visitor to create/delete events. The events will be synchronized to Google Calendar.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: gcalconcptbkgsys

This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned with others.
*/

The functions.php file content is:

<?php
?>

The index.php file content is:

<?php /* Template Name: FullCalendar */?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
  <head>
    <meta charset="<?php bloginfo( 'charset' ); ?>" />
    <title><?php wp_title(); ?></title>
    <meta http-equiv="pragma" content="no-cache" />
    <link rel="profile" href="http://gmpg.org/xfn/11" />
    <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />
    <?php if ( is_singular() && get_option( 'thread_comments' ) ) wp_enqueue_script( 'comment-reply' ); ?>
    <?php wp_head(); ?>
  </head>
  <body>
    <h1>Google Calendar WordPress Theme Demo</h1>
    <div id="calendar"></div>
    <?php wp_footer(); ?>
  </body>
 </html>

Now you can go to your WordPress admin. Activate this theme and visit the site. You should see a blank web page.

Add Google Calendar API codes

Inside the [admin-ajax.php](https://github.com/simonho288/google-calendar-wordpress/blob/master/admin-ajax.php), which is the code to manipulate the Google Calendar. The most important part is the Google Calendar API setup code:

...
function initGoogleCalendarApi() {
  $gapi = new Google_Client();
  $gapi->setAuthConfig(__DIR__ . '/service-account.json');
  $gapi->setApplicationName('Google Calendar Wordpress Theme');
  $gapi->addScope(Google_Service_Calendar::CALENDAR);
  $gcal = new Google_Service_Calendar($gapi);
  return $gcal;
}
...

As you can see, it loads the service account API keys, setup the scope and initialize the Google Calendar object. (For full docs, please click here). The rest of functions are Ajax handlers to handle the request from frontend.

Add frontend codes

The frontend code files are saved in assets directory. WordPress loads those files via wp_enqueue_scripts. Below is the outline of enqueue.php file:

<?php

function enqueue_style_func() {
    // Setup the CSS files
    ...
}
add_action('wp_enqueue_scripts', 'enqueue_style_func');

function enqueue_script_func() {
    // Setup the JS files
    ...
}
add_action('wp_enqueue_scripts', 'enqueue_script_func');

Frontend libraries

We'll use jQuery FullCalendar to render the calendar on our site. Moment.js for date/time manipulating. Below is the code fragment of main.js for FullCalendar initialization:

...
/**
 * Initialise the FullCalendar by adding the global events array.
 */
function initCalendar() {
  $('#calendar').fullCalendar({
    viewRender: onViewRender, // when week changed...
    defaultView: 'agendaWeek',
    dayClick: onDayClick, // when a time slot clicked...
    eventClick: onEventClick, // when an event clicked...
    events: events, // Event objects array to be displayed
    editable: true
  });
}
...

Frontend/backend communication

As I mentioned above, the frontend interactive with users. And the backend accesses the Google Calendar. The communication between that is Ajax. Below is the frontend code fragment from main.js:

...
/**
 * Invoke admin-ajax.php via Ajax to get events from Google Calendar
 */
function ajaxGetEvents(dateStart, dateEnd) {
  var postData = {
    dateStart: dateStart,
    dateEnd: dateEnd,
    action: 'get_events'
  };
  return $.ajax({
    type: 'POST',
    dataType: 'json',
    url: php_data.ajaxUrl,
    data: postData
  });
}
...
function ajaxPutAnEvent(event) {
  ... // The code similar to above ajaxGetEvents()
}

function ajaxDelEvent(eventId) {
  ... // The code similar to above ajaxGetEvents()
}

Below is the corresponding backend code fragment from admin-ajax.php:

...
function get_events() {
  $dateStart = $_POST['dateStart'];
  $dateEnd = $_POST['dateEnd'];
  ... // Google API manipulation
}
add_action('wp_ajax_get_events', 'get_events'); // Support within Wordpress admin, and
add_action('wp_ajax_nopriv_get_events', 'get_events'); // support without Wordpress admin
...

Calendar manipulation

Below are the code fragments to manipulate Google Calendar API. The full code file is in admin-ajax.php.

To get Google Calendar event(s):

function get_events() {
  $dateStart = $_POST['dateStart'];
  $dateEnd = $_POST['dateEnd'];

  $gcal = initGoogleCalendarApi();

  // Query the Google Calendar. API doc:
  // https://developers.google.com/calendar/v3/reference/events/get
  $opts = array(
    'maxResults' => 2500, // max results allowed by Google Calendar
    // 'orderBy' => 'startTime',
    'singleEvents' => TRUE,
    'timeMin' => $dateStart,
    'timeMax' => $dateEnd
  );
  $events = $gcal->events->listEvents(CALENDAR_ID, $opts);

  $return = array( // The Ajax return value
    'result' => TRUE,
    'events' => array()
  );

  // Handling the pagination from the Google Calendar results
  while (true) {
    foreach ($events->getItems() as $event) {
      array_push($return['events'], array(
        '_id' => $event->getId(),
        'title' => $event->getSummary(),
        'start' => $event->getStart()->getDatetime(),
        'end' => $event->getEnd()->getDatetime()
      ));
    }

    // Handling pagination
    $pageToken = $events->getNextPageToken();
    if ($pageToken) {
      $opts = array('pageToken' => $pageToken);
      $events = $gcal->events->listEvents(CALENDAR_ID, $opts);
    } else {
      break;
    }
  }

  echo json_encode($return); // Return the result to frontend
  wp_die();
}

To save an event to Google Calendar:

function put_event() {
  $jsEvent = $_POST['event']; // Event object from frontend
  $event = new Google_Service_Calendar_Event(array(
    'summary' => $jsEvent['title'],
    'description' => 'Created by Google Calendar Wordpress theme demo',
    'start' => array(
      'dateTime' => $jsEvent['start']
    ),
    'end' => array(
      'dateTime' => $jsEvent['end']
    )
  ));

  $gcal = initGoogleCalendarApi();

  // Save the event to Google Calendar. The doc:
  // https://developers.google.com/calendar/v3/reference/events/insert
  $result = $gcal->events->insert(CALENDAR_ID, $event);

  $return = array(
    'result' => TRUE,
    'event_id' => $result['id']
  );
  echo json_encode($return); // Return the result to frontend
  wp_die();
}

To delete an event from Google Calendar:

function del_event() {
  $event_id = $_POST['event_id']; // Event object from frontend

  $gcal = initGoogleCalendarApi();

  // Google Calendar delete event doc:
  // https://developers.google.com/calendar/v3/reference/events/delete
  $result = $gcal->events->delete(CALENDAR_ID, $event_id);

  $return = array(
    'result' => TRUE
  );
  echo json_encode($return); // Return the result to frontend
  wp_die();
}

Conclusion

You can develop a powerful App by extending this to add Bootstrap in the frontend and save the events to WordPress custom table (custom post type) and custom field (post meta).