Add External Events to Calendar

This topic contains 13 replies, has 2 voices, and was last updated by  Stephen Harris 10 years, 5 months ago.

Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • #12282

    Hi Stephen!

    Love your WordPress tutorials and have been (mostly) loving your Event Organiser Plugin! What an honour it is to finally request support from you (haha).

    Okay, so here’s the problem: we’d like your Events Organiser to do something that (from what I gather), it wasn’t really intended to do but it may easily be capable of. I’m trying to create an Event Organiser Calendar with events from more than one site so that we can give students an easier time of finding cool stuff on campus.

    I’ve read through some of the answers in this forum and some of them approach what I’m asking for (for example, http://wp-event-organiser.com/forums/topic/sharing-events-across-wordpress-sites/), but I’m afraid not all of the events we want to add to the calendar are from other Event Organisers. (ie, not sure the iCal feeds are going to cut it.)

    So, hypothetically, if I’d rigged up a JSON API backend plugin that could beam out events from another site (in the same format that EO expects, and we can specify by the same start and end parameters that EO does), would it be possible to add these external events to the calendar just before the locally-stored events were rendered (or just before they were normalised for rendering)? I mean, it looks to me like it should be possible (to add another source, for example, and get more events via ajax), only I’m much more comfortable in PHP than JavaScript, and it looks to me like your EventManager object is doing a lot of the heavy lifting.

    Yes, so I’m not asking you to do any coding or anything like that. I’m just curious if there would be a way to add another external event source to the calendar, and, if there were, if you could suggest a way to go about it. Would be super cool if there were.

    Thanks for listening!

    Paul

    Geoff Pimlatt
    #12292

    Hi Paul,

    Glad you to hear you like the tutorials and Event Organiser :).

    I think you’re just talking about the (full)calendar here – which is populated by an AJAX request to the server. The events are pulled out of the database, and an array is populated, before being returned to the client to display on the browser. (Out of that context, things can get really messy, really quickly).

    Unfortunately there is no where to ‘inject’ those external events. This is a minor problem, because I’d be happy to add a filter. But without that, it would be impossible: trying to inject events ‘before the loop’ can be done, but it will probably fail. As the plug-in loops through the events, populating the above mentioned array, it uses the API which expects an event ID, which simply won’t exist in the case of external events.

    Event with a filter added, and the events injected. A external HTTP request to fetch these events will drastically slow the site down to the point where you would want to at least cache these events. But then if you are caching these events, you perhaps may as well as store them in the database. (That said, the entire response sent to the client is cached as well).

    You mentioned that not all sources would be Event Organiser powered sites, so iCal might not cut it. It wouldn’t matter if they are run by Event Organiser, so long as they provide an iCal feed. Failing that, you could set up a JSON feed to broadcast the data, and have a listener to periodically pull in the events locally. (This is essentially what the iCal sync plug-in does, except you would be using a different format of feed).

    Of course you might not want to pull in events locally as you don’t want the events on your site, but just to point to the source site. In these situations, you could do the above, but assign them a custom taxonomy term (indicating their source), and exclude any of these events from the front-end, and even use WordPress’ filters to change their url to the source site. In this way the events exist on your site as a ‘ghost’ event. Present only for easy querying. You could even set up redirects in case a nosey visitor tried to force they way onto this ‘ghost’ event by finding its ID and visiting yoursite.com?p=[ID] (or perhaps, more likely, to stop a bot from indexing it…).

    Stephen Harris
    #12316

    Hello again Stephen,

    You’re right about the fullcalendar: rendering external events side-by-side with our locally-hosted events on the main site calendar is basically the meat and potatoes of what I’m trying to do. I’m not too interested in having much of a front-end for these external events: ie, generating pages for them or whatever, just as long as you can see them on the calendar.

    I’ve also worked out a caching system, so no worries on that front. I’ve been working on this for a few weeks now, so I’m at a point where I have a plugin that accepts external event data (and caches it if it’s not in the cache), and then I’ve got a shortcode printing the events to the screen. So I’ve got some event data and I’ve worked it out so that it’s not a huge performance issue. I’m using the WordPress Transient API, so I’ve not got them in a backend database table or anything, but the JSON response is accessible if you have the name to call it with.

    So, yes, I’m aiming for a solution like what you outlined in your last paragraph. Pull in a bunch of events that aren’t really discoverable on the frontend except for the calendar, give them all externally-facing URLs, and redirect nosy robots. At this point, I have the event data and I’m caching stuff so that nothing is lagging behind terribly, but I’m not really sure where or if it’s possible to try and pass them off to your plugin.

    You mentioned adding a filter somewhere? Where would it make sense to put it?
    Would it help me out to get the iCal sync plugin?

    Paul

    Geoff Pimlatt
    #12335

    In that case, I don’t think you’ll need the iCal plug-in.

    The filter will go in event-organiser-ajax.php to filter ther server’s response to the ajax request. Specifically line 70 and line 260.

    I’ve opened up this issue for it so I don’t forget to include it in 2.9.0.

    Stephen Harris
    #12339

    Thank you, Stephen! That would be perfect!

    Geoff Pimlatt
    #12343

    Hello again, mate,

    Hope you’re not tired of hearing from me yet.

    I have a few more thoughts on this, now that we’re veering towards specifics.

    1. Parameters<br>
      I’ve been thinking about what information it would be absolutely necessary to get back from your filter, and so far all I’ve come up with is the start + end dates. (They’re the first thing you set in the $request array, yeah?) I mean, it would be probably nice to have the time formatting and date formatting as well just so as to play nice with what you’re doing, but the start + end dates are probably the most essential. The timezone seems to be something any code running on the same server can replicate. The categories + venues + tags wouldn’t really help in terms of narrowing down the actual event data, but I’m thinking that a specific category or tag could be used as a flag to indicate whether this particular calendar wants external events at all. So maybe passing one of those would be helpful.<br>Other considerations?

    2. Other Widgets<br>
      Haha, give an inch and they’ll take a mile, eh? I was looking through your demo (not the code yet) and was wondering if the same filter could be used for a few of the filters, specifically (in decreasing order of preference) the Event List Widget, the Agena Widget, and the Simplified Calendar widget. The location map, and category + venue lists I don’t think would work because of the inconsistency of the data I’m using, and the event archive is obviously meant for events in the database. Yeah, so I was just wondering about the possibility of including this filter in the widgets.<br>If this is any kind of headache, then don’t worry about it, but if it’s easy to replicate the filters in the widgets, then that would be excellent!

    3. JS Callback Method<br>
      Would be super-duper cool if there were a way of firing some JavaScript once the events are returned (or, more likely) rendered. Even if it was just listening for an event (like a .change() listener on the calendar or something). Does this currently exist? If not, would it be easy to add?

    Again, I’m sorry I keep pestering you. I could try my hand at doing a github pull request if you didn’t want to be bothered with all this extra work.

    Thanks for everything so far, Stephen! You’re a champ!

    Paul

    Geoff Pimlatt
    #12368

    Hi Paul,

    Regarding parameters, I’d recommend taking a look at includes/event-organiser-ajax.php, lines ~85-249. For details on what you can send to the calendar. These properly should including

    • start & end datetime ( format Y-m-d\TH:i:s\Z ) e.g. “2014-09-02T12:41Z”
    • allDay – (boolean)
    • classNameeo-event
    • title
    • url
    Stephen Harris
    #12402

    Hi again Stephen!

    I’m afraid you misunderstood me. I was asking about what parameters you might put in your filter so that *someone* wanting to add external events could get some information about the events to return.

    I’ve got it working in theory (creating a fake event and sending it back), and I’ve modified your source code (at line 260 in includes/event-organiser-ajax.php) with a filter I’ve come up with that sends off the events array, timezone, and start and end dates as parameters. Basically, like this. so:

    $eventsarray = apply_filters( 'eventorganiser_inject_my_events', $eventsarray, $tz, $request['event_end_after'], $request['event_start_before'] );

    And then I’m sending back events with the following array properties:

    • className
    • title
    • url
    • allDay
    • start
    • end
    • allDay
    • description
    • category ( empty array )
    • tags ( empty array )
    • color
    • textColor

    I was thinking that it would also be really useful to get the start and end dates from your filter, the time and date formats as selected by the user (as well as the timezone), and some kind of flag which would indicate whether this particular calendar should accept external events at all (maybe passed in as a specific tag or category value?). Am curious to know what you think — have I missed anything?

    • This reply was modified 10 years, 6 months ago by  Geoff Pimlatt. Reason: removed unnecessary tag
    Geoff Pimlatt
    #12406

    Ah I see, the first argument will the the array of events (obviously), and the second would probably be the query as passed to eo_get_events() (which could include category/venues).

    The timezone can be obtained from eo_get_blog_timezone().

    Stephen Harris
    #12444

    Hi Stephen!

    Thanks for your suggestion the other day. I am currently using a filter I’ve done up myself just before the if( !$calendar || !is_array($calendar) ) check in includes/event-organiser-ajax.php and everything is going swimmingly.
    Filter looks like this, as per your suggestion: $eventsarray = apply_filters( 'eventorganiser_inject_my_events', $eventsarray, $query );

    Still wondering about my earlier questions, but I’ve opened another thread for the more general one.
    To carry on this one though (as it still relates to injecting external events):

    • Would it be possible to inject events into a list view (such as the agenda widget or the list widget)? It looks like the Agenda Widget uses an ajax method that is very similar to the fullcalendar — not too sure about the Event List Widget.

    As always, thanks for all your hard work Stephen! Overall very pleased with Events Organiser!

    Paul

    Geoff Pimlatt
    #12446

    Just wanted to clarify a little why this would be useful.

    The fullcalendar is an excellent way to display events: it’s an easy format to understand and it works for people.

    Unfortunately, while the fullcalendar does scale to some extent, it’s not possible to display it properly on a mobile phone. The benefit of the Event List or the Agenda Widget would be providing a mobile-responsive Event List, which — you can imagine — would be a huge benefit. (Now that I’ve looked into it a bit more, the Agenda Widget is probably more useful than the Event List because it’s dynamic. Doesn’t matter that it’s a widget — I can work around that.)

    So if it wouldn’t be too much work to put a similar filter into one of your event lists, I would be extremely grateful.

    Paul

    Geoff Pimlatt
    #12472

    There are steps that you can take to make the fullCalendar more suitable for mobile devices, (e.g. hiding unnecessary buttons from the header). But the calendar does display a lot of information, which is difficult to present on mobile devices. For this reason I am looking into adding support for response calendars (e.g. see http://tympanus.net/Development/Calendario/index2.html for the inspiration). However, these have a more simplistic approach to events which isn’t immediately suited to the more complex long/short part-day/all-day events supported by Event Organiser & fullCalendar, so this may take time.

    Regarding the agenda widget – I’m reluctant to add a filter for this is just yet, as I am to complete overhaul it’s inner-workings. The aim is to have a single json output for events so any javascript based calendars/list use the same source, and display it as appropriate. For the time being, though, is the following:

    add_action( 'wp_ajax_nopriv_eo_widget_agenda', 'my_widget_agenda_output', 5 );
    add_action( 'wp_ajax_eo_widget_agenda', 'my_widget_agenda_output', 5 );

    Your function my_widget_agenda_output() would then be responsible for printing an appropriate json array and killing the process. In practise you can copy eventorganiser_widget_agenda() function, and insert your own external events where desired. This will work up until (probably 3.0.0), when the agenda widget will enjoy a (much-needed) complete rewrite, and there should be a ‘standard’ json source to be used by the agenda widget / fullcalendar and any other responsive calendars added.

    Stephen Harris
    #12640

    Hi again Stephen!

    Just calling in to say that the problems have been resolved on our end. (Hooray!)

    In thinking about a mobile events widget, I realized that the philosophy behind the event/agenda list widget and the fullcalendar are different enough that I didn’t want to use them. I didn’t want a certain number of upcoming events, I just wanted a list view of the exact same events that were on the fullcalendar, with the same header controlling the content.

    So, we’ve ended up just working with the fullcalendar filters you put in (thanks very much!!) as well as the JS eventorganiser.fullcalendar_render_event hooks to build a list view for smaller screens based on the events returned to the fullcalendar.

    Updated Event Organiser today and everything’s working perfectly.

    Thanks for the help, and sorry if I caused you any headaches!

    Paul

    Geoff Pimlatt
    #12645

    Great, glad to hear it :).

    Stephen Harris
Viewing 14 posts - 1 through 14 (of 14 total)
To enable me to focus on Pro customers, only users who have a valid license for the Pro add-on may post new topics or replies in this forum. If you have a valid license, please log-in or register an account using the e-mail address you purchased the license with. If you don't you can purchase one here. Or there's always the WordPress repository forum.