Using RSS/Atom feeds with JSON to drive a Simile Timeline

This application of MIT Simile’s marvellous Timeline widgety thing is based around WordPress and RSS, but with small tweaks should be applicable to Movable Type, Atom and so on.

You may prefer to use a fine hosted service like MyTimelines if you don’t have the time to do this and if you’re prepared to accept their limitations and whatever their commercial angle is.

You’ll need to correct WP’s “smart” quotes if you copy-paste, and, since I dunnit quickly (this is my ┬ícor! business) and I’m quite extraordinarily ill-informed about this kind of thing, I take no responsibility for anything that may happen to you or your domestic animals:

  1. Create a new feed processor to get all the stuff you need without fiddling around with Javascript. Here’s mine (which suffers slightly from a weird thing in WP 2.0.5 that doesn’t let you overrule the recent posts setting in reading options):
    <?php

    if (empty($wp)) {
    require_once('wp-config.php');
    wp('feed=rss2');
    }

    header('Content-type: text/xml; charset=' . get_settings('blog_charset'), true);
    $more = 1;

    ?>
    <?php echo '<?xml version="1.0" encoding="'.get_settings('blog_charset').'"?'.'>'; ?>

    <!-- generator="wordpress/<?php bloginfo_rss('version') ?>" -->
    <rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    <?php do_action('rss2_ns'); ?>
    >

    <channel>
    <title><?php bloginfo_rss('name'); ?></title>
    <link><?php bloginfo_rss('url') ?></link>
    <description><?php bloginfo_rss("description") ?></description>
    <start><?php echo mysql2date('Y-m-d H:i:s', get_lastpostmodified('GMT'), false); ?></start>
    <generator>http://wordpress.org/?v=<?php bloginfo_rss('version'); ?></generator>
    <language><?php echo get_option('rss_language'); ?></language>
    <?php do_action('rss2_head'); ?>
    <?php $items_count = 0; if ($posts) { foreach ($posts as $post) { start_wp(); ?>
    <item>
    <?php
    $tit = get_the_title();
    if (strlen($tit) > 26) { $tit = substr($tit, 0, 23); $tit .='...'; }
    ?>
    <title><?php echo $tit ?> (<?php comments_number('0', '1', '%'); ?>)</title>
    <link><?php permalink_single_rss() ?></link>
    <icon>http://oreneta.com/oreneta/img/layout/t.gif</icon>
    <start><?php echo mysql2date('Y-m-d H:i:s', get_post_time('Y-m-d H:i:s', true), false); ?></start>
    <end></end>
    <color>#0066ff</color>
    <?php if (get_settings('rss_use_excerpt')) : ?>
    <description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
    <?php else : ?>
    <description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
    <?php if ( strlen( $post->post_content ) > 0 ) : ?>
    <content:encoded><![CDATA[<?php the_content('', 0, '') ?>]]></content:encoded>
    <?php else : ?>
    <content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
    <?php endif; ?>
    <?php endif; ?>
    <?php do_action('rss2_item'); ?>
    </item>
    <?php $items_count++; if (($items_count == 250) && empty($m)) { break; } } } ?>
    </channel>
    </rss>
  2. Edit wp-feed.php to reflect this. Here’s mine:
    <?php

    if (empty($doing_rss)) {
    $doing_rss = 1;
    require(dirname(__FILE__) . '/wp-blog-header.php');
    }

    // Remove the pad, if present.
    $feed = preg_replace('/^_+/', '', $feed);

    if ($feed == '' || $feed == 'feed') {
    $feed = 'rss2';
    }

    if ( is_single() || ($withcomments == 1) ) {
    require(ABSPATH . 'wp-commentsrss2.php');
    } else {
    switch ($feed) {
    case 'atom':
    require(ABSPATH . 'wp-atom.php');
    break;
    case 'rdf':
    require(ABSPATH . 'wp-rdf.php');
    break;
    case 'rss':
    require(ABSPATH . 'wp-rss.php');
    break;
    case 'rss2':
    require(ABSPATH . 'wp-rss2.php');
    break;
    case 'iso':
    require(ABSPATH . 'wp-rss-iso.php');
    break;
    case 'comments-rss2':
    require(ABSPATH . 'wp-commentsrss2.php');
    break;
    }
    }

    ?>
  3. Create a folder somewhere. I’ve kept it out of the way of my WP installation.
  4. Upload Magpie RSS into it. This is the bit that fetches your feed. It caches–so you can make the number of posts served up in your feed quite large–but you’ll probably need to create the cache folder yourself.
  5. Upload JSON.php. Put it in the same folder if you want to make your life easy.
  6. Create a file to take Magpie and pass it through JSON.php. You’ll need to alter the feed called at the beginning and at some stuff at the end to make the output easily recognisable by Timeline. Here’s mine, based on something whose address I’ve forgotten (sorry!):
    <?php
    // user input
    $feed = (isset($_GET['feed']) ? $_GET['feed'] :
    'https://elorganillero.com/blog/?feed=iso');
    $callback = (isset($_GET['callback']) ? $_GET['callback'] : FALSE);

    require('rss_fetch.inc'); // From MagpieRSS
    require('JSON.php'); // From JSON-PHP

    // fetch the RSS feed
    $rss = fetch_rss($feed);

    // new JSON object
    $json = new services_JSON();

    // encode the RSS feed
    $output = $json->encode($rss->items);

    if($callback) {
    $output = htmlspecialchars($callback) . "(" . $output . ");";
    }

    // display the JSON output
    ?>

    {
    'dateTimeFormat': 'iso8601',
    'events' :

    <?php
    print $output;
    ?>

    }

    <?php
    ?>
  7. Call this file and style it on another page. Mine is here, and uses stuff by Juan Manuel Caicedo and Kiyo, amongst others.

Here it is as an iframe (my server seems to dislike includes), but the standalone is easier on the brain:

I’d be interested to know how well a file of this size actually works in a place with a normal connection–I’m sharing a public satellite facility in the mountains with half a dozen small boys playing Habbo Hotel, so things are fairly slow.

Similar posts


Comments

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