Control of Personal Data (GDPR Compliance)

RSVPMaker now allows individuals to download a copy of their personal data or request that it be erased, in keeping with the provisions of GDPR.

The European Union’s General Data Protection Regulation (GDPR) is part of a broader trend toward giving individuals more control over how their data is secured and managed. WordPress 4.9.6 includes utilities for exporting and erasing user data on demand.

rsvpmaker personal data
Sample personal data export, including RSVPMaker registration info.

RSVPMaker piggybacks on those features, so that in addition to user data or comments associated with an email address, a data export can include event registration data. All registration data associated with that email address can also be deleted on demand.

In both cases, data will be retrieved or deleted based on a search for the person’s email address and all associated records. The website will send an automated email asking the user to confirm that request.

You will find the Export Personal Data and Erase Personal Data screens under the Tools menu of the administrator’s dashboard.

Adding a Privacy Policy

If you are running an independent WordPress site, you will see prompts suggesting you add a privacy policy to your website as soon as you update to version 4.9.6 or later. WordPress will suggest some default wording. You may also wish to consult my version from rsvpmaker.com for wording specific to the RSVPMaker.

Adding a Privacy Policy Consent Checkbox

GDPR’s requirement for informed, active consent is commonly interpreted as requiring an additional checkbox (not pre-selected by default) with which the user agrees to your privacy policy. The RSVPMaker settings screen allows you to specify that the checkbox should be displayed on all forms, with a message you can customize.

privacy consent checkbox
Error message when consent checkbox is not checked.

Since RSPMaker’s registration function is meaningless without data collection, the submission form submissions will fail if the box is not checked.

You might think that it would be obvious that the purpose of this form is data collection, but the idea is people should know the specifics of how you will store, protect, and use the data they share.

Use of Email Addresses

RSVPMaker includes built-in features to support sending confirmation, reminder, and follow up messages to individuals who register for your events. Registration information is retained indefinitely, but an administrator can delete it in response to a request using the tools provided by WordPress. However, site owners should be cautious about adding email addresses collected this way to a permanent email list.

Under GDPR, other regulations, and generally accepted best practices, consent is required to add an email address to a marketing email list.

If you use the integration with MailChimp, it’s possible to include an “Add me to your email list” checkbox on the registration form and let MailChimp take care of the double opt-in process. An email address will not actually be added to the email list until the owner of that email address confirms. That is, they will be sent a notification and must click to confirm before they are added to your list. If you are not using that integration, you should obtain consent some other way.

RSVPMaker Reminders For Multiple Events Based On The Same Template

If you use the events template feature of RSVPMaker to create multiple events including the same boilerplate details that repeat every time, now you can also create automated reminder messages for each of those events more easily.

When you create a series of events based on a template, each event gets a copy of the basic content (where and when you meet, who to contact with questions) and most of the associated metadata (like whether RSVPs are being collected, whether there is a fee, what event type the post is associated with). However, the reminder message setup isn’t duplicated by default — and you might not necessarily want the reminder message to be the same each time. Just like you do not want to automatically overwrite the content of posts that might have been updated independently of the template.

On the other hand, you may want the reminder message to be the same (or basically the same) most of the time. Improving how this is handled is one of those features I needed for my own purposes. Since I run an Online Toastmasters club (Online Presenters) that meets every week, and every one of those meetings needs an automated reminder message to the people who signed up to attend as a guest. The reminder includes details like the online meeting link and basic instructions for how to sign in. Adding those reminders one meeting at a time was a drag.

Now, when you update a reminder message for any event associated with a template, you will see an option to apply that update to all the other events associated with that template. This is similar to the process for updating events based on a template, where you can click “Check all” but still make exceptions for special events that require a slightly different message.

Checking reminders to be updated.

Note that the subject line includes a series of date formatting codes, which default to the same ones used in your site’s “long date” format from the RSVPMaker settings page. You may want to tweak it, for example if you do not think it’s necessary for the year to be displayed.

The result looks like this

Success!

For basics on how the reminders function works, see this post.

 

Saved Locations Added to RSVPMaker WordPress Plugin

RSVPMaker users have periodically requested that I add a standard way of recording event locations. If you were organizing a series of events at a specific location, you could create an event template, but RSVPMaker didn’t have a way of managing locations independently of events. Now it does.

