Blog

Making Timezone Conversions Easily Accessible for Online Events

When you hold a seminar or conference online, you make it available to the world — and even if you were compelled to take it online by COVID-19, you ought to take advantage of that fact. That means attracting people from many timezones, not just the timezone the organizers happen to be located in. Yet even many professional events, fail to make this easy — expecting people to be able to do the mental math to calculate the difference from EST to PST to GMT and beyond.

With RSVPMaker’s Show in my timezone button, the computer can do the math for them. Recent enhancements allow you to use it in a broader variety of situations.

Timezone conversion animation
This event is advertised in U.S. Eastern time, but viewers can see the entire schedule translated into their own local timezone.

The example here is from VTM CON on Dec. 5, 2020, a conference for speakers and leaders I’m helping publicize. I was a founder of Online Presenters Toastmasters, one of the sponsors, which has been using the Show in my timezone button on its event notices for years, but in this case we wanted to show the entire schedule of events for the conference in a table. The times for EST, PST, and UTC were entered by hand, but we wanted to make the listing equally accessible to people in other timezones.

You can see it live and register for the event. If you attend, be sure to say hello.

For the VTM CON example, I’ve added the CSS class tz-table2 to the an HTML table created with the WordPress block editor. This tells my script the data to be converted is in the second column of the table. The available classes are tz-table1, tz-table2, and tz-table3 for the first second and third columns of a table.

You can also apply tz-convert to a table or another container block such as a paragraph, heading, div, or span element. When tz-convert is applied to a table, the script searches for any content formatted like a time (either 1:00 PM or 13:00). The data to be converted should be the only content in the table cell or other container targeted.

In the WordPress editor, you can add a class to any block of content by selecting Advanced in the sidebar panel for that block type.

Screenshot of where to enter an HTML class in the WordPress editor
Adding a class to a table

Using tz-convert for my table would be fine if it only contained times in EST, but in my example it would also mess with the times given for PST and UTC. Using tz-table2 avoids that issue.

For those interested in the technical details, I’ve provided an HTML / JavaScript example at the end of this post that could be used outside of WordPress or RSVPMaker.

Timezone Conversion for the RSVPMaker Schedule Block

Animation showing the RSVPMaker Schedule block
Timezone conversion for the RSVPMaker Schedule block

The timezone conversion feature also works with the RSVPMaker Schedule listing, which was introduced several versions ago as an alternative to the RSVPMaker Upcoming schedule listing.

Here, the idea is that each session of the conference has been modeled as its own RSVPMaker event. The RSVPMaker Schedule block includes options that allow you to limit the listing by start and end date and by the RSVPMaker Event Type (similar to a category for a blog post).

Rather than showing the full date and time at the start of each post, RSVPMaker shows the date just once for each event falling on that date, followed by the start time, the event title, and the content of the event. Within each event post, you can use the more tag to specify content that should only be displayed if the user clicks Read More — making the schedule easier for the viewer to scan quickly.

Screenshot: settings for the RSVPMaker Schedule block
RSVPMaker Schedule block settings

The tz-convert tag is automatically added to the times in an RSVPMaker Schedule display, so that’s a detail you don’t have to worry about. Just toggle on Display “Show in my timezone” in the block settings to activate this feature.

If you’re a user of the software, but not a programmer, you can stop reading now. The next section is just for other coders.

HTML/JavaScript Code Example

Here is a working example of my timezone table example with some of the complexities specific to my plugin stripped away. JavaScript knows the viewer’s timezone as long as that person’s computer clock is set correctly, so there is no need to ask for it.

The script takes advantage of the fact that JavaScript can also parse a datetime string that includes a timezone into a universal timestamp, representing it in memory as in integer. When you then as the script to display the time, it shows it relative to the user’s own timezone.

Most of the necessary information, such as the original datetime and timezone, is included as attributes on the Show in my timezone button. The rest of the script uses JQuery selectors to target the HTML classes I’ve designated for data that can be converted.

