How I create a combo feed using WordPress

When my site was on Barley I had something we called a “combo feed”. A combo feed combined all content types (what we called custom post types) into my┬ámain RSS feed. This allowed someone to subscribe to a single feed and get all of the blog posts, statuses, photos, and audio bits that I publish. Optionally, they could choose to subscribe to each of them individually, effectively allowing them to opt-out of the ones they’d rather not see. A good example of why someone may do this would be if they followed me on Twitter they may not want to subscribe to my status updates.

I wanted to have this functionality on WordPress too and I thought I’d share how I did it for anyone else that may find it useful. If you see anything I’m doing wrong please let me know.

When I register my custom post types I enable the post type archive. This turns on the /feed URL for each of them. See my statuses feed as an example. According to the Codex page for register_post_type I could also turn on rewrite for ‘feed’. But since I turn on the archive this is done automatically. Here is a slightly modified version of the code I use:

add_action( 'init','custom_post_type_register' );
function custom_post_type_register() {

    $args = array(
        'label' => __( 'Audio' ),
        'singular_label' => __( 'Audio Item' ),
        'public' => true,
        'show_ui' => true,
        'capability_type' => 'post',
        'hierarchical' => true,
        'has_archive' => true,
        'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', 'revisions', 'page-attributes' ),
        'rewrite' => array( 'slug' => 'audio', 'with_front' => false ),
       );

    register_post_type( 'audio' , $args );
}

Now that I know there will be feeds for each custom post type, it’d be nice to list them in the HEAD of the HTML document so that they are discoverable by feed readers. For example, Feedly (the feed reader I use) lists all of the feeds available to subscribe to. I’d like that list to include all of my feeds and not just my combo feed. WordPress has a function to “add theme support” for several things and one of them is adding feed links to your site automatically. Which is nice since I may add or subtract feeds over time and this way all of the currently available feeds will be discoverable without me changing anything. Here is the documentation for this function, but here is what it looks like in my functions.php file:

add_theme_support( 'automatic-feed-links' );

The final step is to combine all of the custom post types that I want into my main feed. This is done by modifying the request for the main feed to include the other post types. WordPress calls this “filtering”. When a request for my feed comes from a feed reader I “filter” the request to include the default blog posts and the custom post types that I want.

// Combine Custom Post Types into main feed
function combine_cpt_into_feed($the_request) {
    if ( isset($the_request['feed']) && !isset($the_request['post_type']) ) :
        $the_request['post_type'] = get_post_types($args = array(
	  		'public'   => true,
	  		'_builtin' => false
		));
    array_push($the_request['post_type'],'post');
    endif;
    return $the_request;
}
add_filter('request', 'combine_cpt_into_feed');

This function first checks to be sure the request coming in is for a feed. Specifically the main feed. It does this by checking if the request is for a feed and that the request does not include a custom post type. Next, I set the post_type array on the request to include all public post types that are not built in (meaning, not out-of-the-box from WordPress such as post and page) using get_post_types. Lastly, I add the default ‘post’ type so that my blog posts are included in the request as well.

For my use I include all public custom post types because I do not have any that I do not want to include in my main theme. You could just as easily create the array yourself to include any custom post types that you’d like. But then you’d have to manually update that array when you add or remove custom post types.

I’m happy with the result. I hope you subscribe.

#, #, #