Category Archives: amr events

Notes that relate to creating and editing events

Grouping events

Events can be grouped by date formats or by categories, tags or custom taxonomies.

  • Events can be grouped by days, weeks, months and some funkier options that no one will probably ever use, but I liked the challenge! Actually I imagined one could do some seasonal styling perhaps? each grouping has it’s own css classes, and date/time format
  • Grouping also allows one to do timetables (grouped by day), weekly schedules, or monthly, quarterly or seasonal event views.
  • See how to format the date related groupings here.
  • Each grouping comes with css classes so you could for example do seasonal styling of event groups.
  • By adding in the javascript in the settings, one could also expand and collapse the groupings.

Settings

 

Grouping settings
Grouping settings

Styling Groupings – use the css classes

Example of html produced with css classes
Example of html produced with css classes

Correct Handling of UID, RECURRENCE-ID, SEQUENCE

Modifications to events, especially to an instance of a recurring event, or an update to a modified instance can all seem quite complex.  It’s not that bad once you understand the various bits that you need to provide for the receiving application to make sense of it. See the RFC5545 spec for details.  This tools.ietf.org version or icalendar.org or the kanzaki version.

  • UID – must have and must be unique
  • SEQUENCE – numerically update to indicate which is the latest version
  • RECURRENCE-ID – if modifying a single instance with in a recurring stream.  Note that for a UID and SEQUENCE pair, the “RECURRENCE-ID” value for a recurrence instance is fixed. The event date may change but the “RECURRENCE-ID” does not. It must always be the original date as generated by the RRULE.
  • LAST-MODIFIED – Probably a good idea top update this too

Note also:

  • if a user subscribes to an ICS URL, then the receiving application will check for updates on a regular basis at a frequency determined by it.  It will be seen as a separate calendar.  It will use the SEQUENCE numbers to determine the latest event details. There may be a delay in an update being made on the originating system and it being reflected in the receiving system.   The only reliable way to be sure that users will have updates seen in their calendars is if you can get them to subscribe to the url (or ‘import’ the url, not the file)
  • if an ics file is imported (eg: when event details are sent as an ics file attachment, not as a url, or if the user downloads the ics file from a url and then imports it), then it will be added as events into the calendar chosen by the user.  Updates may overwrite IF the user re-imports the events AND the application is clever enough to match up the UID’s (and RECURRENCE-IDs if it’s part of a recurring set).  It should then also use the SEQUENCE to determine if the details are actually the latest.  There is no way on devices to force a user to load an updated ics file sent to them.

Example

Modifications to recurring rules or rdates and modifications to instances of those recurring rules (themselves already a modification.)

Assume we have a recurring event.  It starts with a SEQUENCE: 0

DTSTART;VALUE=DATE:20140421
 RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=3MO
 UID:1f4irrb5uh6q3cdfsnq15vd00g_R20140421@google.com
 SEQUENCE:0

This generates an infinite set of mondays, including the following

  • 19th May
  • 16th June
  • 21 July
  • 18 August
  • etc

Now, one of the instances gets modified.  (This could be just the description or the actual date.)  A RECURRENCE-ID VEVENT is created for each instance modification and the SEQUENCE NO is updated.   The recurrence-id matches the date in the recurring rule that it applies to. The combination of UID, RECURRENCE-ID and SEQUENCE helps us identify the instance that is being updated.

For a given pair of "UID" and "SEQUENCE" property values,
   the "RECURRENCE-ID" value for a recurrence instance is fixed.
DTSTART;VALUE=DATE:20140721  (ie no date change in this example)
 DTSTAMP:20140720T064853Z
 UID:1f4irrb5uh6q3cdfsnq15vd00g_R20140421@google.com
 RECURRENCE-ID;VALUE=DATE:20140721

Now assume the original RRULE is modified too, perhaps just the description or shock horror, the recurring date definition?  It’s sequence-no is updated too BUT now what should happen to the RECURRENCE-ID instance?  Should it be updated to indicate it is still valid?  IE we now have:

  • generated date 21 July 2014 with UID and SEQUENCE = 3 and
  • RECURRENCE-ID;VALUE=DATE:20140721 with matching UID and SEQUENCE = 3

It appears that perhaps SEQUENCE numbers can increment separately, so one could conceivably receive a file with a RRULE with an equal to or  greater sequence number than a RECURRENCE-ID.       From   this discussion, it is really not clear what the supplying calendar application will do:

Once UID 1/SEQUENCE 0 hits UID 1/SEQUENCE 1 (which would
mean something significant about the set of instances
has changed) all bets are off in regards to RECURRENCE-ID
values that previously existed.

If the UID/RECURRENCE-ID/SEQUENCE matches a generated date from the rrule with same SEQUENCE (ie both have been modified), then what?  One cannot just use eg: LAST-MODIFIED:20140620T200327Z.  Who is to say that a mod of the RRULE was intended to overwrite the RECURRENCE instance?   Quite possibly not.

Some lengthy related discussions here and in other parts of the thread:

Complications that urge one to keep events as simple as possible:

Searching the web seems to indicate some folks believe RECURRENCE-IDS should not change.  So should we assume that if the RECURRENCE-ID vevent is still in the file then it is still valid and should be included.  (What does this mean for syncing and deletions?  IE How does one ‘delete’ an existing event.  Or should one always delete events from an ics file and reload ONLY what’s in the ics file?)

Dates, Times, Formatting

There are a number of date and time options for you to choose when displaying your events.    The main ones you should be using are created by the plugin and will be formatted by the date and time settings you have specified in the plugin settings (and applying any localisation that may be available in your wordpress setup).  You can specify these by listtype, so say a widget could have a very compact date format and a full list may be more detailed.

screnshot Date Time Formats
Date Time Format settings by listtype

Event date fields formatted by your date settings:

  • EventDate: Mon, June 23, 2014
  • EndDate: Mon, June 30, 2014 (only if event greater than one day)

Event time fields formatted by your time settings:

  • StartTime: 9:00 am
  • EndTime: 10:00 am