One reason I hesitated was I didn’t want to provide a template that would lock you into a specific presentation, without taking into account individual preferences for which mapping service to use or how events should be presented to your audience.

My solution is to provide a default format but let you edit it however you want, using the WordPress editor. Details like whether you want the location to appear at the top of the post, the bottom of the post, or in the middle are left up to you. I’m shooting for a little more consistency, but no foolish consistencies.

Add a location

Click the Location button in the event editor, and you will get a form that lets you add a new location. Give it a name and put in the address details. You can manually add a map link or let the software generate a Google Maps link (be sure to test it afterward to make sure it guides people to the right address).

When you click Add, the formatted address will be inserted into your event post. It will also be saved as a special kind of RSVPMaker post. The next time you want to add that address, you will be able to pick it from the dropdown list and click Choose.

Get a saved location

You can change or enhance the content of one of these saved locations using the WordPress editor. For example, you might want to add a location photo to point out a hard-to-find entrance.

Locations are listed under RSVP Events when you have it set to Show All (rather than sorted to show only future events). The Edit button shown in the dialog above will also guide you to the correct post.

Here’s an example of retrieving that sample location to add it to an event post.

Inserting a saved location

If you want to provide any special styling for the display of locations, there are several class tags you can take advantage of:

Here’s an example of a little CSS I experimented with using the WordPress Customizer tool

… which results in this:

Styled location output

 

Color-Coded Event Posts

Here is an example of how you can style your RSVPMaker listings for different types of events, using class tags in the HTML that correspond to the event type you set in the WordPress editor. RSVPMaker’s event types work like categories for your blog. I prepared this example in response to a question:

The question was whether the color coding could be associated with an RSVPMaker event template.

The answer is yes — if you assign a category to the template, it will be applied to all the events you generate based on that template. Here’s an example of a color-coded calendar and event listing. I’m not offering this as an example of good design necessarily, just an example of what’s possible.

January 2018
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
 
1

 

2

 

3

 

4

 

5

 

6

 

7

 

8

 

9

 

10

 

11

 

12

 

13

 

14

 

15

 

16

 

17

 

18

 

19

 

20

 

21

 

22

 

23

 

24

 

25

 

26

 

27

 

28

 

29

30

31

     
Month/Year /

Monday January 29, 2018 7:00 PM
 

This one does not have colored styles.

Event Types:

Tuesday January 30, 2018 7:00 PM
 

Sample showing how to style event posts by event type.

Let’s see how this works.

Event Types: ,

Wednesday January 31, 2018 7:00 PM
 

Sample showing how to style event posts by event type.

Let’s see how this works.

Event Types: ,

The event headlines shown in the calendar are coded like this

While the body of an event post as listed on the page begins with this coding on the div

This means we have two class tags we can target .team_blue vs .team_red (on the a tag) and .rsvpmaker-type-team-blue vs .rsvpmaker-type-team-red (on the enclosing div or the article tag on a single post view).

In addition to styling the div or article tag with class .rsvpmaker-type-team-blue we can target the headline, paragraph and div tags etc. inside of it as in this code for the example above.

If you do not want to hack your theme’s style.css or the stylesheet used by RSVPMaker, you can add a few quick CSS customizations of this sort using the Additional CSS tab of the Customizer.

Note: One inconsistency is that the RSVPMaker class tags for calendar items have terms separated by underscores, whereas the rsvpmaker-type tags on posts have terms separated by hyphens and all the terms are rendered in lower case. The class tags on calendar items are not necessarily lower case. So the event type entered as “Special Event” in the editor comes out as Special_Event on the calendar but rsvpmaker-type-special-event as the class wrapped around the event post. (I could change it to make it more consistent, but I won’t because I don’t want to break the website of anyone who is using these tags as-is.)

The important thing is it works.

I hate outdated websites. If the event or the deadline is past, why are you telling me about it?

Outdated websites are the worst. Particularly when it’s obvious. When you view the home page and it’s advertising an “upcoming” event that happened a week or a month ago. Or urging you to take advantage of a limited time offer for which the deadline is already past.

