Importing Localist Events with Feeds

I’ve been fiddling around for a while with trying to figure out a good method for getting events out of our central events calendar. Colleagues and I had toyed with implementing modules to provide a block or custom Views code to feed JSON into a table or what have you. Recently I came across Baris Wanschers’ article about importing a twitter feed and realized it was exactly what we needed.

A grid of images and descriptions of upcoming events.

While I still think having some kind of Views module specific to this task would be useful, this works well as a simple solution leveraging existing modules.

What You Need

Create a Content Type

We’ll need to add a content type to store our events. For our example implementation, we’ll want to store the Event ID from Localist (so we can track which ones we’ve already imported), the event title, description, date, a link to the Localist page for the event, and a link to the event image.

Add a Feed Importer

You’ll want to navigate to admin/structure/feeds and create a new feed importer. Under basic settings, attach the importer to your newly-created content type. Next, you’ll want to change the parser from the default ‘Common syndication parser’ to the JSONPath parser.

Map Fields

Here’s where things get a little tricky. If you try to head straight to configuring the JSONPath parser at this stage, you’ll get stuck as the parser will complain that there are no mappings yet. Rather, you’ll need to head into the node processor mapping and start setting up your field mappings. For each field you want to import from Localist, add a mapping with ‘JSONPath Expression’ as the source value.

With your mappings done, head back to the JSONPath Parser settings. You should see fields to provide a global context and JSONPath expressions for each of the fields you’ve defined in your mapping.

To make sense of the expressions we need, let’s take a look at the Localist API documentation. Here’s a sample response to a list request:

[javascript]
{
"events": [
{
"event": {
"event_instances": [
{
"event_instance": {
"id": 452848,
"ranking": 0,
"event_id": 188155,
"start": "2013-10-09T10:00:00-04:00",
"end": "2013-10-09T17:00:00-04:00",
"all_day": false
}
}
],
"id": 188155,
"title": "Amy Sherald: Paintings",
"url": "http://www.rflewismuseum.org/exhibitions/special",
"updated_at": "2013-10-08T09:25:32Z",
"created_at": "2013-08-26T06:26:44Z",
"facebook_id": null,
"first_date": "2013-09-14",
"last_date": "2013-12-29",
"hashtag": "",
"urlname": "amy_sherald_paintings",
"user_id": 52182,
"directions": "",
"allows_reviews": true,
"location": "Reginald F. Lewis of Maryland African American History and C…",
"room_number": "",
"location_name": "Reginald F. Lewis of Maryland African American History and C…",
"created_by": null,
"updated_by": null,
"city_id": 1,
"neighborhood_id": 58,
"school_id": 55,
"campus_id": null,
"recurring": true,
"free": true,
"private": false,
"verified": true,
"rejected": false,
"sponsored": false,
"venue_id": null,
"ticket_url": "",
"ticket_cost": "",
"keywords": [

],
"tags": [

],
"description_text": "Known for her life-sized fantastical portraits of African Am…",
"photo_id": 76525,
"detail_views": 52,
"address": "830 E. Pratt St. Baltimore, MD 21202",
"description": "<p class="description">Known for her life-sized fantastical …",
"featured": true,
"geo": {
"latitude": 39.2873,
"longitude": -76.6038,
"street": "830 East Pratt Street",
"city": "Baltimore",
"state": "MD",
"country": "US",
"zip": "21202"
},
"filters": {
"event_types": [
{
"name": "Arts & Culture",
"id": 20196
}
]
},
"custom_fields": {
},
"localist_url": "http://events.wtmd.org/event/amy_sherald_paintings",
"photo_url": "http://images-cf.localist.com/photos/76525/huge/195a2ae18388…",
"venue_url": null
}
}
],
"page": {
"current": 1,
"size": 10,
"total": 10
},
"date": {
"first": "2013-10-08",
"last": "2013-11-07"
}
}
[/javascript]

We get an ‘events’ object that mas multiple ‘event’ objects under it, each of which have our event details. The trick, then, is to specify the global context as $.events.*.event, which allows us to then simply associate our node field names with the corresponding fields in our event object.

An example illustrating jsonpath parser configuration.Tamper With Things

Since we’re not directly importing images from Localist, we won’t be able to do any image processing on our end to do re-sizing. The image URL returned in the feed will be pointing to the originally uploaded image, so consistency is going to be a problem. Fortunately, Localist also exposes their re-sized images, you just have to know where to look for them.

Take a look at an example value for the ‘photo_url’ field:


http://images-cf.localist.com/photos/70006/huge/80bf4232a5da29fe7173fd9603a11a5152373c45.jpg

See that bit that says /huge/? Turns out you can pass that different values to get different image sizes. Replace that with /big/ and, in our instance at least, you’ll get a nicely scaled and cropped image.

Enter Feeds Tamper. This is a versatile little module that allows you to alter your feed’s source data before importing the node. While it’ll do a lot of things, we’re just going to use it for a simple find and replace, to change all of our image URLs to reference the image format we want.

Back on admin/structure/feeds, you’ll notice a link next to your new feed importer that says ‘tamper’. Click that, find your Image URL field, click ‘add plugin,’ search for the ‘Find replace’ action, and set it to search for /huge/ and replace it with /big/.

Start the Importer

We’re done with most of the configuration for this, now we just need to kick off the importer and point it at our data source. Head to Add Content and add an event node. For the feed URL, you could certainly just plugin ‘http://calendar.uoregon.edu/api/2/events/’ and have it work, but you’ll need to craft your URL if you don’t want to drink from the firehose and get every single upcoming event. I’ll point you to the Localist API documentation again at this point, specifically in the section that discusses the event list query and passing filters to it.

Make a View

You know how to do this part, right? Events should start flowing in and showing up as nodes, so you can do whatever you want with them at this point. We’re done!

2 thoughts on “Importing Localist Events with Feeds

    • I never did wind up trying to cross that bridge, no. It seemed to me that the only way that would be useful would have been to somehow create separate instances of the event for each item in that event date array, or maybe to somehow map that to a multiple-value field and then figure out how to deal with the presentation on the frontend.

      Honestly, since writing this post originally, there’s a few things about my implementation that could definitely be improved if I had to do it over again. If you do figure something out, I’d love to see your take on the idea.

Leave a Reply

Your email address will not be published. Required fields are marked *