<!DOCTYPE html>
<html lang="en-US" class="no-js no-svg">
<head>
<meta charset="UTF-8">
<title>Timezone Conversion Demo</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h3 class="dateblock"><span class="event-date">Saturday December 5, 2020</span> <span class="event_time">8:15 AM</span> EST</span></h3>
<div id="timezone_converted"></div>
<div class="rsvpcalendar_buttons"><button class="timezone_on" datetime="2020-12-05 08:15:00" timezone="EST">Show in my timezone</button></div>
<p>Click the button above to see the times converted for your timezone (based on your computer clock).</p>
<figure class="tz-table2">
<table><tbody>
<tr><td>PST</td><td>EST</td><td>UTC</td><td>Event</td><td>Coordinators</td></tr>
<tr><td>5:15&nbsp;AM</td><td>8:15&nbsp;AM</td><td>1:15&nbsp;PM</td><td>Warm up / Entry into event</td><td>Nik Lakhani</td></tr>
<tr><td>6:00&nbsp;AM</td><td>9:00&nbsp;AM</td><td>2:00&nbsp;PM</td><td>Welcome to VTM Conference</td><td>Lois Margolin DTM / Nik Lakhani</td></tr>
<tr><td>6:10&nbsp;AM</td><td>9:10&nbsp;AM</td><td>2:10&nbsp;PM</td><td><a href="https://vtm.toastmost.org/speaker-linda-marie-miller/">WORKSHOP &#8211; Linda-Marie Miller</a></td><td>Mathilde Fischer DTM</td></tr>
<tr><td>7:00&nbsp;AM</td><td>10:00&nbsp;AM</td><td>3:00&nbsp;PM</td><td>Break</td><td></td></tr>
<tr><td>7:15&nbsp;AM</td><td>10:15&nbsp;AM</td><td>3:15&nbsp;PM</td><td><a href="https://vtm.toastmost.org/rsvpmaker/evaluation-contest/">Evaluation Contest</a></td><td>Carol Prahinski DTM PID / Lukas Calafell</td></tr>
<tr><td>8:45&nbsp;AM</td><td>11:45&nbsp;AM</td><td>4:45&nbsp;PM</td><td>Break</td><td></td></tr>
<tr><td>9:00&nbsp;AM</td><td>12:00&nbsp;PM</td><td>5:00&nbsp;PM</td><td>Result and Interview with Winner</td><td>Carol Prahinski, DTM PID</td></tr>
<tr><td>9:05&nbsp;AM</td><td>12:05&nbsp;PM</td><td>5:05&nbsp;PM</td><td><a href="https://vtm.toastmost.org/roger-courville/">WORKSHOP &#8211; Roger Courville</a></td><td>Mac Whyte</td></tr>
<tr><td>9:55&nbsp;AM</td><td>12:55&nbsp;PM</td><td>5:55&nbsp;PM</td><td>Break</td><td></td></tr>
<tr><td>10:10&nbsp;AM</td><td>1:10&nbsp;PM</td><td>6:10&nbsp;PM</td><td><a href="https://vtm.toastmost.org/speaker-derrick-trimble/">WORKSHOP &#8211; Derrick Trimble</a></td><td>Louis Brown DTM</td></tr>
<tr><td>11:00&nbsp;AM</td><td>2:00&nbsp;PM</td><td>7:00&nbsp;PM</td><td>Break</td><td></td></tr>
<tr><td>11:15&nbsp;AM</td><td>2:15&nbsp;PM</td><td>7:15&nbsp;PM</td><td><a href="https://vtm.toastmost.org/rsvpmaker/table-topics-contest/">Table Topics Contest</a></td><td>Carol Prahinski DTM PID / Lukas Calafell</td></tr>
<tr><td>12:15&nbsp;PM</td><td>3:15&nbsp;PM</td><td>8:15&nbsp;PM</td><td>Break</td><td></td></tr>
<tr><td>12:30&nbsp;PM</td><td>3:30&nbsp;PM</td><td>8:30&nbsp;PM</td><td>Result and Interview with Winner</td><td>Carol Prahinski, DTM PID</td></tr>
<tr><td>12:35&nbsp;PM</td><td>3:35&nbsp;PM</td><td>8:35&nbsp;PM</td><td><a href="https://vtm.toastmost.org/speaker-fursey-gotuaco/">WORKSHOP &#8211; Fursey Gotuaco</a></td><td>Natalie Thomas</td></tr>
<tr><td>1:25&nbsp;PM</td><td>4:25&nbsp;PM</td><td>9:25&nbsp;PM</td><td>Break</td><td></td></tr>
<tr><td>1:40&nbsp;PM</td><td>4:40&nbsp;PM</td><td>9:40&nbsp;PM</td><td><a href="https://vtm.toastmost.org/marquesa-pettway-discover-your-zoom-speaker-brand/">WORKSHOP &#8211; Marquesa Pettway</a></td><td>Ilda Kuleba</td></tr>
<tr><td>3:30&nbsp;PM</td><td>5:30&nbsp;PM</td><td>10:30&nbsp;PM</td><td>Thanks and credits</td><td>Lois Margolin DTM / Nik Lakhani</td></tr>
<tr><td>3:40&nbsp;PM</td><td>5:40&nbsp;PM</td><td>10:40&nbsp;PM</td><td>END OF EVENT</td><td></td></tr>
</tbody></table>
</figure>
<script>
$('.timezone_on').click( function () {
var datetime = $(this).attr('datetime');
var event_tz = $(this).attr('timezone');
var localdate = new Date(datetime+' '+event_tz);
localstring = localdate.toString();
$('#timezone_converted').html(localstring);
var match = localstring.match(/\(([^)]+)/);
var timeparts = datetime.split(' ');
var newtime;
var timecount = 0;
$('.tz-convert, .tz-convert table tr td, .tz-table1 table tr td:first-child, .tz-table2 table tr td:nth-child(2), .tz-table3 table tr td:nth-child(3)').each(
function () {
celltime = this.innerHTML.replace('&nbsp;',' ');
//if celltime contains time but not more html
if((celltime.search(/\d:\d\d/) >= 0) && (celltime.search('<') < 0)) {
timecount++;
newtime = timeparts[0]+' '+celltime+' '+event_tz;
console.log(newtime);
ts = Date.parse(newtime);
if(!Number.isNaN(ts)) //verify string parses to time
{
localdate.setTime(ts);
newtime = localdate.toLocaleTimeString().replace(':00 ',' ');//get time for user's locale, stripping off seconds
this.innerHTML = newtime;
$(this).css('font-weight','bold');
}
}
}
);//end tz_convert each
var checkrow = true;
$('.tz-table1 table tr td:first-child, .tz-table2 table tr td:nth-child(2), .tz-table3 table tr td:nth-child(3)').each(
function() {
if(checkrow && (this.innerHTML != '') && (this.innerHTML.search(':') < 0) ) // if this looks like a column header
this.innerHTML = '<strong>Your TZ</strong>';
checkrow = false;
}
);
});
</script>
</body>
</html>

