Import and Display RSS Feeds in WordPress
Importing and displaying external RSS feeds on your site is a great way to share your online activity with your visitors. If you are active on Flickr, Delicious, Twitter, or Tumblr, your visitors will enjoy staying current with your updates. Many social media sites provide exclusive feeds for user-generated content that may be imported and displayed on virtually any web page. In this article, you will learn three ways to import and display feed content on your WordPress-powered website — without installing yet another plugin.
On the menu for this tutorial:
- Import and display feeds with WordPress & Magpie (basic method)
- Import and display feeds with WordPress & Magpie (advanced method)
- Import and display feeds with SimplePie (WordPress not required)
Sound good? Let’s get to it..
Import and display feeds with WordPress & Magpie (basic method)
If you only need to display the titles of a feed, you can take advantage of the built-in WordPress function, wp_rss()
, which provides WordPress with essential feed-fetching and feed-parsing functionality. All you need to do is place the following code into the desired display location within your theme template file (e.g., sidebar.php
):
<?php include_once(ABSPATH.WPINC.'/rss.php');
wp_rss('http://domain.tld/your-feed/', 7); ?>
In the first line, we include the required wp_rss()
function from the rss.php
file (rss-functions.php
in older versions of WordPress). In the second line, we specify two parameters: the first is our feed URL and the second is the number of titles to display. Simply edit these two parameters and enjoy the results.
Import and display feeds with WordPress & Magpie (advanced method)
Magpie provides an XML-based RSS built with PHP. WordPress uses Magpie to parse RSS and Atom feeds and display them on your website. Magpie parses feeds for two different WordPress functions:
wp_rss()
– fetches and parses feeds for instant/automatic outputfetch_rss()
– fetches and parses feeds for advanced/custom output
Each of these functions uses the Snoopy HTTP client for feed retrieval, Magpie for feed parsing, and RSSCache for automatic feed caching. Feel free to change those up however with other services, scripts, etc.
The wp_rss()
function fetches and parses feed content and then outputs an unordered list containing each of the feed’s post titles (see previous section). The fetch_rss()
also fetches and parses feed content and will output the results according to your specific script configuration. Instead of just spitting out titles, the fetch_rss()
function enables us to display any available feed data in customized format. Let’s look at an example.
<?php
include_once(ABSPATH.WPINC.'/rss.php'); // path to include script
$feed = fetch_rss('http://domain.tld/your-feed/'); // specify feed url
$items = array_slice($feed->items, 0, 7); // specify first and last item
?>
<?php if (!empty($items)) : ?>
<?php foreach ($items as $item) : ?>
<h2><a href="<?php echo $item['link']; ?>"><?php echo $item['title']; ?></a></h2>
<p><?php echo $item['description']; ?></p>
<?php endforeach; ?>
<?php endif; ?>
Once placed in the desired location in your WordPress theme template file, the previous code will output the title and description (content) of the seven most recent feed items. Simply edit the three variables in the first three lines of the script and you are good to go. Then, once you see that everything is working as intended, feel free to modify the markup as you see fit. Before moving on, let’s walk through the method in sequential fashion:
- Include the script – specify the path to
rss.php
(orrss-functions.php
in older versions of WordPress) - Specify feed URL – specify the URL of the feed you would like to display
- Limit number of items – edit the two numbers to reflect the numbers of the first and last feed items, respectively
- Empty check – before running the loop, check that the feed isn’t empty
- Begin the loop – begin the standard
foreach
loop - Display the items – for each feed item, display the post title, title link, and post content
- Wrap it up – close the loop and end the empty check
Notes on using WordPress/Magpie
If you are calling feeds that may or may not include a description, you may want to avoid the output of empty paragraph elements ( <p>
) by wrapping the description with a conditional check like so:
<?php if (isset($item['description'])) : ?>
<p><?php echo $item['description']; ?></p>
<?php endif; ?>
Also, if the feed isn’t showing, try replacing the associated line with this:
$feed = @fetch_rss('http://domain.tld/your-feed/');
For an alternate way of checking for the presence of a working feed, replace the empty check with this:
<?php if (isset($rss->items) && 0 != count($rss->items)) : ?>
You can also clean up feed output by taking adavantage of WordPress’ built-in filtering functionality:
<?php echo wp_filter_kses($item['link']); ?>
<?php echo wp_specialchars($item['title']); ?>
Here are some of the variables that are available from your feeds (not sure if all of these work):
$item['link']
– post permalink$item['title']
– title of the post$item['pubdate']
– post publication date$item['description']
– post excerpt or content$item['creator']
– post author (does this work?)$item['content']
– post content (does this work?)
Note that when using the $item['pubdate']
variable, the default output will look like this:
Mon, 11 Jul 2050 01:11:11 +0000
Fortunately we can clean this up a little bit by parsing it with PHP’s substr()
function like so:
$pubdate = substr($item['pubdate'], 0, 16);
Which will output the following date format:
Mon, 11 Jul 2050
And, finally, an alternate loop format that defines the number of items to display without using the array_slice()
function:
<?php for($i = 0; $i < 5; $i++) { $item = $rss->items[$i]; ?>
<!-- loop content -->
<?php } ?>
Importing and displaying feeds with SimplePie (WordPress not required)
For more robust feed fetching in the most simple way possible, SimplePie is the perfect choice. SimplePie is a blazing fast PHP class that is easy to learn and simple to use. With a few quick steps, you can use SimplePie to retrieve and parse any RSS or Atom feeds and display them on any PHP-enabled website (WordPress is not required).
SimplePie works great with its default settings, but it is also highly customizable. You can use SimplePie to display any type of data from any number of feeds, and it even works without WordPress. Sound good? Here’s how to setup SimplePie in three easy steps:
- Download SimplePie and unzip
- Place the “
simplepie.inc
” into a folder named “php
” located in the web-accessible root directory of your website - Create a folder named “
cache
” (also in the web-accessible root directory) and make it writable by the server (i.e., CHMOD to 755, 775, or 777)
That’s all there is to it. Once SimplePie is properly setup on your server, you may check that it’s working by uploading the following code to the web page of your choice (edit as specified):
<?php // basic functionality check - edit script path and feed url
include_once $_SERVER['DOCUMENT_ROOT'].'/php/simplepie.inc'; // script path
$feed = new SimplePie('http://domain.tld/your-feed/'); // feed url
<h1><?php echo $feed->get_title(); ?></h1>
<p><?php echo $feed->get_description(); ?></p>
If the feed title and description don’t appear on the page, check the path to simplepie.inc
in the first line and also verify that the feed URL is correct and that the feed is working properly.
Once everything is working and flowing like butter, the possibilities are endless. To get you started, let’s expand the previous “testing” code to include the title, link, content and date for the seven most recent feed items:
<?php
include_once $_SERVER['DOCUMENT_ROOT'].'/php/simplepie.inc'; // path to include script
$feed = new SimplePie(); // bake a new pie
$feed->set_feed_url('http://domain.tld/your-feed/'); // specify feed url
$feed->set_cache_duration (999); // specify cache duration in seconds
$feed->handle_content_type(); // text/html utf-8 character encoding
$check = $feed->init(); // script initialization check
?>
<h1><a href="<?php echo $feed->get_permalink(); ?>"><?php echo $feed->get_title(); ?></a></h1>
<p><?php echo $feed->get_description(); ?></p>
<?php if ($check) : ?>
<?php foreach ($feed->get_items(0, 7) as $item) : ?>
<h2><a href="<?php echo $item->get_permalink(); ?>"><?php echo $item->get_title(); ?></a></h2>
<p><?php echo $item->get_description(); ?></p>
<p><small>Posted on <?php echo $item->get_date('j F Y @ g:i a'); ?></small></p>
<?php endforeach; ?>
<?php else : ?>
<h2>Feeds currently not available</h2>
<p>Please try again later</p>
<?php endif; ?>
That is the code I start with when implementing SimplePie on client projects. It serves as an easy-to-customize template that incorporates plenty of functionality and outputs feed content in common format. Let’s walk sequentially through the code for better understanding of functionality and proper use.
Setting the variables
- Path to the SimplePie script – edit according to your specific setup
- new SimplePie – setup a new instance of SimplePie feed variable
- Feed URL – specify the URL of the feed you would like to display
- Cache duration – specify how long the feed should be cached (seconds)
- Character encoding – ensures that content is in text/html, UTF-8 format
- Script check – sets a variable upon successful script initialization
Format the output
- Feed title and link – wrapped in
<h1>
tags and placed before the loop because only one title exists for each feed - Feed description – wrapped up in paragraph tags and placed before the loop because only one description exists for each feed
- Initialization check – if the
$check
variable is set, then continue processing the script - Begin the loop – standard
foreach
loop with parameterized argument for setting the number of feed items to display - Feed items – for each feed item, display the post title, title link, post content, and post date.
- End the loop – terminate the recursive processing of feed items
- Else condition – if the
$check
variable is not set, then display the following code - Else message – text/markup to display if the initialization check fails and the feed is not displayed
- End the if condition – conclude the script by terminating the
if
condition
Notes on SimplePie
It is possible to merge feeds into a single stream by replacing the associated lines with the following:
<?php
$feed = new SimplePie();
$feed->set_feed_url(array(
'http://domain.tld/your-feed-01/',
'http://domain.tld/your-feed-02/',
'http://domain.tld/your-feed-03/'
));
?>
Also, you can truncate the number of words that appear in the content of each feed item by using PHP’s substr()
function:
<?php echo substr($item->get_description(), 0, 180); ?>
In the foreach()
loop, you may specify the number of the first and last feed to process by editing the “0
” and “7
” in the following line:
<?php foreach ($feed->get_items(0, 7) as $item) : ?>
For WordPress users who would rather not mess with all of the “under-the-hood” code stuff, there is an awesome SimplePie plugin that automates just about everything. It should be noted, however, that the SimplePie plugin consists of two different plugins and requires a significant amount of time and effort in order to implement. It’s a great set of plugins, but I would argue that the manual implementation method is easier.
Finally, keep in mind that your feeds are cached according to either the default setting or your specified cache duration. The default caching duration is one hour, which is suitable for most implementations. Don’t forget that, for caching to work, SimplePie must have write access to the cache
directory (see above).
With SimplePie, the options are endless. This tutorial is enough to get you started, but you should check the SimplePie Wiki for more comprehensive documentation.
Feed ’em!
With these versatile, easy-to-use techniques for importing and displaying external feeds, virtually anything is possible. If you are using WordPress, you can take advantage of the built-in Magpie functionality and display feeds quickly and easily. For non-WordPress users or for those seeking more control over the feed importation and display process, you will find all of the flexibility you need with SimplePie. These methods will help you provide more content to your readers and do so without getting locked into using yet another needless plugin. So go forth and feed that insatiable audience of yours! :)
105 responses to “Import and Display RSS Feeds in WordPress”
ah, no worries Jeff.
I actually made it work making a variable equal to the function pulling the user field data (in this case being created by a plugin, but would work similarly for the “website” text field) – then i placed that variable into
fetch_rss
including all of that in aforeach
after the data was retrieved and rss script included.in my case (and in the event it helps someone else) the code is this:
include(ABSPATH.WPINC.'/rss.php'); // path to
inc
lu
de script
$values = get_cimyFieldValue(false, 'FEEDURL');
foreach ($values as $value) {
$user_id = $value['user_id'];
$FV = cimy_uef_sanitize_content($value['VALUE']);
$feed = fetch_rss($FV); // specify feed url
$items = array_slice($feed->items, 0, 3); // specify first and last item
echo "".$value['user_login']."";
foreach ($items as $item) {
echo "<a>". $item['title']."</a>";
}
echo "";
}
now im off to try and filter the user role for which all of that is processed – wish me luck! haha.
thanks again Jeff!
Good luck — and thanks for the followup with code solution. Very cool. I tried formatting it with some indentation and whatnot, so let me know if anything is incorrect.
Now I know who to contact if I ever need some feed-parsing ninja skillz! ;)
Awesome article Jeff, Clear , to the point and so easy to follow. I’ll be disposing of my plugins and coding up my own code from now on. Love it mate.
Sweet! Now if only I had had all this info last fall. I would have suffered a lot less…
@Zeeshawn: Awesome, great to hear it — thanks for the feedback! :)
@mccormicky: I know what you mean. I should have written this article a year ago. I think it took me that long to understand it all myself. Oh well, at least it’s here for next time! :)
Hi every one, you’ve done a great piece of code here.
I was fighting to get one of my own categories listed as RSS in separate page … in vane before i’ve come here.
I’ m barmen, not a code ninja…
Just a note about WP 2.7:
1 i couldnt include my own feed using your code (got a warning for the second display about function array …)
2 have given the feed to google feedburner and set the feed url of the last one
result: Worked as a swiss watches and fixed as well the problem of the “Frenchy letters” é l’e etc…
Thanx a lot for your being born.
the result is upgrading here : http://www.monmillion.fr/boutique/
Man, I would love to get what @davis (comment #13) did working on my site but I am so far failing miserably. Help? Thanks!
@Serge: I’m speechless! Thanks for the feedback :)
@Mark: I wish I could help here, but I am not familiar with the details of the technique. Hopefully davis will drop in again and lend a hand..
@mark
one thing to keep in mind before i break this down: the
get_cimyFieldValue
is a function created by the plugin Cimy User Extra Fields ( http://www.marcocimmino.net/cimy-wordpress-plugins/cimy-user-extra-fields/documentation/ )I used it to create a field in the User profile. In this case a text field that i placed an RSS feed url into.
knowing that, here is the walk through.
include(ABSPATH.WPINC.'/rss.php');
— This is including the RSS magic$values = get_cimyFieldValue(false, 'FEEDURL');
— This is saying the variable
$values
is equal to the function created by Cimy User Extra Fields false and ‘FEEDURL
’ are options for that… in this case ‘FEEDURL
’ is merely what i named the new text field i created with the plugin.So it’s essentially just saying that I want
$values
to be the values of the new fields in the user profile, and Im calling to the new field ‘FEEDURL
’ specifically – again that could be named anything.foreach ($values as $value) {
Here it is saying run this for everyone of them
$FV = cimy_uef_sanitize_content($value['VALUE']);
This line i’ve created the variable
$FV
to be equal to another function created by the plugin (one to echo the text of the field i created) and called upon in the$values
line above.$feed = fetch_rss($FV); // specify feed url
—- Here im just telling it that
$feed
is equal tofetch_rss
function with a feed value of the variable$FV
which i created to call the functioncimy_uef_sanitize_content
which understands we are looking at the text field value for ‘FEEDURL
’ per the$values = get_cimyFieldValues()
line above.$items = array_slice($feed->items, 0, 3); // specify first and last item
— This is styling the
$feed
The rest is echoing to the page.
echo "".$value['user_login']."";
— This echos the user login name and below it is saying for each
$item
(that are pulled from$feed
, that is fetching from$FV
that is equal tocimy_uef_santize_content()
that is limited from$values
to ‘FEEDURL
’) echo each feed entry as follows.foreach ($items as $item) {
echo "<a>". $item['title']."</a>";
}
echo "";
I hope that helps to explain what i did.
I still have to figure out how to only apply this whole thing to only one class of users (or to specific users) but i haven’t jumped back into yet to tackle that one.
Great article Jeff.
I’m using WP 2.71. Does anyone happen to know if Magpie writes the cache to a table or to a file (I read somewhere that it adds entries to wp_options).
@Patternhead: I think you are correct — there is no file that I know of that is used by Magpie and no information about setting permissions etc for such a file. If I remember correctly, there is a “magpie” field in the options table, as you suggest. If anyone has any specific information on this please share. Thx.
Yes WordPress does store the cache of the feed in the options table using a number of options (named magpie_x I think).
WordPress 2.8 feed functions, which now use SimplePie, will also cache in the options table but using the new transients functionality. What this does is store the information in the db unless you have installed an object cache plugin to use some thing like memcache for the WordPress object cache -then the transients are just stored in the cache.