Is that really the worst thing a website could be? Nah, I suppose it could be ugly or disorganized or unprofessional in a lot of different ways. But it’s one of the things I see regularly on websites that are otherwise very polished. The big event, or the date of the big promotion, has come and gone, but no one has gone back to refresh the website. If it goes on for a few days, it’s forgivable: we all have lots of other things to do. Pretty quickly, though, it starts to look like a sign of neglect.

Here’s the thing: computers can tell time. Content management systems can be configured to let outdated content expire or fade into the background. Just by using a blog and posting to it regularly, you can display your latest content more prominently than older content. For people to be able to find your original announcement of an event in the blog archives isn’t a bad thing, as long as there is more recent content (photos of happy people in the event recap) piled on top.

RSVPMaker event listings address this in a different way, allowing you to display a calendar of events in order of event dates as opposed to in order of posting date (blog style). Site visitors can navigate back through the calendar to find old event posts, but the upcoming stuff is always displayed more prominently.

When you want to embed a featured event on the home page, you can set that up using the rsvpmaker_one shortcode and specify that it should expire after the date is past. I also provide an rsvpmaker_timed shortcode that you can wrap around any block of content with start and/or end times specified for when it should be displayed. (Both are not new but have been improved in recent releases).

The rsvpmaker_one shortcode

The rsvpmaker_one shortcode is particularly intended as a way of displaying an event on the home page or a landing page. Use it to display a specific event, or the next scheduled event, or the next event in a specific category (like the next webinar). You can display the full event, with either the RSVP Now! button or the registration form included, or a show compact version. You can also extract elements like the date, the button, or the form to be used in a custom layout. In the context of this post, the important thing is that it can be set to expire (disappear off the page) when the event date is past.

There is a button on the button bar (the clock icon) to help you get the parameters right.

Options for embedding a single event

Examples of the shortcode:

Retrieve a specific event by ID and display it along with the registration form. Expire it 6 hours after the start time of the event.

Show the next event in the webinar category (if none is scheduled, don’t show anything). Instead of displaying the whole form, show the RSVP Now! button.

You can also add a style attribute where you specify CSS for a div to be wrapped around the featured event. Example: style=”border: thin dotted #222; padding: 10px;” for a dotted border.

The rsvpmaker_timed shortcode

The rsvpmaker_timed shortcode is a quick-and-dirty way of specifying a start and/or end date for displaying a chunk of content. I’m sure there are other plugins or themes that provide something like this as a feature, but consider this a little something extra you get “for free” with RSVPMaker.

Here’s an example of how you would set it up:

Limited time offer
Use of the rsvpmaker_timed shortcode

The basic usage is like this:

Alternatively, you can do this:

The output is similar to what you would get from the example shown above (the one with the closing [/rsvpmaker_timed] tag), except that we’re pulling the content from another post. The style attribute is also available with this one, if you would like to apply a border or background color to the featured chunk of content.

If you don’t specify time of day, midnight is assumed (a December 26 end time means the post will stop displaying 1 second after midnight that morning). To make the start and end times unambiguous, you may want to put them in SQL format.

I currently don’t provide an editor button for finding the post or page ID, but you can grab it easily enough from the address bar in the WordPress editor.

Finding the post ID

I would typically suggest creating this chunk of content as a blog post. If you don’t want to make it public in the regular navigation flow of the site, you can save it as a draft and still use the WordPress editing tools to format and update that chunk of content independent of the page you are embedding it in.

If you want to use a page or any other post type, you need to add a post_type attribute.

Example:

Note that if you use a caching plugin, content may not disappear immediately after the end time you specified but only when the cache is purged or refreshed.

Those are my latest entries in the war against outdated web content.

Adding a Custom Payment Gateway to RSVPMaker

RSVPMaker now supports two payment methods, PayPal and Stripe (via integration with the WP Simple Pay Lite for Stripe plugin), but I recently got a request from someone wanting to add an additional custom payment gateway. Now you can by using the hook ‘rsvpmaker_cash_or_custom’.

I’ve always tried to keep RSVPMaker developer-friendly for those who want to extend it. If you come up with something cool that ought to be part of the standard distribution, I hope you will consider contributing it to the project.

The new Default Payment Gateway heading on the settings page now includes 3 options: PayPal, Stripe, and Cash or Custom. The Cash or Custom setting can also be used by anyone who wants to display pricing on the website even if they will tell people to pay by cash or some other means, rather than paying online.

