Customize a WordPress RSS feed
Several versions of WordPress ago, the platform had an annoying problem. While it was great at producing RSS feeds, it was lousy at parsing them. Developers had to rely on third-party RSS feed software or roll their own.
Now, though, WordPress has a built in feed-grabbing function that makes it easy to customize the display of any RSS feed. It's based on SimplePie, a truly awesome feed-parser. Couple that with WordPress's excellent feed-delivery system, and you have a way to deliver customized dynamic content throughout your site using feeds.
In this post I'll provide a quick overview of WordPress feeds, and then walk through an example of how to grab the feed you want and customize it's display.
WordPress feeds
WordPress makes it easy to grab the feed for an entire site or just part of it. You do it by adjusting the URL of the feed when you fetch it. You can get a long explanation from WordPress if you want it. Here's the summary, assuming your site is set up to use permalinks (and if it's not, it should be):
- Entire site: http://yourdomain.com/feed/
- Comments: http://yourdomain.com/comments/feed/
- Post-specific comments: http://example.com/post-name/feed/
- A particular category: http://yourdomain.com/category/categoryname/feed/
- A particular tag: http://yourdomain.com/tag/tagname/feed/
fetch_feed()
Once you know what feed you want, you need to grab it, then format it for display. For that we use the WordPress function fetch_feed(). You can grab any property of the feed object that SimplePie defines; I'll walk you through a practical example, using a modified version of the WordPress example code.
Let's say you want to have a "Latest news" section of your home page, powered by your blog posts. Here's some code to do that:
<?php $feed = fetch_feed( 'http://yourdomain.com/feed/' ); if (!is_wp_error( $feed ) ) : // Checks that the object is created correctly // Figure out how many total items there are, but limit it to 5. $maxitems = $feed->get_item_quantity(5); // Build an array of all the items, starting with element 0 (first element). $rss_items = $feed->get_items(0, $maxitems); endif; ?> <?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 ) : ?> <div> <?php //Use regular expressions to find all images in the post $output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $item->get_content(), $matches); //Grab the first image to use as a thumbnail $first_img = $matches [1][0]; //If an image exists, display it if($first_img) {echo '<img src="'.$first_img.'" alt="'.$item->get_title().'" />';} ?> //Display the post title as a link inside an <h5> tag <h5><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></h5> //Display the item's publishing date <p><?php echo $item->get_date('n/d/Y'); ?></p> </div> <?php endforeach; ?>
The above code produces a feed item for each post that looks something like this (with some CSS applied):

If you wanted to display the post content, you would use
$item->get_content
If this were a summary display, you could use some PHP code to limit the display to a certain number of characters or words if you wanted. Alternatively you could enable WordPress Excerpts and display a hand-crafted summary for each post using
$item->get_description
Detailed walkthrough
Now let's break the above code down line by line:
$feed = fetch_feed( 'http://yourdomain.com/feed/' );
This tells fetch_feed() what feed you want to grab. Just put the URL into the function call.
if (!is_wp_error( $feed ) ) : // Checks that the object is created correctly // Figure out how many total items there are, but limit it to 5. $maxitems = $feed->get_item_quantity(5);
Confirm the feed exists. If it does, find out how many items there are so we know how many times to loop through the feed. In this case we want no more than five items, so we send the value "5" to the get_item_quantity() property.
// Build an array of all the items, starting with element 0 (first element). $rss_items = $feed->get_items(0, $maxitems); endif; ?> <?php if ($maxitems == 0) echo '<li>No items.</li>';
Put the items (up to a maximum of 5) into any array for processing.
That finishes the initial process of grabbing and sorting the feed, so the first "if" statement ends. The script then checks the results to see if there are any items at all. If not, it displays a message saying so.
else // Loop through each feed item and display each item as a hyperlink. foreach ( $rss_items as $item ) : ?> <div> <?php
If there are items in the feed, loop through them and write them into HTML. Each item gets its own div wrapper.
//Use regular expressions to find all images in the post $output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $item->get_content(), $matches); //Grab the first image to use as a thumbnail $first_img = $matches [1][0]; //If an image exists, display it if($first_img) {echo '<img src="'.$first_img.'" alt="'.$item->get_title().'" />';} ?>
In this example, we want to have a thumbnail with each entry. We could use the featured image functionality to assign a thumbnail to each post, and then use the_post_thumbnail() to retrieve it. But that requires a user to set a thumbnail for each post, and users can be unreliable. So we've decided to simply parse the post content ($item->get_content()) for image src links and use the first one we find for the thumbnail.
Notice that I'm using preg_match_all(), which finds all images in the post. Because we only care about the first image, I could have used the simpler (and faster) preg_match(), which finds the first match and then stops. I did it this way because the code is more flexible: I can easily grab additional images, if they exist. But if you know you don't need that flexibility, just use preg_match().
Also note that when writing the image tag, we grab the post title ($item->get_title()) and use it as the alt text for the image.
//Display the post title as a link inside an <h5> tag <h5><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></h5>
This step uses three feed properties to create a headline link to the actual post.
- $item->get_permalink(): The URL to the full post. We use this for the "href" value of the link. Notice the use of esc_url() to sanitize the permalink.
- $item->get_date(): The publishing date of the post. Notice that it includes standard PHP date-formatting specs. This example uses it for the title attribute of the permalink.
- $item->get_title(): The title of the post. We use this for the text of the headline. Notice the use of esc_html() to sanitize the title.
//Display the item's publishing date <p><?php echo $item->get_date('n/d/Y'); ?></p> </div> <?php endforeach; ?>
Finally, we grab the date again and render it in a slightly different format inside a paragraph tag. Then we move on to the next item and do it all over again.
As you can see, WordPress' feed functions let you easily define what part of the site's feed you want to use, grab a wide array of specific elements from that feed, and then configure it pretty much any way you want.
Going the extra mile
With a little extra coding you could turn the above example into a template system, consisting of a feed-parsing function containing the basic feed-parsing code, and a series of template functions defining different styles -- one that includes an image and short summary, say, and another that's just a headline. The page would call the feed-parsing function and pass it two things: a feed URL and a template name. The feed-parsing function would then parse the proper feed and call the named template function to format the output. Such a system would let you control your output styles centrally, and you would need just a single line of code to place an RSS feed on a page.