Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

How can I make a separate RSS feed for each custom post type?

I had searched the net for it and found suggestions to do something like this:

http://www.yoursite.com/feed/?post_type=book

I tried the above, but it just didn't work! It only takes me back to the custom post type archive page again...

Does anybody knows where I went wrong or what I am missing???

FYI, I used the Custom Post Permalinks plugin to allow post type specific permalinks for post type archive pages. Not sure if this may affect the RSS feed problem.

Cheers!

share|improve this question
add comment

3 Answers

add the small example function:

    add_action( 'request', 'fb_add_to_feed' );

    // add to post-feed
    function fb_add_to_feed($request) {

        if ( isset($request['feed']) && !isset($request['post_type']) ) {
            $request['post_type'] = get_post_types( $args = array(
                'public'          => true,
                'capability_type' => 'post'
            ) );
        }

        return $request;
    }

Alternative you can creat a own feed onl yfor the custom post type. See the follow example for a "Draft Feed" of draft posts.

<?php
/*
Plugin Name: Drafts Feed
Plugin URI:  http://bueltge.de/wordpress-feed-fuer-entwuerfe/829/
Description: Add a new Feed for drafts: <code>/?feed=draft</code>
Version:     0.2
Author:      Frank Bültge
Author URI:  http://bueltge.de/
Licence:     GPL
Last Change: 17.06.2009 10:50:19
*/

//avoid direct calls to this file, because now WP core and framework has been used
if ( !function_exists('add_action') ) {
    header('Status: 403 Forbidden');
    header('HTTP/1.1 403 Forbidden');
    exit();
}

if ( function_exists('add_action') ) {
    //WordPress definitions
    if ( !defined('WP_CONTENT_URL') )
        define('WP_CONTENT_URL', get_option('siteurl') . '/wp-content');
    if ( !defined('WP_CONTENT_DIR') )
        define('WP_CONTENT_DIR', ABSPATH . 'wp-content');
    if ( !defined('WP_PLUGIN_URL') )
        define('WP_PLUGIN_URL', WP_CONTENT_URL.'/plugins');
    if ( !defined('WP_PLUGIN_DIR') )
        define('WP_PLUGIN_DIR', WP_CONTENT_DIR.'/plugins');
    if ( !defined('PLUGINDIR') )
        define( 'PLUGINDIR', 'wp-content/plugins' ); // Relative to ABSPATH.  For back compat.
    if ( !defined('WP_LANG_DIR') )
        define('WP_LANG_DIR', WP_CONTENT_DIR . '/languages');

    // plugin definitions
    define( 'FB_DF_BASENAME', plugin_basename(__FILE__) );
    define( 'FB_DF_BASEFOLDER', plugin_basename( dirname( __FILE__ ) ) );
    define( 'FB_DF_TEXTDOMAIN', 'draft_feed' );
}