In the case where you are implementing a custom payment gateway, you would write a routine something like this.

Normally, what you would do in this space is output the payment button or other user interface code for the payment gateway functionality you are adding. This sample function just dumps all the data you get to work with related to the pricing and the information the user submitted about themselves, such as the email address for a confirmation message.

Want to add a custom payment method?

You would then take responsibility for handling the user’s submission. Ideally, you want to capture confirmation of the completed transaction and log the payment as complete in the RSVP report. Here is the function call.

In this example:

‘blockchain’ is the label for my custom payment method
$amount is the amount paid in this transaction
$rsvp_id is the ID for the event registration
$event is the post id ($post->ID)
$transaction_id is an optional transaction identifier, intended for an ID # you got back from the payment service

Here is what you get to work with (the output of the test function shown above, with an example user entry).

Charge

300

Invoice ID #

rsvp126102

Tracking # for payments

RSVP ID #

Unique ID for main database record for registration

5

Details

Details about the transaction

Profile

Details about the person

Post

Creating an Events Registration Landing Page with RSVPMaker

Improvements for RSVPMaker often arrive when I see the need for them in my own projects, and recently I found myself creating a landing page for a series of workshops at Online Presenters. This is a Toastmasters club I founded, which focuses on helping members develop skills for webinars and online meetings, presentations, and trainings of all sorts.

landing page example
Online Presenters Landing Page

Because the workshop series is intended as a recruiting tool, I wanted our promotions (including some paid Facebook ads) to direct visitors to a page with a clear call to action — RSVP Now! — with no distractions that might tempt them to click away to another page or blog post. That meant the regular page sidebar and the menu at the top of the page had to go. Continue reading “Creating an Events Registration Landing Page with RSVPMaker”

Cutting Prices for Events Website Hosting

I’ve updated my pricing on two easy ways to get access to a WordPress website with RSVPMaker events management already integrated, lowering the price of entry to $75 from $99. Hosting your site with Carr Communications Inc., creator of RSVPMaker, makes sense if event management is one of the main purposes of your site. We can offer closer support, including PayPal setup, if you host your website with us.

Subdomain Hosting

For $75 per year, you get a website at an address like seminar.rsvpmaker.com. We handle the web hosting and technical details, but you get access to all the standard WordPress features, plus the event management capabilities of RSVPMaker. This fee includes assistance setting up the site to allow you to accept event payments via PayPal.

In addition to posting your events, you can promote them through the blog and build out other pages for details like speaker bios and your event agenda.

Sign Up Now

Subdomain Label
Administrator’s email address


Independent Website Hosting

Price: $175 per year for hosting of your own independent website, plus configuration assistance and RSVPMaker support. This gives you greater freedom to configure your site however you want and make your own decisions about adding themes and plugins, without being limited to those available on RSVPMaker.com.

Sign Up Now

Domain Name


Note: Hosting fee does not include domain registration or copywriting, consulting, and design services. It does include setup and proper configuration of WordPress site and RSVPMaker, as well as updating of all code so you always have the most recent, most secure, and most functional versions.

As with hosting anywhere else, the customer gets FTP access to the server and can perform their own additional customizations. Includes 5 GB disk space. Data center services provided by LiquidWeb, comparable to standard shared hosting plan.

How RSVPMaker Looks Up Prior Event Registrations

The latest updates to RSVPMaker were inspired in part by this post on the WordPress.org support forum for the plugin.

Users within my organization tend to forget that they’ve registered for an event and wind up RSVP’ing multiple times. How can I restrict duplicate entries with an error message that says that they’ve already RSVP’d to an event?

One of the new ways I am trying to address this is with a JavaScript / AJAX powered lookup of any prior RSVPs associated with the user’s email address. As they start to type their email address into the form, they will see prompts to update any matching record, and as they type more of their email address the list of possible matches should narrow until there is only one (or none if they had not previously RSVP’ed using that email address).

Looking up matching RSVPs by email address.

A user can follow the link in that prompt to update their previous registration, if necessary. Or they may just need to be reminded that a registration for them is already on file.

This mechanism is actually a fallback. The standard email confirmation message includes an Update RSVP link users can follow to update their record. However, that only works if they go back and find the confirmation message.

