Creating an 'Add to Calendar' button for NationBuilder events

Add a button to NationBuilder that transfers event data to Outlook, Google Calendar, Apple iCal, and Yahoo with one click.

An easy-to-use method for people to add events to the calendar of their choice is a great way to ensure people remember a future event. NationBuilder does not offer this feature in its pre-built themes, but luckily adding it is a breeze.

There are dozens of free calendar widgets out there. For this example, I'll be using the one at addtocalendar.com.

The widget consists of three components:

  1. The HTML that forms the button and holds the content.
  2. The CSS that styles the button.
  3. The Javascript that sends the button's content to the app, which sorts and maps event data to the desired calendar in a new tab.

To make it work on NationBuilder, we'll need to add a fourth component: Page and Event-specific Liquid code which will fill in the blanks with dynamic data unique to each event.

CSS

Let's begin by configuring the CSS. You can use the boilerplate styles featured on addtocalendar.com by pasting the stylesheet link below between the <head> tags of layout.html:  

<link href="http://addtocalendar.com/atc/1.5/atc-style-blue.css" rel="stylesheet" type="text/css">

But I would recommend pasting the relevant CSS directly in your main stylesheet: theme.scss. You can change the fonts and colors later to customize the style of the button and its links. 

JavaScript

Just as with the CSS, the necessary JavaScript can be loaded in multiple ways. The simplest is by pasting the following code somewhere in the <body> of the page, either in the main template at layout.html or in the event page template itself:

    <script type="text/javascript">(function () {
            if (window.addtocalendar)if(typeof window.addtocalendar.start == "function")return;
            if (window.ifaddtocalendar == undefined) { window.ifaddtocalendar = 1;
                var d = document, s = d.createElement('script'), g = 'getElementsByTagName';
                s.type = 'text/javascript';s.charset = 'UTF-8';s.async = true;
                s.src = ('https:' == window.location.protocol ? 'https' : 'http')+'://addtocalendar.com/atc/1.5/atc.min.js';
                var h = d[g]('body')[0];h.appendChild(s); }})();
    </script>

You can also create and upload your own atc.min.js file to the main Files section of your theme, then link to it in the <head> of layout.html. This is my preferred method. The link will look like this:

<script src="atc.min.js">

HTML + Liquid

With the CSS and JavaScript ready to go, we now turn to modifying our HTML templates. The first thing we need to do is to create a partial template that will hold the button's HTML framework. Partial templates are HTML files that can be used to display content from one page on another. Their filenames must begin with an underscore. Create a new file in your main website theme, and name it something like _addtocalendar.html

Paste the demo boilerplate HTML from addtocalendar.com into your new file, like this:

    <span class="addtocalendar atc-style-blue">
        <a class="atcb-link">Add to Calendar</a> <!-- You can change button title by adding this line -->
        <var class="atc_event">
            <var class="atc_date_start">2017-05-04 12:00:00</var>
            <var class="atc_date_end">2017-05-04 18:00:00</var>
            <var class="atc_timezone">Europe/London</var>
            <var class="atc_title">Star Wars Day Party</var>
            <var class="atc_description">May the force be with you</var>
            <var class="atc_location">Tatooine</var>
            <var class="atc_organizer">Luke Skywalker</var>
            <var class="atc_organizer_email">luke@starwars.com</var>
        </var>
    </span>

Now let's replace each variable with its equivalent as a Liquid output tag. You can find them all at http://nationbuilder.com/event_page_variables. Ignore "atc_timezone" for now. Use the page's url for the description so people can go back to it at a later date. You should be left with this:

    <span class="addtocalendar atc-style-blue">
        <a class="atcb-link">Add to Calendar</a> <!-- You can change button title by adding this line -->
        <var class="atc_event">
            <var class="atc_date_start">{{ page.event.local_start_at | date: '%m/%d/%Y %H:%M:%S' }}</var>
            <var class="atc_date_end">{{ page.event.local_end_at | date: '%m/%d/%Y %H:%M:%S' }}</var>
            <var class="atc_timezone">America/New_York</var>
            <var class="atc_title">{{ page.headline }}</var>
            <var class="atc_description">Check {{ page.full_url }} for the latest info.</var>
            <var class="atc_location">{{ page.event.venue_address.one_line }}</var>
            <var class="atc_organizer">{{ page.event.contact_name }}</var>
            <var class="atc_organizer_email">{{ page.event.contact_email }}</var>
        </var>
    </span>