if ( !class_exists('DraftFeed') ) {
    class DraftFeed {

        // constructor
        function DraftFeed() {

            add_action( 'init', array(&$this, 'add_draft_feed') );
            if ( is_admin() ) {
                add_action( 'wp_dashboard_setup', array(&$this, 'my_wp_dashboard_setup') );
                add_action( 'admin_head', array(&$this, 'add_my_css') );
                add_action( 'admin_init', array(&$this, 'textdomain') );
            }
        }

        function textdomain() {

            if ( function_exists('load_plugin_textdomain') ) {
                if ( !defined('WP_PLUGIN_DIR') ) {
                    load_plugin_textdomain( FB_DF_TEXTDOMAIN, str_replace( ABSPATH, '', dirname(__FILE__) ) . '/languages' );
                } else {
                    load_plugin_textdomain( FB_DF_TEXTDOMAIN, false, dirname( plugin_basename(__FILE__) ) . '/languages' );
                }
            }
        }

        function my_wp_dashboard_recent_drafts( $drafts = false, $view_content = false ) {
            if ( $drafts )
                return;

            $drafts_query = new WP_Query( array(
                                                                                    'post_type' => 'post',
                                                                                    'post_status' => 'draft',
                                                                                    'posts_per_page' => 5,
                                                                                    'orderby' => 'modified',
                                                                                    'order' => 'DESC'
                                                                                    ) );
            $drafts =& $drafts_query->posts;

            if ( $drafts && is_array( $drafts ) ) {
                $list = array();
                foreach ( $drafts as $draft ) {
                    $url = get_edit_post_link( $draft->ID );
                    $title = _draft_or_post_title( $draft->ID );
                    $user = get_userdata($draft->post_author);
                    $author = $user->display_name;
                    $item = '<a href="' . $url . '" title="' . sprintf( __( 'Edit “%s”', FB_DF_TEXTDOMAIN ), esc_attr( $title ) ) . '">' . $title . '</a> ' . __( 'by', FB_DF_TEXTDOMAIN ) . ' ' . stripslashes( apply_filters('comment_author', $author) ) . ' <abbr title="' . get_the_time(__('Y/m/d g:i:s A'), $draft) . '">' . get_the_time( get_option( 'date_format' ), $draft ) . '</abbr>';
                    $list[] = $item;
                }
        ?>
            <ul>
                <li><?php echo join( "</li>\n<li>", $list ); ?></li>
            </ul>
            <p class="textright"><a href="edit.php?post_status=draft" class="button"><?php _e('View all', FB_DF_TEXTDOMAIN); ?></a></p>
        <?php
            } else {
                _e( 'There are no drafts at the moment', FB_DF_TEXTDOMAIN );
            }
        }

        function my_wp_dashboard_setup() {

            wp_add_dashboard_widget( 'my_wp_dashboard_recent_drafts', __( 'Recents Drafts', FB_DF_TEXTDOMAIN ) . ' <small>' . __( 'of all authors', FB_DF_TEXTDOMAIN ) . '</small>', array(&$this, 'my_wp_dashboard_recent_drafts') );
        }

        function add_my_css() {

            $echo  = '';
            $echo .= "\n";
            $echo .= '<style type="text/css">'."\n";
            $echo .= '<!--'."\n";
            $echo .= '#my_wp_dashboard_recent_drafts abbr {' . "\n";
            $echo .= 'font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif;' . "\n";;
            $echo .= 'font-size: 11px;' . "\n";
            $echo .= 'color: #999;' . "\n";
            $echo .= 'margin-left: 3px;' . "\n";
            $echo .= '}'."\n";
            $echo .= '-->'."\n";
            $echo .= '</style>'."\n";

            echo $echo;
        }

        // add feed via hook
        function add_draft_feed() {

            // set name for the feed
            // http://examble.com/?feed=draft
            add_feed( 'draft', array(&$this, 'get_draft_feed') );
        }

        // get feed
        function get_draft_feed() {
            global $wpdb;

            // draft or future
            $sql = "
                            SELECT ID, post_title, post_date, post_author, post_author, guid, post_excerpt, post_content
                            FROM $wpdb->posts
                            WHERE post_status = 'draft'
                            ORDER BY post_date_gmt DESC
                        ";
            $items = $wpdb->get_results($sql);

            if ( !headers_sent() )
                header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
            $more = 1;
        ?>
        <?php echo '<?xml version="1.0" encoding="' . get_option('blog_charset') . '"?' . '>'; ?>

<rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    <?php do_action('rss2_ns'); ?>
>

<channel>
    <title><?php bloginfo_rss( 'name' ); wp_title_rss(); ?></title>
    <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
    <link><?php bloginfo_rss( 'url' ) ?></link>
    <description><?php bloginfo_rss( 'description' ) ?></description>
    <pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false ); ?></pubDate>
    <generator>http://bueltge.de/</generator>
    <language><?php echo get_option( 'rss_language' ); ?></language>
    <sy:updatePeriod><?php echo apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod>
    <sy:updateFrequency><?php echo apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency>
    <?php do_action('rss2_head'); ?>
    <?php
    if ( empty($items) ) {
        echo '<!-- No submissions found yet. //-->';
    } else {
        foreach ($items as $item) {
    ?>
        <item>
            <title><?php echo stripslashes( apply_filters( 'comment_author', $item->post_title ) ); ?></title>
            <link><?php echo stripslashes( apply_filters( 'comment_author_url', get_permalink($item->ID) ) ); ?></link>
            <pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', $item->post_date ); ?></pubDate>
            <dc:creator><?php echo stripslashes( apply_filters('comment_author', $item->post_author) ); ?></dc:creator>

            <guid isPermaLink="false"><?php echo stripslashes( apply_filters('comment_author_url', $item->guid) ); ?></guid>
            <?php if ( $item->post_excerpt != '' ) { ?>
            <description><![CDATA[<?php echo trim(stripslashes( apply_filters('comment_text', $item->post_excerpt) ) ); ?>]]></description>
            <?php } else { ?>
            <description><![CDATA[<?php echo strip_tags( trim( stripslashes( apply_filters('comment_text', $item->post_content) ) ) ); ?>]]></description>
            <?php } ?>
            <content:encoded><![CDATA[<?php echo trim( stripslashes( apply_filters( 'comment_text', $item->post_content ) ) ); ?>]]></content:encoded>
            <?php do_action('rss2_item'); ?>
        </item>
    <?php
        }
    }
    ?>
    </channel>
</rss>
        <?php
        }

    } // end class

    $df_wp_injector = new DraftFeed();
} // end if class exists

// WP init and add ne function for feed
if ( isset($df_wp_injector) && function_exists( 'add_action' ) ) {
    add_action( 'DraftFeed',  array(&$df_wp_injector, 'init') );
}
?>
share|improve this answer
    
Hmmm... tried both of the above, but none of them worked. It is such a basic thing. Is it possible that it is my theme that's causing the problem?? –  gmaggio Nov 1 '10 at 7:47
add comment
up vote 2 down vote accepted

Okay, thanks to all who contributed to answering my question, but I had finally figured out the solution to my problem.

Sorry for being naive but it turned out that I had a template_redirect action added to direct anything that's related to my post types to their respective template files. Something like this:

function my_template_redirect()
{
    global $wp, $wp_query;

    if ( ( $wp->query_vars["post_type"] == "news" ) && !is_single() )
    {
        if (have_posts())
        {
            include(TEMPLATEPATH . '/news.php');
            die();
        }
        else
        { $wp_query->is_404 = true; }
    }
}
add_action("template_redirect", 'my_template_redirect');

It, apparently, also redirected my post-type feeds to the template files, thus "it only takes me back to the custom post type archive page again...'

So I just added an extra filter to exclude feeds from this redirection, that is, I added !is_feed() in the if statement:

if ( ( $wp->query_vars["post_type"] == "news" ) && !is_single() && !is_feed() )

...and the feeds work as they should be again. I knew there was something wrong with the theme...

Thanks again for the help, guys! :)

share|improve this answer
add comment

You should be able to get the feed by going to http://www.yoursite.com/?feed=rss2&post_type=your_post_type as long as the post type is set to be publicly_queryable.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.