apt-get install debian-wizard

Insider infos, master your Debian/Ubuntu distribution

  • About
    • About this blog
    • About me
    • My free software history
  • Support my work
  • Get the newsletter
  • More stuff
    • Support Debian Contributors
    • Other sites
      • My company
      • French Blog about Free Software
      • Personal Website (French)
  • Mastering Debian
  • Contributing 101
  • Packaging Tutorials
You are here: Home / Random / How to create custom RSS feeds with WordPress

How to create custom RSS feeds with WordPress

January 7, 2011 by Raphaël Hertzog

WordPress has many alternate built-in feeds: per category, per tag, per author, per search-keyword. But in some cases, you want feeds built with some more advanced logic. Let’s look at the available options.

WordPress advanced built-in feeds

You can create feeds for “unions” or “intersections” of tags, you just have to use a URL like /tag/foo,bar/feed/ (all articles tagged with foo or bar) or /tag/foo+bar/feed/ (all articles tagged with foo and bar).

You can also have feeds excluding a category, although that requires you to know the category identifier (and hardcode it in the URL like this: /?feed=rss2&cat=-123 where 123 is the category id that you want to exclude).

But there’s no simple way to have a feed that excludes articles with a given tag. The best solution found involves creating a custom feed. I’ll show you a variation of this below.

Creating a custom feed

  1. First of, install the Feed Wrangler plugin, it will take care of registering our custom feeds with wordpress.
  2. Go to “Settings > Feed Wrangler” in your WordPress administrative interface and create a new feed, let’s call it “myfeed”.
  3. You should now create a “feed-myfeed.php” file and put it in your current theme’s directory. The initial content of that file should be this:
    <?php
    include('wp-includes/feed-rss2.php');
    ?>

    <?php include('wp-includes/feed-rss2.php'); ?>

  4. At this point, you already have a new feed that you can access at /feed/myfeed/ (or /?feed=myfeed). It’s a complete feed like the main one.

Now, we’re going to look at ways to customize this feed. We’re going to do this by changing/overriding the default query that feed-rss2.php’s loop will use.

A feed excluding articles with a tag

If you want to create a feed that excludes the tag “foo”, you could use this:

<?php
global $wp_query;
$tag = get_term_by("slug", "foo", "post_tag");
$args = array_merge(
        $wp_query->query,
        array('tag__not_in' => array($tag->term_id))
);
query_posts($args);
include('wp-includes/feed-rss2.php');
?>

<?php global $wp_query; $tag = get_term_by("slug", "foo", "post_tag"); $args = array_merge( $wp_query->query, array('tag__not_in' => array($tag->term_id)) ); query_posts($args); include('wp-includes/feed-rss2.php'); ?>

That was relatively easy, thanks to the “tag__not_in” query parameter. Now you can further customize the feed by adding supplementary query parameters to the $args array. The documentation of query_posts details the various parameters that you can use.

A feed excluding articles with a custom field (meta-data)

I went further because I did not want to use a tag to exclude some posts: that tag would have been public even if it was only meaningful to me. So I decided to use a custom field to mark the posts to exclude from my new feed. I named the field “no_syndication” and I always give it the value “1”.

This time it’s not so easy because we have no query parameter that can be used to exclude posts based on custom fields. We’re going to use the “post__not_in” parameter that can be used to exclude a list of posts. But we must first generate the list of posts that we want to exclude. Here we go:

<?php
global $wp_query;
$excluded = array();
$args_excluded = array(
    'numberposts'     => -1,
    'meta_key'        => 'no_syndication',
    'meta_value'      => 1,
    'post_type'       => 'post',
    'post_status'     => 'published'
);
foreach (get_posts($args_excluded) as $item) {
        $excluded[] = $item->ID;
}
$args = array_merge(
        $wp_query->query,
        array('post__not_in' => $excluded)
);
query_posts($args);
include('wp-includes/feed-rss2.php');
?>

<?php global $wp_query; $excluded = array(); $args_excluded = array( 'numberposts' => -1, 'meta_key' => 'no_syndication', 'meta_value' => 1, 'post_type' => 'post', 'post_status' => 'published' ); foreach (get_posts($args_excluded) as $item) { $excluded[] = $item->ID; } $args = array_merge( $wp_query->query, array('post__not_in' => $excluded) ); query_posts($args); include('wp-includes/feed-rss2.php'); ?>