Similarly, when you invite people using the MailChimp integration, their email address is embedded in the RSVP Now button. The idea there was always to save them some typing by looking up profile data from any previous RSVPs so they would not have to type it in again. (In the process of updating this code, I fixed a few bugs that were preventing this process from working properly).

If someone responds to the invitation, forgetting that they previously registered, RSVPMaker will ask them if they want to update their previous response. Similarly, if RSVPMaker detects a cookie associated with a previous response to the same event, it asks if they want to update that response rather than entering a new one.

update rsvp prompt
Update RSVP? prompt

What is the scenario where the user would NOT want to update the previous RSVP? There are scenarios where the user wants to enter multiple independent RSVPs under the same email address. Maybe an administrative assistant is registering several executives but wants all the confirmations to come to his or her email address. Another example is a couple that shares an email address, where the husband’s RSVP should not overwrite the wife’s or vice versa. My preference would be that one person enter an RSVP with one or more other people indicated as guests, but it doesn’t always work that way in practice.

Security Considerations

There are a few potential security concerns with this scenario. The high security option would be to require users to login with a password before completing the RSVP form, and their identity would be tied to that login. RSVPMaker supports making logins required, but in many cases the more important goal is to make it as easy as possible for people to register without having a pre-assigned password.

If any information gathered on the form is sensitive, I recommend tagging it as private. You can see that with the tagging of the phone # and related fields in the default form:

The form builder utility (the popup you get when you click the “Generate form” button) also allows you to mark fields as private. If data has been recorded for that field, the message “Private data on file” is displayed instead of the private content. In other words, this prevents people from using your email address to look up your phone number or other information designated as private.

However, a mischievous or malicious user could use the lookup by email function to alter someone else’s RSVP response. I haven’t seen this be a problem, but it’s not impossible.

Design Considerations

In the AJAX-powered email lookup example shown above, the data entry field for email appears before those for first and last name. The idea is to get them to enter their email address first. If we match it to a record, we want to do that before they have reentered a lot of the same information.

I’ve made this the new default form layout for new users, but established users of RSVPMaker may need to tweak their RSVP form code. The form builder now includes an option to specify that the email field should come first.

Teardown Of A WordPress Multisite Events & Membership Site (Video/Slides/Code)

These are the slides from a WordPress meetup presentation that covered the code behind RSVPMaker, the RSVPMaker for Toastmasters extension, and a WordPress multisite instance where I offer free club websites as subdomains of toastmost.org.

The audience was at a mix of experience levels in terms of technical knowledge, with some people being more designers or business users of WordPress as opposed to programmers. I tried to frame it so those with more WordPress programming experience would have a chance of learning something new, and the others would at least get a glimpse of what is possible when WordPress is used as the basis for a community website.

To make this more useful, in addition to the slides and the video I’m sharing some of the relevant code snippets and pointers to some tutorials with more info on specific aspects.

Meetup-Tear-Down.pptx

How to create a plugin

Create a PHP file with a header like this and upload it into a subdirectory of wp-content/plugins

Actually, for a one-off hack for your own site that you don’t intend to publish, it could be as simple as

Once this is uploaded, you should see the name of your plugin on the Plugins screen of the WordPress administration dashboard inviting you to activate it.

Making your plugin do something

The point of a plugin is to add to or modify the default behavior of WordPress. You do this by connecting with the plugin and filter hooks WordPress makes available. You can modify almost everything about how WordPress functions, which means you as a developer can do either wonderful or horrible things to a website. You can change the display of content, modify the database queries used to retrieve content, or alter security parameters for who should be able to access what.

The two major families of hooks are:

  • Actions triggered as WordPress loads a page like
    • ‘init’ – means the system has been initialized, but the process of running the page lookup query and outputting content has not yet begun)
    • ‘admin_init’ – same thing on the administration back end of WordPress
    • ‘wp_footer’ – fired by the wp_footer() function call that occurs in the footer of a properly coded theme. Often used to output a snippet of JavaScript or other code at the bottom of every public page or post.
  • Filters that allow you to modify some content or data
    • ‘the_content’ – change the content of a post
    • ‘the_title’ – change the title of the post
    • ‘query_where’ – change the WHERE clause in the SQL query used by the WordPress loop for retrieving a list of posts