The only variable we can't call in Liquid is the timezone name.. or at least I couldn't, after multiple attempts to use {{ page.event.local_start_at | date: '%z' }} to pass a UTC variable the app would accept proved fruitless, so let me know if you know a better alternative. 

You'll need to hit up addtocalendar.com, go to Event Data Options, and use the timezone dropdown to find out what time zone name applies to you. Since I'm on the East coast, I used "America/New_York". Be careful to enter the text exactly as it appears.

Once you have _addtocalendar.html prepped and ready for action, you'll need to plug it into an event page. To do so, pull up an event page template  (You can add the button to a single event, or change the main template for all events, usually named pages_show_event.html and pages_show_event_wide.html in your Theme files section) and plug in the following code wherever you want the button to render:

{% include "addtocalendar" %}

And there you go! If everything's correct, you'll see a button labelled "Add to Calendar" on your event page. Click it and a dropdown will appear listing several options. Selecting one should open up that calendar in a new tab and populate it with the event's information, or download an ics file. 

Putting the Button in Event Listings 

The method described above will only work when used on event landing pages, so what if you want to put your Add to Calendar button in the event listing on a NationBuilder calendar page or associate it with an upcoming event on the homepage widget?

These "teaser" pages are not full event landing pages.. they're partials that pull information from an event and display it elsewhere on the site, usually the main calendar. The main one used on most NationBuilder themes is _event.html, and since its Liquid uses a different syntax, the outputs we configured above won't work on it.

To make it work, we'll need to use Liquid to make our button change its outputs depending on where it's being used. Pull up _addtocalendar.html and paste the following Liquid at the top line before anything else:

{% if page.type_name == "Event" %}

Here we ask whether the page type is a full event landing page. The rest of the code should be underneath it. Skip to the end, at the very last line after everything else, and enter: 

{% else %}

Then enter an alternative HTML + Liquid that will work on partials like _event.html:

    <span class="addtocalendar atc-style-blue">
        <a class="atcb-link">Add to Calendar</a> <!-- You can change button title by adding this line -->
        <var class="atc_event">
            <var class="atc_date_start">{{ event.event.local_start_at | date: '%m/%d/%Y %H:%M:%S' }}</var>
            <var class="atc_date_end">{{ event.event.local_end_at | date: '%m/%d/%Y %H:%M:%S' }}</var>
            <var class="atc_timezone">America/New_York</var>
            <var class="atc_title">{{ event.headline }}</var>
            <var class="atc_description">Check {{ page.full_url }} for the latest info.</var>
            <var class="atc_location">{{ event.event.venue_address.one_line }}</var>
            <var class="atc_organizer">{{ event.event.contact_name }}</var>
            <var class="atc_organizer_email">{{ event.event.contact_email }}</var>
        </var>
    </span>

This code is almost identical to the block above, only the Liquid has been tweaked a bit, with "page" changed to "event". Now add closing tag at the very end to make it official:

{% endif %}

Now our Add to Calendar button "knows" its place in the universe and shifts its references accordingly. The final product should look like this. Go ahead and paste 

{% include "addtocalendar" %}

in _event.html, and any other partial that references an event, such as _homepage_widget.html, wherever you want the button to render. 

I use Google Tag Manager and Google Analytics to track the use of such buttons and determine which events are most popular. I have found that they are highly utilized on most sites that focus heavily on event management. People tend to click on Add to Calendar buttons more than they do formal RSVPs, so it's a good way to monitor your site's "lurkers" and strategize ways to engage them. Overall, I consider this an essential feature for most sites and try to incorporate it in every one that I make.