How to Add Custom Data to a WordPress RSS Feed

Sparks flying in circles off of a pipe.

You’ve quite likely heard of “RSS Readers” or “Feed Readers” before—if only when a lot of people got angry that Google was shutting theirs down. In fact, RSS feeds are one of the most important and least understood technologies that keep the internet working.

Today, we’ll discuss how to modify the data your site publishes to its RSS feed, and why you’d want to modify that data in the first place.

Today’s Article as a Video

I wanted to try something new. Here’s this week’s article as a video screencast:

How do you like the video, and the video/article combination? We might do this more if you find it helpful. Let us know in the comments!

What RSS Feeds Are

An RSS feed is an XML document that WordPress publishes for you.

An RSS feed is an XML document that WordPress publishes for you. Technically, there are a few different common formats for “RSS”—only some of which are RSS. For example, “Atom” is a common format for data feed publishing, which are typically and casually called “RSS feeds.”

One of the really great things about WordPress is that it will publish an RSS feed for you, at example.com/feed/Here’s ours. This may seem unimportant—until you want the fact that you’ve published new data on your WordPress site to trigger some action, like sending an email in MailChimp. Or perhaps you want to make new posts trigger another action (tweet at @WordPress! put your iPad in airplane mode! turn off your fridge!) via a tool like IFTTT. Then RSS is friggin’ sweet!

Why I Changed the WPShout RSS Feed

When we forgot, people would have to click from the feed to our site to see what the linked content was, and then visit it.

This week, I finally got around to a bit of RSS cleanup. As you probably know, we regularly post links to cool things around the internet. In the backend, those links have a custom field (also known as “post meta”) that powers a lot of the linking to them.

And previously, the RSS feed didn’t do a great job of making those links easy to follow: people would have to click from the feed to our site to see what the linked content was, and then visit it. Lame! Well, we finally fixed it.

So here, we’ll explain how we’re showing that custom data inside the body of our RSS feed, to save our RSS readers an extra click and a few seconds a day. Let’s get to it!

The Code to Add Our Links to the Feed

I made a new plugin that just has the following code inside of it:

add_filter( 'the_content_feed', 'wpshout_link_in_feed' );
function wpshout_link_in_feed( $content ) {
    $link = get_post_meta( 
        get_the_ID(),
        'link',
        true 
    );
    if ($link === '') {
        return $content;
    }
    
    return '<a href="'.esc_url($link).'">'
        .'<h2>'.get_the_title_rss()
        .'&nbsp;&rarr;</h2>'
        .'</a>'
        .$content;
} 

Understanding the Hook We’re Using

WordPress has a whole host of feed-specific hooks, where things like the_title and the_content are further altered before they go into the feed(s) WordPress makes.

The first interesting thing in the code above is the filter it uses: we’re hooking onto the_content_feed, because we’re looking to add the link to the start of each post’s content in the feed.

As it turns out, WordPress has a whole host of feed-specific hooks, where things like the_title and the_content are further altered before they go into the feed(s) WordPress makes. If you’re curious, the feed templates themselves live in /wp-includes/feed-{format}.php. Because that’s a part of core, you’re going to want to use hooks to change things in them. But if you look at them, you’ll see they look a lot like glorified Loop-containing members of the template hierarchy (from a theme)—which they nearly are.

So we’re using the the_content_feed filter to make our code do something. Among the special “feed” filters, this one is actually an oddball. If you want to change the title, you can hook into the_title_rss. For changing excerpts, it’s the_excerpt_rss. And so on. the_content_rss was deprecated in WordPress 2.9 because there was value in having the hook carry information about different feed formats (the esoteric “RSS” vs “Atom” stuff we mentioned earlier).

As a note, you can also make this work with a hook onto the_content itself. Then, you’d just want to use the conditional tag is_feed() to only impact your feed and not your whole site. The result is the same, but using the_content incurs a very marginal extra-processing penalty on every request where the filter is invoked. Generally, the most specific hook you can find is best, and there are enough for feeds: here’s the best “list” in the Codex.

The Function Itself

Okaay: what’s this filter function doing? Well, our links are just regular posts, with a custom field—creatively named link—where the linked-to URL is stored. What we’re doing is trying to fetch that custom field for every post. That’s the role of get_post_meta():

get_post_meta()

$link = get_post_meta( 
    get_the_ID(), 
    'link', 
    true 
);

We explain get_post_meta() in more detail in our introduction to custom fields. It has three parameters:

  1. The post ID; the in-the-Loop function get_the_ID() works fine here.
  2. The name of the custom field.
  3. A boolean that signals whether or not you want WordPress to make the field a string for you. We do here, thus the true.

Exiting Early for Non-Link Posts

We’ve got a “guard clause” that exits early if no value is found for the link custom field.

Because tutorial posts like this one are also caught going to be caught by our filter, but don’t have the link field filled on them, we’ve got a “guard clause” that exits early is no value if found for the custom field:

if ($link === '') {
    return $content;
}

Adding HTML to Link Posts

Then, we’re adding some HTML to the $content we’re passed by the filter. We’re appending to its start a linked H2 which duplicates the post title and tacks a little right-arrow on the end. The esc_url() call is best practice late-escaping of the (probably-safe) link URL value, and we’re using get_the_title_rss() rather than get_the_title() because, heck, it’s going in a feed!

return '<a href="'.esc_url($link).'">'
        .'<h2>'.get_the_title_rss()
        .'&nbsp;&rarr;</h2>'
        .'</a>'
        .$content;

The Result

This is how WPShout’s feed now looks in my personal feed reader of choice, Fever:

shout-feed-item-in-fever-rss-reader

So Many Possibilities

Obviously, there are lots of modifications you might want to make to your RSS feed. Perhaps you want to add your site name to your post titles? Or tweak your feed dates at random to mess with people? The core thing to learn here is just to remember to hook onto the similarly-named RSS/Feed specific hook that WordPress provides. Happy hacking!

Image credit: drainrat


0 Comments
Inline Feedbacks
View all comments