Note there may be situations where there is no end time or no end date (eg: if there is no duration or the end date is the same as the start date.   If a field has not been populated, it will not be displayed and neither will any ‘before’ or ‘after’ text.

Field from the ics specification that may be useful.

Formatted using human language function

  • DURATION:1 week , 1 hour

Other date fields in the ‘edit events’ admin screen

screenshot of show screen options in edit events
show screen options in edit events
  • Last 20140630

The ‘last’ date shown in the edit events admin screen shows the last recurrence date of an event.  It is used to select events within a date range (ie exclude events whose recurrences are in the past, without having to rebuild the recurrence logic).  It is also used to sort events in the admin screen by this last recurrence.   It is therefore formatted yyyymmdd for the sorting.   It is not intended to be displayed elsewhere.

Technical fields

These are direct from the ics specification formatted by the DateTime settings  in the plugin settings.   Note the DTEND has a special definition in the ics specification for all day events (it will have the next day as the end date) and may be confusing to normal users.   Some ics generators get the DTEND logic wrong, so this plugin tries to work with duration just in case.

  • DTEND: Mon, June 30, 2014 10:00 am
  • DTSTART: Mon, June 23, 2014 9:00 am

Other fields

As these are very technical, precise fields, they are by default not formatted but left as found.

  • DTSTAMP: 20140616T021842Z
    • the date and time that the instance of the iCalendar object was created.
  • LAST-MODIFIED:20140616T025756Z
    • the date and time last modified – works with the sequence number to determine the latest modification to an event instance.

Complete multi-lingual event website

To achieve a complete multi-lingual website using amr-events and amr-ical-events-list, the following are required:

the wordpress language files

These are required for the day, month etc event time localisations.  See this post for instructions and links.

your theme language files

Some theme language files can be found at http://i18n.svn.wordpress.org/
. You may have to click down various paths as sometimes somelanguages are stored differently.
Danish example: http://i18n.svn.wordpress.org/da_DK/trunk/messages/twentythirteen/

Updated plugin language files

Some folks have kindly provided translations.  You can see the latest available here.   These are not always up to date.  See translation tools below.  If you need to update your language files, please send me the update and I’ll upload it.

If you do NOT send an update, your version may be overwritten in a plugin update unless you move it.

Custom Language File Location

For these two plugins, you can store your custom .mo and .po files in your WP-CONTENT languages subfolder.

Do not use the subfolder /plugins as wordpresss may one day be auto loading translations to that folder.

custom_language_file

Translation tools:

Finally a Language switcher and/or a multi-lingual language plugin. Some plugins that may help:

  • Xili (unverified in recent years)

Demonstration

lang.icalevents.com

Importing events from a csv file

Simple ‘flat’ events can be imported from a csv file.  This is possible with a third party csv import plugins. The amr-events plugin attempts to use the wordpress meta data as simply as possible to facilitate this kind of easy integration with other plugins.

Events can be complicated: they can recur, be in different timezones, have exceptions to their recurring definition, have alterations to some instances etc.    These ‘complications’ cannot so easily be imported.

From a brief review of the csv import plugins out there, starting with the self named “ultimate csv importer” and backing away in disappointment, I read reviews of a few others and decided to try the really simple importer.   It worked so nicely and cleanly that I stopped there!

What a pleasure to see a plugin that

  • inserts itself sensibly into wordpress, adding itself under tools > import just where it should be
  • imports the data with limited fuss, very sensibly using the column headings, making sensible defaults for missing fields instead of insisting that they are mandatory data. eg: choose to include a post_status, or let it default to draft and ‘publish’ it later.
  • handles custom fields and custom post types as easily as they should be handled – why should there be a ‘fuss’

 So how to import events?

I suggest you create yourself a test event or two that are similar to the event data that you wish to import.  This is so that you can see the meta data that is created.  The amr events plugin tries to stay close to the ICS RFC spec formats for the data, but is sophisticated enough to cope with a reasonable set of date formats and will work with minimal event data input.   Sample files provided below.   The plugin needs

  • some of the standard wordpress post data, as little as your chosen csv importer will cope with.
    • post_title
    • post_content
    • post_type = event (or whatever you have in your settings, or load as post and change afterwards if your csv importer is a bit ‘dumb’.)
  • a minimal set of event meta data (see example file for variations):
    • _DTSTART in RFC format eg: 20140402T090000   or 20140402
  • optional extras:
    • _DTEND  (to define any timed events or events of greater than 1 day.  NOTE RFC 5545 says _DTEND ends on NEXT day for one day events – be careful what you define and test it!)
    • _timezone (if timezone differs from UTC or your website timezone – careful testing with your setup)
    • _allday (timed or allday)
    • _LOCATION
    • see your sample events post-meta in phpmyadmin for more possibilities.

Notes:

  • It is probably not practical to try CSV importing recurring _RRULE data or detailed duration data (use DTEND rather)
  • If you experience any problems, please consider carefully whether it is a problem with your chosen CSV importer and if so, log your support query there.
  • If some data goes in a bit wonky – maybe you set it up a bit wrong, the amr-events plugin does try to correct things – update the post and save.

Screenshots:

imported csv events
variety of events with various data supplied or omited
really simple csv  import screen
really simple csv import screen

 

import csv menu
The csv import option is right there in the wordpress import menu – exactly the right place

Example Event CSV file:

minimal_events

Html in descriptions in ics feed generation

What to do about html in event descriptions?

Some applications will cope with the html, but there are other applications which do not. EG: Google calendar – does not faciliate html nor  issue it in feed.

HTML in the description field is not explicitly forbidden, however it is probably not recommended.  There is some provision for html to be explicitly allowed for, either:

  •  in the description using an ALTREP parameter,
  • or in an ‘experiemental’  X field, X-ALT-DESC,

WordPress allows us to create events with html in them.  So what to do when the ics feed is generated?

Retaining the html – two possibilties:

Link to the html representation:

DESCRIPTION;ALTREP="http://www.example.com/somepath/":This is an example description.

Provide separate field with html representation:

Outlook will recognise:

X-ALT-DESC;FMTTYPE=text/html:<p>This is an example description.</p>

 

This update does both, as well of course ,as stripping the html from the description field in the ics file.  This means images will be stripped too (only for the feed – do not panic!)

More information for the technically minded

 

 

Custom fields for events

There are several good plugins that allow one to create custom fields (or indeed one can just add the fields yourself manually!).

The events plugin has no easy way of knowing what custom fields have been created and how they should be displayed.  See the bear hunt approach below. Custom fields could be

  • images?,
  • urls?,
  • boolean values where the displayed value is something else – maybe the field name?
  • maybe an array – the result of a multi choice select
  • an array of non homogenous values…

Add the custom fields to the post content

Ideally the plugin that creates the custom fields also provides a way to add them to the post content, especially if there is special formatting involved (which the events plugin would not know about).  This is what the sharing and social media plugins do… add stuff to the post content.

The events plugin applies all shortcodes and filters to the content, so the creating plugins shortcodes or filters should work to includes those custom fields in the post content.

If the plugin you are using does NOT offer a way to add the info, then you could consider a site specific plugin where you add your own filter or shortcode to display the values however you want them displayed.

Add custom fields elsewhere in the events list

If adding the custom fields to the post content is not ok, then you need some advanced php smarts (or my custom services -:) ).   The plugin offers a multitude of filters and pluggable functions where you can add code to do your own thing.