Here’s an example of an action on ‘init’ used to set up the rsvpmaker post type. Without that, the system would not recognize urls pointing to rsvpmaker content.

Here are a couple of filters.

I’ve abbreviated the code of some of these plugins for simplicity, but the point is that the filter on the_content

  • Checks whether the content is associated with the post type rsvpmaker, and if not returns the content unchanged
  • Looks up the date or dates (stored as post metadata) and adds it to the top of the content.
  • Checks whether RSVPs (registrations) should be collected and if so displays the RSVP form at the bottom of the post.

The filter on wp_title changes what should be output in the HTML title tag in the page header. Again, it checks if the content is rsvpmaker content and if so adds the date.

Adding AJAX

In the Toastmasters application, when a meeting organizer is assigning other people to roles, the user ID of the chosen member is sent to the server via a JavaScript AJAX method so that it’s saved even if the meeting organizer doesn’t make it down to the bottom of the form and click Save.

This is accomplished with some JQuery Javascript

and the PHP code that will accept this input and process it

The JavaScript detects when a select form field with the class .editor_assign has changed, gets the current value of that field and submits it to the server. The data is posted to a global variable ajaxurl (set automatically by WordPress) that points to a PHP file used specifically to process ajax requests. The submission must also include an ‘action’ attribute, in this case ‘editor_assign’ that WordPress will use to figure out what function to call.

The PHP code starts with an add_action call including that action string prefixed by wp_ajax_. This is the version that works for a logged in user — for an unauthenticated website visitor, it would be wp_ajax_nopriv_ or in this case wp_ajax_nopriv_editor_assign.

The add_action command identifies the function that will process the input, record it as post metadata, and send back a confirmation message to be displayed by the JavaScript routine.

Metadata for posts and users

My plugins make extensive use of custom metadata associated with posts and with users. The date of an event is stored as post metadata, and so is the 1 or 0 indicating whether the registration form should be displayed. The Toastmasters application modifies user profiles so they can contain data like home_phone and mobile_phone and Toastmasters ID # in addition to default fields like name and email address.

The pattern for getting and setting metadata is.

In both cases, when getting metadata you must specify the third parameters as true if you are trying to retrieve a single value. By default, you will get back an array, which what be what you want if your application stores multiple items such as the log messages in this example under a single lookup key.

Here is what the corresponding database structure looks like for the wp_postmeta table, with metadata for an RSVPMaker post.

Post metadata

Modifying the Editor

When we create an RSVPMaker post, we need to add form fields to the standard WordPress editor and also functions for saving the data entered into that form as post metadata.

Here’s the WordPress editor, with the additional RSVPMaker fields showing under the editor.

RSVPMaker editor

Code to add the additional “metabox” on the form (simplified).

The action ‘admin_menu’ triggers a function that registers our meta box, gives it a name, associates it with the function draw_eventdates, and says what kind of content it is associated with, in this case rsvpmaker posts.

The draw_eventdates pulls in all the metadata associated with the event so far and displays the form for setting event dates and other attributes.

Because there is a long list of options associated with setting up a registration form, those are hidden by default until the Collect RSVPs checkbox is checked. The code for displaying that section of the form looks like this.

When an RSVPMaker post is saved, the post title and content are saved just the way that they normally are. In the process, WordPress triggers the action post_save, which RSVPMaker uses to detect and save the additional data submitted from its additions to the editor form.

Shortcodes and Visual Representations of Shortcodes

WordPress shortcodes are placeholders for content to be inserted into the body of a post based on the output of a function.

Shortcodes are how this in the editor …

rsvpmaker_upcoming shortcode in the editor (Text view)

… turns into this on the website.

RSVPMaker event listing with calendar

A shortcode begins and ends with square brackets. The name of the shortcode is the first string of text after the opening bracket, and the shortcode can also include attributes like calendar="1" — which will be passed to the function to indicate the calendar should be displayed at the top of the event listings.

Here’s a simplified version of the rsvpmaker_upcoming shortcode

The excerpt shown here covers how RSVPMaker changes the standard WordPress query to look up a series of posts ordered by the date of the event rather than displaying them in blog post order of publication date. The $atts parameter is an array containing any shortcode attributes such as calendar="1" or past="1" (to display past instead of future dates).

If the shortcode uses a close tag like this

