Creating a Custom Tumblog with SimplePie, RSS Feeds & WordPress
It’s interesting how projects can completely change from the way you first planned them to be. For February’s 12412 project, I originally wanted to play with social media APIs to create a custom tumblog of every site I’ve ever been a part of, in addition to learning PHP to add them all together.
I took one look at the API documentation of Twitter and I admin – I chickened out. Actually, I didn’t so much as chicken out as I was turned off by the crappy documentation – I mean, how hard is it to show some nice examples for beginners? I also quickly realized that most of these services had a pre-made RSS feed of activity that you could just grab – so I got an idea.
SimplePie
WordPress has a built in SimplePie function that allows you to display RSS feed content from any link, even if off-site. Here’s the basic SimplePie function:
<?php // Get RSS Feed(s) include_once(ABSPATH . WPINC . '/feed.php'); // Get a SimplePie feed object from the specified feed source. $rss = fetch_feed('http://example.com/rss/feed/goes/here'); if (!is_wp_error( $rss ) ) : // Checks that the object is created correctly // Figure out how many total items there are, but limit it to 5. $maxitems = $rss->get_item_quantity(5); // Build an array of all the items, starting with element 0 (first element). $rss_items = $rss->get_items(0, $maxitems); endif; ?> <ul> <?php if ($maxitems == 0) echo '<li>No items.</li>'; else // Loop through each feed item and display each item as a hyperlink. foreach ( $rss_items as $item ) : ?> <li> <a href='<?php echo esc_url( $item->get_permalink() ); ?>' title='<?php echo 'Posted '.$item->get_date('j F Y | g:i a'); ?>'> <?php echo esc_html( $item->get_title() ); ?></a> </li> <?php endforeach; ?> </ul>
This function is great when displaying a feed on it’s own, but I wanted one feed line that displayed everything in correct chronological order.
In order to accomplish this, we’ll need to create an array to dump everything into and then spit it back out. On top of that, each feed item has it’s own layout and icon, so we’ll need a way to identify the type of update.
The Feeds
Let’s start with a basic array
// Using WordPress's SimplePie RSS function // We'll call each feed and place into an array include_once(ABSPATH . WPINC . '/feed.php'); // Create the array $feed = array();
The first item I added was the easiest – just my own blog. We’ll use the first part of the standard WordPress fetch_feed function to call the feed URL and let SimplePie know how many feeds we want to display. Since I had a ton of services I was adding, I decided not to display more than 20 from each feed.
$rss = fetch_feed('http://www.amberweinberg.com/feed'); if (!is_wp_error( $rss ) ) : $maxitems = $rss->get_item_quantity(20); $rss_items = $rss->get_items(0, $maxitems); endif;
Now we get to the trickier part. We’ll start off by adding an if statement, so if there are no updates to show (or an error), it displays a message, otherwise we’ll need to loop through each update and grab the important parts. For the blog, I only wanted to display the linked title and date of the post. You can checkout SimplePie’s documentation to get an idea of what arguments you can use.
We’ll set a variable for each feed, for the dev blog, I used ‘wp’ for WordPress. we’ll then need to set a type for the array, WP, which is what will be printed as the class name for CSS, as well as allow us to switch out the layouts later on.
if ($maxitems == 0) echo '<li>Gasp! There are no posts from my dev blog.</li>'; else foreach ( $rss_items as $item ) : $wp = array('type' => 'WP'); $wp['time'] = strtotime($item->get_date()); $wp['link'] = $item->get_link(); $wp['title'] = $item->get_title(); $feed[ $wp['time'] ] = $wp; endforeach;
You’ll see the last line before the endforeach statement, that I attached the key ‘time’ to the feed variable. I’ll explain what that does in a bit.
Now all you need to do is add each feed you want to use, being sure you change the variables on the left side of the foreach and the $rss variables to something unique. We can also use other items than just the link and title.
For example, here’s the code I used for Pinterest:
$rss8 = fetch_feed('http://pinterest.com/amberweinberg/feed.rss'); if (!is_wp_error( $rss8) ) : $maxitems8 = $rss8->get_item_quantity(20); $rss_items8 = $rss8->get_items(0, $maxitems8); endif; if ($maxitems8 == 0) echo '<li>I can\'t believe she hasn\'t found anything to pin!</li>'; else foreach ( $rss_items8 as $item8 ) : $pinterest = array('type' => 'pinterest'); $pinterest['time'] = strtotime($item8->get_date()); $pinterest['description'] = $item8->get_description(); $pinterest['link'] = $item8->get_link(); $pinterest['title'] = $item8->get_title(); $feed[ $pinterest['time'] ] = $pinterest; endforeach;
A few of the services I wanted to use didn’t have a feed at all (boo! I say!) so I had to “make” my own. Lanyrd didn’t have a feed at all, and Foursquare and Github’s wouldn’t work for some reason. Interestingly enough, I found three different solutions to these issues.
For Foursquare, I simply added the feed to Feedburner and it worked. This solution, however, didn’t work for Github, and Lanyrd didn’t have a feed at all. Lanyrd did, however, have an iCal feed and Thanks to Paul Maloney‘s suggestion, I turned to Yahoo Pipes for both solutions. If you’ve never used Pipes before, it is one of THE most complicated looking pieces of software to use, but once you figure it out, it can actually do some fantastic functions without you ever needing to touch the code.
It took hours to figure out how to get iCal fed into the Pipe correctly and made into an RSS feed, and then even longer to get the date working, but I finally did. To save you the cursing, you can use mine (you fork it like in Github) to add your own Lanyrd iCal feed in. Taking Github’s broken atom feed to RSS in Pipes was pretty quick and easy, and you can grab that one as well. From there you just add it in like the rest of the items.
Sorting the Feeds In Time
Now, remember when I mentioned adding the time key to the $feed array? If not, here it is again from the example above:
$feed[ $pinterest['time'] ] = $pinterest;
We do this because we want to sort our items according to their time and date and list them in chronological order. This is surprisingly easy with one line of code, placed after your RSS feeds:
//Now sort them (Keys are timestamps) krsort($feed);
Displaying the Feeds
The first line in our foreach was assigning a unique name to the feed in order to be able to sort it later. This is where we’ll do that. I’ll first show you my code, and will explain it after.
<?php foreach ($feed as $i): ?> <li class="<?php echo $i['type']; ?>"> <span class="icon"></span> <?php if($i['type'] == 'Twitter') : ?> <?php echo $i['text']; ?> <?php elseif($i['type'] == 'WP' || $i['type'] == 'WP2' || $i['type'] == 'github') : ?> <?php echo '<a title="'.$i['title'].'" href="'.$i['link'].'">'.$i['title'].'</a>' ?> <?php elseif($i['type'] == 'foursquare') : ?> <?php echo 'Amber was '.$i['description'].'' ?> <?php elseif($i['type'] == 'dribbble' || $i['type'] == 'Instagram' || $i['type'] == 'ravelry') : ?> <?php echo '<a title="'.$i['title'].'" href="'.$i['link'].'">'.$i['title'] .$i['description'].'</a>' ?> <?php elseif($i['type'] == 'pinterest') : ?> <?php echo $i['description'] ?> <?php elseif($i['type'] == 'meetup') : ?> <?php echo '<a title="'.$i['title'].'" href="'.$i['link'].'">I RSVP\'d to'.$i['title'].'</a>' ?> <?php elseif($i['type'] == 'lanyrd') : ?> <?php echo 'I\'m attending <a title="'.$i['title'].'" href="'.$i['link'].'">'.$i['title'].'</a> on '.date('jS M Y', $i['time']) ?> <?php elseif($i['type'] == 'goodreads') : ?> <?php echo '<a title="'.$i['title'].'" href="'.$i['link'].'">'.$i['title'].'</a>' .$i['description'] ?> <?php elseif($i['type'] == 'codesnippit') : ?> <?php echo '<a title="'.$i['title'].'" href="'.$i['link'].'">'.$i['description'].'</a>' ?> <?php endif; ?> <span class="time"><?php echo date('D jS M - g:i a', $i['time']); ?> from <?php if($i['type'] == 'Twitter') : ?> <a title="Follow me on twitter" href="http://twitter.com/amberweinberg" target="_blank">Twitter</a> <?php elseif($i['type'] == 'Instagram') : ?> <a title="Follow me on instagram" href="http://instagram.com/amberweinberg" target="_blank">Instagram</a> <?php elseif($i['type'] == 'WP') : ?> <a title="Read the blog" href="/category/blog">the development blog</a> <?php elseif($i['type'] == 'WP2') : ?> <a title="Read the blog" href="http://www.amberweinberg.com/design" target="_blank">the design blog</a> <?php elseif($i['type'] == 'foursquare') : ?> <a title="Follow me on foursquare" href="https://foursquare.com/amberweinberg" target="_blank">Foursquare</a> <?php elseif($i['type'] == 'dribbble') : ?> <a title="Follow me on Dribbble" href="http://dribbble.com/amberweinberg/" target="_blank">Dribbble</a> <?php elseif($i['type'] == 'github') : ?> <a title="Follow me on github" href="https://github.com/amberweinberg" target="_blank">Github</a> <?php elseif($i['type'] == 'ravelry') : ?> <a title="Find me on ravelry" href="http://www.ravelry.com/projects/amberweinberg" target="_blank">Ravelry</a> <?php elseif($i['type'] == 'pinterest') : ?> <a title="Find me on pinterest" href="http://pinterest.com/amberweinberg" target="_blank">Pinterest</a> <?php elseif($i['type'] == 'goodreads') : ?> <a title="Find me on goodreads" href="http://www.goodreads.com/user/show/2891681-amber-weinberg" target="_blank">Goodreads</a> <?php elseif($i['type'] == 'lanyrd') : ?> <a title="Find me on lanyrd" href="http://lanyrd.com/profile/amberweinberg/" target="_blank">Lanyrd</a> <?php elseif($i['type'] == 'meetup') : ?> <a title="Find me on meetup" href="http://www.meetup.com/The-London-Knitting-Group/members/6078908/" target="_blank">Meetup</a> <?php elseif($i['type'] == 'codesnippit') : ?> <a title="Find me on codesnippit" href="http://codesnipp.it/amberweinberg" target="_blank">Codesnippit</a> <?php endif; ?> </span> </li> <?php endforeach; ?>
If I just blew your brain up, I apologize! I wanted each type to have a different layout and link, so it was quite a bit of code, but very simple code.
We just simply use a foreach to cycle through each feed item and list them out one by one. From there, the rest is regular code –
I echoed the type as the class in each line item:
<li class="<?php echo $i['type']; ?>">
And I also used it to switch between different displays and layouts, here’s one for my WordPress feeds
<?php elseif($i['type'] == 'WP' || $i['type'] == 'WP2' || $i['type'] == 'github') : ?> <?php echo '<a title="'.$i['title'].'" href="'.$i['link'].'">'.$i['title'].'</a>' ?>
What’s Next?
You’ll notice that it starts to load pretty slowly, especially on my own as I’m using 13 different services. I’d also like to go back more than 20 items, so I need to try and figure out a way to get some pagination going. Perhaps that can be for another month’s 12412
Find this project on Git
See Demo
Download the social media icons
Special thanks to Michael Martin for helping with the array.
Leave a Reply