The code sample is not identical to the code used in RSVPMaker, which includes PHP to pull dates, times, and other data from the the WordPress database. Complete code is on Github at https://github.com/davidfcarr/rsvpmaker

Patch for Security Issue (7.8.5)

Updated: August 20, 2020

RSVPMaker is back online in the WordPress repository, following a fix to one potentially serious security issues and the implementation of other updates required by the wordpress.org plugins review team. Please update ASAP if you are running a version earlier than 7.8.5.

https://wordpress.org/plugins/rsvpmaker/


RSVPMaker has been temporarily removed from the wordpress.org repository because of a SQL Injection vulnerability in some old code. I have provided a patch, which the powers that be are reviewing. Meanwhile, I’ve made it available here [link removed].

I apologize for this potentially serious error.

Updates should be available through the plugin repository again soon.

If you’re running WordPress 5.5, it’s now possible to update a plugin using a ZIP file. The system will tell you there is already an existing plugin directory for RSVPMaker then prompt you to confirm that you want to update to the uploaded version.

Updated Admin Bar Navigation Between Events, Confirmations, Reminders, Forms, and Templates

RSVPMaker uses the black admin bar that appears at the top of the page when you are logged in to provide links to related documents and settings screens.

Because the WordPress full screen (distraction free) editor prevents the display of that menu, it’s now disabled by default when you are editing RSVPMaker posts. This navigation is important to allow you to navigate from an event post for a specific date to the event template it was based on. Recent releases have made it easier to see whether the registration form and the confirmation message are specific to the event you are looking at, as opposed to being the default version from your settings, or a version inherited from the event template.

