Skip to main content

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:

Note: Unlike other common tutorials, this tutorial chooses 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 a 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 the Google Developer console. Below are the steps-by-steps screenshots to do that:
(Click left/right arrows to view next/prev slide)

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, 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 the functions are Ajax handlers to handle the request from the frontend.

Add frontend codes

The frontend code files are saved in the 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).

Comments

Popular posts from this blog

Create An Online Store Theme Used By MyCMS

MyCMS is an open-source Content Management System to generate static online shop website. You can use my hosting to input your products, or you can download the source codes and host it in your own server (running NodeJS). Please refer to my Github repo for the detailed installation instructions. This blog is a step-by-step tutorial that shows you how to create an online-shop theme. In this tutorial, it’s using my hosting to input the shop details and products. If you’re hosting the MyCMS by yourself, just change the domain name to yours will do. Introducing MyCMS Before making the theme, you’ll need to use MyCMS to configure the demo shop and input two demo products. MyCMS generates a static website via a theme. The generated static website is NO server program required. You can put the website files (HTML/CSS/JS) to any CDN, hosting. Shop Configuration You must prepare below settings Before using MyCMS: Setting Description Example Store name Your store name will be displayed in t

How I make a web-components based dynamic Javascript page at the top of Google Search

Introduction Everybody wants their website shown at the first position of Google search. SEO (Search Engine Optimization) is a big topic. I just helped my client's website shows the database records at the top search rankings (at least several Chinese generic keywords). See the three example questions all are listed at top ranking: Website background: My client's website  popa.qa  is a traditional Chinese Q&A site that lets members ask and answer questions. All answers and questions are storing in the database server. Step 1: Create The Project This blog illustrates the problems and the steps to fix that with project source codes. Below is the description of the basic project: NodeJS backend (server.js) Develop an API ( /get-database-records ) to simulate getting database records Web-components frontend (index.html) An example component IndexPage  make use of  LitElement to render database records To start the server type: npm start Then I check the webpage speed using th

Progressive Web App Wordpress Theme (Part 1/2)

After I read two articles: Progressive Web Apps Are The Next Big Thing and More Surprising Statistics About WordPress Usage . I decided to build a Wordpress theme which integrated Progressive Web Apps (PWA) to see how cool it is when two “Big Thing” mix together. TL;DR To avoid Too Long; Didn’t Read. I break the whole procedure into two blogs. In part 1, I will build a Progressive Web App in the local server. What PWA features to be built here? According to PWA wiki , the PWA will be progressive enhancements. The final webapp will be: Responsive design: I choose Bootstrap 4 because it’s mobile-first design. Contents retrieve from Wordpress CMS via REST API . It’s a natural way the App is developed in Javascript. Offline support: The PWA still can run and display the contents when no Internet connection. Installable on Android home screen: I w