A feed with modified content

You might want to add a footer to the articles that are syndicated. I use the Ozh’ Better Feed plugin for this but it applies to all your feeds.

You could do that sort of transformation only in your customized feed by using the WordPress filter named the_content_feed.

Here’s a simple example:

<?php
function myfeed_add_footer($content) {
        return $content . "<hr/>My footer here";
}
add_filter('the_content_feed', 'myfeed_add_footer');
include('wp-includes/feed-rss2.php');
?>

<?php function myfeed_add_footer($content) { return $content . "<hr/>My footer here"; } add_filter('the_content_feed', 'myfeed_add_footer'); include('wp-includes/feed-rss2.php'); ?>

I’ll stop here but obviously you have lots of options and many ways to tweak all the snippets above. They have been tested with WordPress 3.0.4.

Note that in all those examples, I took care to not duplicate the code from feed-rss2.php, instead I used include() to execute it. That way my custom feeds will automatically benefit from all the future enhancements and fixes made by the WordPress developers.

But if you have to modify the XML structure of your custom feeds, you can paste the content of feed-rss2.php in your file and change it like you want…

Filed Under: Random, Tips and tricks Tagged With: feed, HOWTO, PHP, Programming, RSS, tag, WordPress

Comments

  1. Guillermo Garron says

    January 7, 2011 at 5:56 pm

    The good about open source, is this.
    If you know how to change some small things, you can make the software fit exactly your needs.
    I wish I knew PHP. 🙂

  2. Jeiboy Search says

    May 1, 2011 at 2:59 am

    Do you have a tutorial for making rss feed like the wordpress feed?

  3. Jeiboy Search says

    May 6, 2011 at 11:18 pm

    Any response? It would be appreciate. thanks.

    • Raphaël Hertzog says

      May 7, 2011 at 10:15 am

      Sorry, the response is “no”. I don’t have any tutorial.

  4. Michael Straus says

    July 4, 2011 at 12:22 am

    Raphael,
    This is extremely helpful.
    I’m new to messing around with coding, and one clarification question:
    In “Creating a custom feed”, point #3 you write:
    “You should now create a “feed-myfeed.php” file and put it in your current theme’s directory.”
    I’m unclear on “Current theme’s directory”
    I’m using PrimePress theme, and it lists a couple dozen templates – should we modify one of those? If so, which one (none is labeled ‘Directory’) and does it matter where in the body we add the coding? (eg. just stick it at the end?)
    Sorry to ask such a basic question, and thanks for your help,
    Michael

    • Raphaël Hertzog says

      July 4, 2011 at 8:39 pm

      You should not modify an existing template but add a supplementary file in the theme directory… and by “directory” I mean “folder”. Something like wordpress/wp-content/themes/mytheme/.

Get the Debian Handbook

Available as paperback and as ebook.
Book cover

Email newsletter

Get updates and exclusive content by email, join the Debian Supporters Guild:

Follow me

  • Email
  • Facebook
  • GitHub
  • RSS
  • Twitter

Discover my French books

Planets

  • Planet Debian

Archives

I write software, books and documentation. I'm a Debian developer since 1998 and run my own company. I want to share my passion and knowledge of the Debian ecosystem. Read More…

Tags

3.0 (quilt) Activity summary APT aptitude Blog Book Cleanup conffile Contributing CUT d-i Debconf Debian Debian France Debian Handbook Debian Live Distro Tracker dpkg dpkg-source Flattr Flattr FOSS Freexian Funding Git GNOME GSOC HOWTO Interview LTS Me Multiarch nautilus-dropbox News Packaging pkg-security Programming PTS publican python-django Reference release rolling synaptic Ubuntu WordPress

Recent Posts

  • Freexian is looking to expand its team with more Debian contributors
  • Freexian’s report about Debian Long Term Support, July 2022
  • Freexian’s report about Debian Long Term Support, June 2022
  • Freexian’s report about Debian Long Term Support, May 2022
  • Freexian’s report about Debian Long Term Support, April 2022

Copyright © 2005-2021 Raphaël Hertzog