The New option you click on for a new p0st or page lets you create an individual RSVP Event, a New Event Template, or Create/Update events based on a template you’ve defined.

Here are some of those variations.

If an event currently uses the default confirmation message for your site, you can click on the Confirmation Message (Default) link to edit the default version. Alternatively, you can click on the Customize link to create a version specific to this one event.
In this example, the messages have been inherited from a template. The form is the default (meaning the template also references the default version).
In this example, the confirmation and reminder messages as well as the form have all been customized. You can tell because even though it’s based on a template, there are no links prompting you to customize those items.

These options appear under the Edit RSVP Event menu when you are viewing an event on the public site. When you are in the edit, working with event content, these links appear with RSVP / Event Options as the top level menu item.

When you are editing a message or form related to an event, the menu changes again to provide links back to Edit Event and View Event, along with the submenu options.

Links from a form to its parent event.

Finally, here are the new improved options under the New menu. Create / Update links will be provided for any templates you have defined.

New event, versus new template, or Create / Update a series of events based on a template.

Allow Event Submissions from Website Visitors

If you run a website for a community of people who would like to be able to post events occasionally — but not often enough that you need to provide them with an author or contributor password — you can allow them to submit events for review by your website’s team of editors.

An example is shown below. This form can be added to any post or page using the RSVPMaker Event Submission editor block or the [rsvpmaker_submission] shortcode. For security reasons, event descriptions are limited to bold, italic, and link formatting. Any other HTML or script code is filtered out.

When a website visitor completes the form, an email notification is sent to the list of people you specify (either in your default settings or the block settings). RSVPMaker event posts are saved as drafts but not published until a website editor approves them.

Optionally, you can prompt users to include a timezone in addition to date and time. This is important for online events and events across many geographies, but not necessary for a website advertising local community events.

You can try the user experience here.

Event Title:

Day Year

Choose a city in the same timezone as you.
If you want your contact information to be published as part of the event listing, also include it in the description below.

Event Details

Here is what the block looks like in the editor.

RSVPMaker Event Submission editor block

My experience from running community websites is that I'd rather give people a password if they are posting events regularly, partly because I want them to be able to make updates when event details change.

On the other hand, plenty of people who might have something good to share are reluctant to accept the burden of having to remember another password -- and I can't blame them. This is a way of encouraging more participation and building a more complete calendar for whatever community you serve.

Update: Release 7.7.5 adds support for Google reCAPTCHA to combat form spam. The reCAPTCHA credentials must be entered on the RSVPMaker Settings screen.

Sending Confirmation Only After Payment, for Example with the Link for an Online Event

There are now 2 different confirmation messages you can configure in RSVPMaker, one for the initial registration and the other displayed only after payment when you are charging for an event. One scenario: you’re charging for an online class or webinar and do not want to share the link until after payment is collected.

You can test it right now by signing up for the Google Photos workshop my friend and client Chris Guld is taking registrations for.

Setting the Payment Confirmation options.

By default, RSVPMaker sends a confirmation email message immediately after an event registration is recorded. However, you can now change that to say the confirmation email should only be sent after payment is confirmed.

Continue reading “Sending Confirmation Only After Payment, for Example with the Link for an Online Event”

Introducing the Daily Schedule Event Listing Block, with a Conference Demo

One of the new editor blocks available in RSVPMaker is RSVPMaker Schedule, an alternative to the calendar-style presentation meant to let you display a series of related events such as sessions within a conference program.

You can see it at the conference schedule demo site I’ve created, from which this screen shot is taken. The demo is based on a live implementation for the Toastmasters District 47 annual conference (which this year turned into a virtual event).

WordPress enthusiasts might consider this as a way of sharing a WordCamp event schedule.

The setup for the conference schedule demo is that there is one RSVPMaker event post that serves as the registration page for the entire weekend event. Each conference session is then modeled as its own RSVPMaker event. As displayed within the RSVPMaker Schedule listing, the sessions of the individual presenters are grouped by day, with the time that they are speaking shown as part of the session headline.