Not recommended unless your needs are truly not satisfiable in other ways: You could even write your own listing function – receive the list of events, including post id’s and list it all anyway you want, looking up any additional data.

Reinvent the wheel

An option being considered is ‘reinventing the wheel’ – basically adding own feature to add custom fields. At least then this plugin would know what the fields are and how they should be formatted.   This may be available in a future.

Integrate?

Another option is to pick ‘best of breed’ and deep integrate with an existing plugin.    This would put the events plugin at the mercy of change and updates to the other plugin and doesn’t get around the problem that some users will want to use other plugins anyway.

Still thinking about this one.

The difficult way… I’m not afraid…

Colour in sheet courtesy of scholastic books
There is a ‘difficult’ way that the events plugin could offer these other fields to you to design where you want them in the events list. I call it ‘going on a bear hunt’ and have done this in the amr-users plugin for user reporting.  It has a lot of overhead both in admin settings and run time.

“There is no way around it, gotta go through it” – the entire meta table would have to be searched through to find all the fields that could exist for a post type. It can only find what data is already created.  It still has no way of knowing how they should be formatted.  In the wordpress user reporting plugin it does a best guess and offers some options.

The events plugin may do something similar in the future, note it is not a small task.

If you’d like to have a say on this, either comment here, or add a feature request note in the forum.

 

Problem with Dates/Time – Off by 1 Hour?

If you are using amr-events or amr-ical-events-list you will not have this problem!

Every time a zone somewhere in the world kicks on to daylight saving or off for that matter, I see a bunch of support questions popping up about their event times being off by an hour.    (I monitor wordpress support, stackexchange and wpquestions, and maybe a few more…..)

From a favourite cartoon source - thanks http://xkcd.com/673/

Imagine the confusion this can cause where clients may have subscribed to calendar feeds and have the wrong times.

PHP datetime objects and functions

If people are very lucky, the plugin that they are using has some good coding and is using php DateTime objects with timezone support, and the only problem is that their wordpress timezone is set as a GMT offset, not as a timezone.

That is easily fixed! (goto wordpress general settings)

However all too often the plugin developer has failed to appreciate

  • the complexities of times around the world,
  • timezones,
  • daylight saving and
  • most importance of managing recurring events in one timezone for a display in another where one zone changes daylight saving.  Very easy to generate the wrong times for a recurring event without realising it!
  • even worse governments sometimes change the date/time of the switchover (ok not that often, but it does happen, and then you hope your php installation gets updated with the timezone definitions)

Fixes:

If it is not a simple wordpress timezone setting, then these things are NOT easy to fix and will involve changes to code:

  1. Change to use php DateTime Classes for all date logic .If they are using unix time and not  php datetime objects, it is almost impossible to get it right.  It’s a fairly major rewrite to change all date logic to use the DateTime objects and functions.
  2. If already using, it maybe that the intricacies of recurring event logic have won out.  See below for logic help.

Developers and event website managers should read:

 

 

User Interface for entering events

Scott Adams (Dilbert) explains why sometimes entering events (dates) can be tiring.  He puts it down to too many different spatial models.

He also proposes an alternative (a one spatial model) events calendar interface.

Interestingly one commenter offers the google ‘ figure it out from the text’ method.  Perversely that does not work for me.  I have been influenced by my husband to get in the habit of recording the planned date and time in th text as well as in the date fields as a ‘backup’.  Too many tools make it so ‘easy’ to shift an event, that it sometimes happens inadvertently…. If you haven’t recorded the original somewhere… you’re in trouble!

Any way point of the post was to give you all a place to offer any suggestions.  Yes please comment meaningfully if you want to.  If you like the current interface and prefer it to stay that way, please say so too. (hard to please everyone all the time, but I try)

Quite some thought did go into the current amr-events interface:

  • datepicker for dates, but not a time picker (too limiting, not enough value added)
  • flexible date entry if you want – it’ll do its best guess to figure out what you want rather than insisting how you should enter the date.
  • flexible time entry – lots of logic to work out what you want – it is not going to insist on 10:00, you can enter just 10
  • if no time – will assume all day (you don’t have to tick the all day)
  • it’ll echo back the day of week to you when saved for confirmation
  • in settings one choose the date and time entry format.  See also date formats by country
    • english oriented with dd/mm/yy
    • american with that weird month first thing they do
    • europeans who like to adhere to the international standard yyyy-mm-dd
    • 24 hour clock or
    • 12 hour am/pm
    • define the separators
  • Choose also the start of week (Monday, Sunday, Saturday etc)