[my_shortcode]content here[/my_shortcode]

In that case, the shortcode function will also be passed a $content variable you can work with. Something like this:

To make shortcodes easier to use by non-techies, you can instead display an placeholder image in the body of the post, with a popup dialog box as a user interface for setting the shortcode attributes. You also want to add a new button in the visual editor for adding a new instance of your shortcode. What I present below is based on an excellent tutorial, Take your shortcodes to the ultimate level.

Popup editor for rsvpmaker_upcoming shortcode

Here’s an excerpt from the JavaScript code loaded as a plugin to the TinyMCE editor used by WordPress.

This script identifies shortcodes using the same regular expression (pattern matching) formula WordPress uses in PHP on the server side when rendering a post. It parses out the attributes and creates an HTML image tag that embeds those same parameters, so the data is logically associated with the image in the JavaScript object model. The src attribute of the img tag points to a url that has some of that data encoded in it, such as

Instead of referencing an image file, the img tag points to a url the plugin will use to generate an image.

Registered to execute on the admin action, before any content has been queried or output, this function first checks for the presence of a query string like ?rsvpmaker_placeholder=1 and returns if it is not found.

If that query string is present, the function loads a blank background image for the placeholder from the plugins directory, adds text based on the query parameters, and outputs the modified image. Finally, it exits before WordPress can output any other content.

Custom Administration Screens

Because RSVPMaker collects event registrations, we also need to add a screen on the administrative back end where those registrations can be viewed.

RSVP Report screen
Custom Dashboard

The default WordPress dashboard shows updates on plugins and upcoming WordPress meetups. My Toastmasters community is more concerned about managing the agenda for upcoming events, so we present them with a custom dashboard.

Toastmasters dashboard

For a more detailed tutorial, see this from WP Explorer. Here’s a quick summary.

Custom user registration and metadata

User records can also be customized to include metadata for your purposes. For Toastmasters club members, I want to record information such as phone numbers and Toastmasters ID #. Club officers are presented with an Add Member screen that asks for that additional information and records it as part of their user account, along with the required fields like user_login and user_pass (password).

We can test for whether a user is logged in, a member of a specific blog (site within a multisite install), or possesses a specific capability under the WordPress security scheme.

Add Roles and Capabilities

WordPress security revolves around user roles and capabilities. Each of the predefined roles (subscriber, contributor, author, editor, administrator) has a set of default capabilities. That list of capabilities can also be manipulated by plugins. I like the plugin User Roles Editor as a general purpose utility or this purpose. I wrote my own routines to define plugin-specific capabilities and roles.

In this example, I add a Manager role (one level up from editor, not quite an administrator) and add a capability to the default administrator role.

Making a WordPress Installation Multisite

See Create a Network in the WordPress Codex documentation for detailed instructions on configuring a single installation of the software to host a network of sites.

You start the process by modifying your wp-config.php file to include this statement:

When you return to the admin screens, you essentially get a wizard that guides you through the process of determining what settings to change wp-config.php as well as your .htaccess file.

For the subdomain configuration I used, where sites have URLs like op.toastmost.org and demo.toastmost.org, I also had to change the DNS settings to recognize “wildcard” subdomains. Just as the path to a blog post represents a logical naming convention for content in the database, WordPress can then treat subdomains as aliases for sites within the database table.

When you make these changes, WordPress modifies the database for your site to include separate tables for each site. For example, instead of single wp_posts table, you get a whole series of posts tables named according to the subdomain site ID.

Multisite tables for posts

Similarly, your uploads directory gets divided up by site ID to keep those files separate.

Multisite directories.

Finally, I use a custom site registration process that gathers information specific to my application, such as the name of the Toastmasters club and the timezone (important for calendar functions) and adds default content and settings.

The process is:

  • Club website owner first must register for an account. Custom user account registration flow requires that they first register for a MailChimp mailing list. I use the MailChimp API to verify their email address is on the list before accepting their registration.
  • User fills out the form with the requested subdomain and other data.
  • The script below creates the site.
We now have a custom-built website, with some starter content specific to its purpose as a Toastmasters website.

Questions? Drop me a line: david@rsvmpaker.com

The plugins discussed here are in the WordPress repository

You can also look them up (and contribute improvements!) on GitHub

github.com/davidfcarr