Continue reading “Introducing the Daily Schedule Event Listing Block, with a Conference Demo”

3 Confirmation Message Design Examples

Here are examples of designs created using techniques laid out in the blog post Styling Your Confirmation Messages and Broadcast Emails. RSVPMaker now provides the flexibility to style confirmation messages for different events differently.

White on Black

Here’s the black background confirmation message for a pirate party. This design allows me to specify styling on the RSVP button (Update RSVP in the case of a confirmation message) differently from the one used elsewhere on my website.

white on black email confirmation
Confirmation with a black background and white-on-black RSVP Button

White on Black Email Template

Using Gutenberg Columns in the Template

One technique for creating an template layout is to rough out the design in the WordPress editor, then copy the resulting HTML and elements such as shortcodes and dynamic Gutenberg blocks into the body of an email template.

Here, I have created a 2-column layout in the editor and a centered image to appear beneath the columns. The left column contains the [rsvpmaker_email_content] shortcode for dynamically generated content such as confirmation messages. The right column contains a heading block, followed by the latest-posts block to display the latest blog posts (where the idea is to encourage the person who has registered for an event to explore other website content).

Note: I had to use several hacks to make the two columns display acceptably on a mobile email client:

.wp-block-column {max-width: 50%}
.rightmain {padding: 10px;background-color:  #191D6C; color: #EEEEEE; height: 95%; }
.rightmain a {color:#FFFFFF; font-weight: bold; display: block; margin-bottom: 10px; margin-left: -30px;}

See the explanation of columns and CSS inlining.

Using Gutenberg columns to define a sidebar with latest posts.

Adapted from a MailChimp Sample

You can use a sample template provided by MailChimp, or created using MailChimp’s design tools, as the basis for a template you can use within the RSVPMaker mailer tool — including messages RSVPMaker handles itself, such as confirmation messages, as well as messages to be submitted to MailChimp via their API.

For this example, I started with a MailChimp sample design for a fictional gallery promoting a featured exhibit. I then turned it into an RSVPMaker confirmation email template suitable for being used in conjunction with a gallery talk event.

Gallery talk template, based on a MailChimp sample design

MailChimp uses nested tables for its basic layouts, then adds CSS on top tagged to different table cells.

The process of adapting the MailChimp template to work with RSVPMaker follows this pattern:

Exporting HTML from MailChimp
  • Use the Export as HTML option in MailChimp to get the code for one of the templates in your account that you want to use.
  • Place the [rsvpmaker_email_content] shortcode in the table cell where dynamically generated content such as your confirmation message should appear.
  • Add CSS as necessary to make your content look good in the template.
  • Alter MailChimp’s CSS as necessary to allow you to achieve the effects you want. I had to remove some of the default MailChimp code for link styling to get the RSVP button to display properly.

Gallery Event Template

Here is the original MailChimp sample design I started with:

Styling Your Confirmation Messages and Broadcast Emails

The latest update to RSVPMaker focuses on more design freedom and better consistency for confirmation messages, reminder messages, and email broadcasts.

This push was inspired in part by a recent post on the SendGrid blog, How to Send On-Brand Confirmation Emails (+ Examples). Having noticed some shortcomings in the formatting of RSVPMaker email messages (which were annoying me as much as anyone), this project had been on my todo list anyway. The examples in SendGrid’s article nudged me to put it at the top of the list.

Here’s an example of a confirmation message for a wedding, created using these new capabilities, with the correct formatting for a section laid out using the Gutenberg columns block and a centered image below the spot where the registration details are included:

A styled confirmation email
Continue reading “Styling Your Confirmation Messages and Broadcast Emails”

How I Learned to Create a Gutenberg Sidebar for Editing Post Metadata (Tips for WordPress Plugin Developers)

More than a year after releasing the first version of RSVPMaker with support for Gutenberg (the WordPress “block editor” introduced with 5.0), I now have an editor sidebar implementation I’m pretty happy with.

In the process, I learned more than I ever wanted to know about the WordPress Data API for JavaScript — and frankly more than I needed to know for the relatively simple thing I wanted to accomplish. I just wanted to update my old PHP-based UI for getting and setting post metadata to work in Gutenberg. The problem is not just insufficient documentation, but overwhelming documentation that can lead you in a wrong direction.

What you see below is a composite image of 2 screenshots.

What you see on the left are the most basic RSVPMaker settings (when does the event start and end? and are we collecting RSVPs?) as they’ve been added to the Document tab of the standard Gutenberg sidebar. I do that to make these basic elements of editing an event date as accessible as possible.

The insert on the right shows an additional sidebar, specific to RSVPMaker, that I can get to by clicking the calendar icon at the top of the screen. This additional sidebar provides access to a longer list of RSVPMaker settings: not just date and time, but also the email address to send registration notifications to, whether there is a maximum number of registrations to be accepted, and so on.

There are still a few more complex settings, such as those for event pricing online payments, where I direct users to a separate RSVP / Event Options screen. But I want them to be able to accomplish most tasks without delivering the editor.

The designers and developers behind the Gutenberg UI recommend providing a “distraction free” editing environment that minimizes the use of the old “metaboxes” at the bottom of the content editing window, which used to be a standard for WordPress plugin design. I also found that the JavaScript functions in my old metabox code seemed to clash with Gutenberg, so I got rid of metaboxes some time ago. But making those same capabilities available in a Gutenberg sidebar, rather than a metabox has proven challenging.

Gutenberg represents a steep learning curve for those developers who learned plugin programming in PHP and are now asked to master at least the basics of the React JavaScript framework and the Gutenberg component library. I hope that we will eventually be provided with some easier ways of handling common needs like setting the metadata of a post from within the Gutenberg UI.

Meanwhile, here are my tips on how to cope with the current state of things.

Continue reading “How I Learned to Create a Gutenberg Sidebar for Editing Post Metadata (Tips for WordPress Plugin Developers)”

Background Loading RSVPMaker Event Listings From Any Site To Any Site

Using the new widget and/or the new Gutenberg block that have been added to RSVPMaker 6.4.2, you can display a listing of events that will be dynamically loaded from your own site or any other site that implements RSVPMaker. This feature uses JavaScript and RSVPMaker API endpoints to fetch a listing of events in the background and display it in a widget or in the body of a page.

Widget loading an event listing in the background (GIF runs in a loop)

A separate RSVPMaker Widget plugin (see below) is available for sites that want to fetch listings from a remote sites without having the full RSVPMaker plugin installed locally. Or you can embed an HTML/JavaScript code snippet in a non-WordPress site to achieve the same effect.

Advantage of Dynamic Loading

One advantage of using this technique, even for displaying events from the local website, is it may work better with websites that have implemented caching. The client can be served a cached HTML version of the page but will still see a current listing of events because it is loaded in the background via a JavaScript call to the API endpoint.

Site visitors may briefly see a “Loading …” message while event posts are being retrieved.

API urls are in the format:

https://rsvpmaker.com/wp-json/rsvpmaker/v1/future
(all future events)

or

https://rsvpmaker.com/ wp-json/rsvpmaker/v1/type/featured
(events tagged with the event type “featured”)

RSVPMaker Widget plugin

A separate RSVPMaker Widget plugin is available for download as a zip file (and pending as a submission to the wordpress.org plugin repository). I have been using it on websites where the full RSVPMaker is not active or needed.

Example: a WordPress multisite implementation for a Toastmasters district, where divisions within the district have their own blogs but RSVPMaker is not active on those subordinate sites. Instead, RSVPMaker is active on the main domain, and division-specific events are designated with an RSVPMaker Type tag.

The RSVPMaker Widgets plugin allows me to display a listing of each division’s events on the division site homepages, while still maintaining a single calendar of events from across the district.

HTML/JavaScript Snippet

You can also embed events listing into any website, including static HTML sites and those that run a different content management system, using the HTML / JavaScript code snippet shown below. Change the div ID and the parameters for the creation of the widget object to match your needs and modify to taste.

On a WordPress site, you can use the Custom HTML widget or the Custom HTML editor block to add this code (assuming it’s allowed by your site security) as an alternative to installing the RSVPMaker Widget plugin.