Synchronicity, event storage and accessing events via the loop

Synchronicity is the experience of two or more events, that are apparently causally unrelated or unlikely to occur together by chance, that are observed to occur together in a meaningful manner.

Recently within hours of each other I received queries (an email from Chris and a forum post from G470 ) at opposite ends of the spectrum of expectation about recurring events and their storage.    It seems a description of the underlying method of event storage and calculation was necessary for those wanting to do something different.

If you are not up for a detailed technical discussion, do not panic.  Rest assured that the default settings will deliver  commonly accepted ways of seeing events.   The plugin aims to be both simple and customisable.

For the rest read on…..

Chris asked:

Could I just ask how you are handling recurring events? I have seen a number of plugins take a start date and an end date and then just create a whole bunch of database entries for each event in a recurrence, somewhat bloating the database if you have a number of never ending recurring events. Is your way of handling recurring events more sophisticated?

G470 wants recurring events to show up in his normal loop. (Note: the recurring instances, not the original master event).

How are the events stored?

Each event is stored very similarly to the ICS file lines, while attempting to make maximum use of wordpress features and functions.  Each master event (or VEVENT) is one wordpress post (or custom post).  This allows the use of wordpress features, the wordpress query and other plugins with this plugin.  For example, some plugins you may wish to integrate are:

When a recurring ‘master’ event is displayed as a single post, the plugin calculates and displays the future ‘next dates’ – these change all the time as time passes.  Ditto for multiple event listings. See

In the loop?

The master events are displayed or returned  in the loop (if using standard posts or have configured custom posts to display ) sorted by publish date.     Shortcodes are available to list events sorted by their event instance dates.  In addition the function to list the events (amr_list_events) is pluggable, so you can even do your own thing, although generally it will be easier to customise a list type than to write your own whole display routine.

Event instances are themselves not typically displayed ‘in the loop’ for a number of reasons:

  • the loop normally displays posts by dates that have passed – future posted posts are not displayed ‘in advance’.  Events on the other hand, one needs to know in advance.
  • recurring events may result in multiple instances being shown one after another with unnecessary detail.  There are better ways to advise of forthcoming events (widgets, shortcodes, or calling from within a template file (eg: using do_shortcode();)

How are recurring events generated and displayed?

Event instances are displayable via shortcodes either in a page, a widget or within a master event.  The default display assumes that one is only interested in events in the not too distant future from now or from today.

Note: Although unlike Alice in Wonderlands memory which only works backwards, the amr-events plugin can work forwards and backwards, near or far – you can have your jam tomorrow as well as today and yesterday.  See the shortcode parameters for ideas on what you can do.

Thus the recurring logic is done real time for the most appropriate current window of time.  (IE, with respect to the current start date&time and with respect to configurable limits.)

The administrator sets how many days or months to generate for and how many events maximum.   These limits are used at a general/total level and at a specific level to provide some boundary for infinite events.   Administrators should choose limits that make sense for the frequency / density of their events.

The instances are then generated for that ‘window’ of time using some clever logic.

The logic follows the suggested rules found in various ics documentation with respect to ‘expanding’ and ‘contracting’ by the parts of the RRULE.   Needless to say it took a lot of design and coding to get this stable and coping with almost all the possible RRULES.  That part of the plugin has been around for a few years now and was rewritten at least once!

Mapping of WordPress Fields to ICS fields, or additional ‘displayed’ data

ICS => WordPress post

  • SUMMARY => post title
  • DESCRIPTION => post content
  • DTSTAMP => post published date
  • ORGANIZER => post author (may change later, currently NOT issued in ics file produced)

some ICS lines are stored as wordpress META data:

  • DTSTART
  • DURATION (OR DTEND, not both)
  • RRULE
  • EXDATE
  • RDATE
  • LOCATION (depending which location plugin is used)

Additional data:
Some data is generated at display time.  These are usually the ‘instance’ fields:

  • EventDate
  • EventTime
  • EndDate (of instance)
  • EndTime

Summary

Before feeling that you need to write your own code, please  explore other options

  • see  the variety of list types and the ways that you can customise them before deciding that you need to write your own listing routine.
  • explore other plugins that may integrate well as this plugin was designed to work well with wordpress and the tools that it provides.

This will hopefully save you a lot of time and trouble.