Monday, November 25, 2019

WP Plugin Hacking: Adding a [learn-more] tag to Simple Calendar's Event Template Tags

I'm helping a team of folks revamp our Shul's website and one area we're focusing on is the events/calendar section. Like most organizations, we've got to balance sharing information with the need to minimize maintenance. Simply put, having to keep event data manually in sync in multiple locations is a recipe for disaster.

The Simple Calendar WordPress plugin solves most of this challenge. It lets the office staff maintain a master Google Calendar and the website's event page renders using this data.

The ability to use the plugin's Event Template Tags means that the web team can customize how events appear and can publish them in the clearest way possible.

The challenge comes, however, when we consider the amount of information tracked in a Google Calendar entry. The essentials are there: title, when, where and a description but extra information that we'd like published on the website is missing. Is there a fee for this event? Is it kid friendly? What's the dress code? And so on.

We could cram this information into the description of a Google Calendar entry, but that will be both painful to manage and throw off other apps using the master calendar feed.

Our solution is to create a WordPress post for each event that contains all the event details. This is easy enough to do, but leaves us with the new challenge of how we link these posts from within an event template. I'd hoped I could write a bit of code to do this, but the Simple Calendar plugin docs don't mention any hooks or filters that I could tie into.

Fortunately, looking through the plugin source code I realized that such hooks do exist, mainly: simcal_event_tags_add_custom and simcal_event_tags_do_custom.

Below is the code for a trivial plugin that lets you auto-link a 'Learn More' post to a calendar entry. Once the plugin is enabled, you can use the [learn-more] tag to link to the relevant post within an event template:

Posts are associated with a calendar by setting a custom field to the relevant calendar entry ID:

Calendar entry IDs are shown to admin users when they visit the events page. So using them requires a bit of copying and pasting, but it isn't hard to do.

This scheme should provide us the best of both worlds: a centralized calendar for easy management, and support for detailed information on the website that is auto-linked to the calendar.

Here's the plugin code that makes this all work:

<?php
/*
Plugin Name: Simple Calendar Learn More
Description: A plugin to add a [learn-more] link to the simple calendar Event Tags.
Version: 1.0.0
Author: Ben Simon
*/


add_filter('simcal_event_tags_add_custom', function($tags) {
  $tags[] = 'learn-more';

  return $tags;
});

add_filter('simcal_event_tags_do_custom', function($body, $tag, $partial, $attr, $event) {
  if($tag == 'learn-more') {
    $id = str_replace('@google.com', '', $event->ical_id);
    $attrs = shortcode_atts([
      'newwindow' => 'yes',
      'label'     => "Learn More"
    ], shortcode_parse_atts($attr));

    $posts = get_posts([
      'meta_key' => 'calendar-id',
      'meta_value' => $id
    ]);

    $html = '';

    if($posts) {
      $label = $attrs['label'];
      $target = $attrs['newwindow'] == 'yes' ? 'target="_blank"' : '';
      $url    = get_permalink($posts[0]);
      $html = "<a href='$url' $target>$label</a>";
    }

    if(current_user_can('edit_posts')) {
      $html .= "<p style='text-align: right'><small>calendar-id is <i>$id</i></small></p>";
    }
    return $html;

  } else {
    return $body;
  }
}, 10, 5);


?>

No comments:

Post a Comment