Now that we have seen how to setup Tumblr-style posts, it would be nice to be able to segregate the Tumblr-posts category from the main feed into its own, separate feed. This would enable readers to subscribe exclusively to the Tumblr-posts feed and maybe display it in their sidebar or something. While we’re at it, it would also be cool to be able to provide readers with a full menu of feed choices, including the following:
- Everything feed: includes both the main posts and the Tumblr posts
- Articles-only feed: includes only the main articles and no Tumblr stuff
- Tumblr-only feed: includes only the Tumblr-style posts
Let's look at an overview of the process..
Overview of this tutorial
To accomplish our goals, we’ll perform the following steps:
- Create two custom-Page templates
- Create two Pages, one for the articles and one for the Tumblr-posts
- Assign the custom templates to their respective Pages
- Make sure the feeds validate and clean up theme tags
That’s the plan, now let’s dig in..
Step 1: create a couple custom-page templates
Our two custom Page-templates will contain all of the code needed to generate our two custom feeds. These two custom templates are almost identical. For the articles-only feed, we will exclude the tumblelog category from the loop, and for the tumblr-only feed, we will include only the tumblelog category.
Let’s do the articles-only Page template first. In your theme, create a new Page-template file called “articles.php” and insert the following code:
<?php /* Template Name: Articles */ $numposts = 10; // number of posts in feed $posts = query_posts('showposts='.$numposts.'&cat=-1'); // replace the number 1 with the ID of your tumblelog category $more = 1; header('Content-Type: '.feed_content_type('rss-http').'; charset='.get_option('blog_charset'), true); 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/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" <?php do_action('rss2_ns'); ?> > <channel> <title><?php bloginfo_rss('name'); wp_title_rss(); ?> - Article Feed</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> <lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate> <?php the_generator( 'rss2' ); ?> <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 while( have_posts()) : the_post(); ?> <item> <title><?php the_title_rss(); ?></title> <link><?php the_permalink_rss(); ?></link> <comments><?php comments_link(); ?></comments> <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate> <dc:creator><?php the_author(); ?></dc:creator> <?php the_category_rss(); ?> <guid isPermaLink="false"><?php the_guid(); ?></guid> <?php if (get_option('rss_use_excerpt')) : ?> <description><![CDATA[<?php the_excerpt_rss() ?>]]></description> <?php else : ?> <description><![CDATA[<?php the_excerpt_rss() ?>]]></description> <?php if ( strlen( $post->post_content ) > 0 ) : ?> <content:encoded><![CDATA[<?php the_content() ?>]]></content:encoded> <?php else : ?> <content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded> <?php endif; ?> <?php endif; ?> <wfw:commentRss><?php echo get_post_comments_feed_link(); ?></wfw:commentRss> <slash:comments><?php echo get_comments_number(); ?></slash:comments> <?php rss_enclosure(); ?> <?php do_action('rss2_item'); ?> </item> <?php endwhile; ?> </channel> </rss>
Alternately, you may download the two required page-template files here.
Once you have that code in place, edit the
$numposts variable according to the number of articles that you would like to display in the articles-only feed. Then edit the
$posts variable according to the ID of your tumblelog category. See the comments in the code for details.
That’s it for your articles-only feed. Now, for your tumblr-only feed, create another new Page-template file called “tumblelog.php” and insert the exact same chunk of code as before. The first change that we need to make for this second template is to remove the hyphen (
- ) from the
$numposts variable like so:
$posts = query_posts('showposts='.$numposts.'&cat=1');
This tells WordPress to include only your tumblelog category in your tumblr-only feed. For your articles-only feed, the presence of the hyphen (negative sign, whatever) tells WordPress to exclude your tumblelog category. Simple, but effective.
The second (and final) change that we need to make for the tumblr-only template is to give it a new template name in the first line:
Template Name: Tumblelog
This will enable WordPress to distinguish between the two custom templates in the next step.
Step 2: create two Pages in the WordPress Admin
With your two custom Page-templates uploaded to your server, login to your Admin area and create two new Pages:
- Create a Page called “Articles” and assign it the “Articles” template
- Create a Page called “Tumblelog” and assign it the “Tumblelog” template
At this point, your two new custom feeds are fully functional, appearing at the following URLs:
http://domain.tld/articles/— articles-only feed
http://domain.tld/tumblelog/— tumblr-only feed
Once you have some posts in your tumblr-only category, you will see that they are excluded from the articles-only feed and appear by themselves in the tumblr-only feed. Of course, your main posts feed, located at
http://domain.tld/feed/ will contain all of your posts, enabling you to offer the following feeds to your readers:
- “Everything” feed — that would include both the main posts and the Tumblr posts
- “Articles-only” feed — that would include only the main articles and no Tumblr stuff
- “Tumblr-only” feed — that would include only the Tumblr-style posts
Final step: validation and theme clean-up
Now that everything is working, you should take the time to double-check the validity of your new feeds. This will ensure that subscribers receive the correct content in the proper format. Rest assured, I have already validated the XML produced from the custom page-template, but double-checking is always a good idea in case there are any unintended side-effects from plugins, scripts and whatnot.
One of our favorite validation services is available at: http://www.feedvalidator.org/ — go there and enter the URLs of your new feeds.
Here at DiW, we recently used this exact method to establish an articles-only feed for use at Planet WordPress. You can verify that it validates quite nicely.
Finally, after setting up your custom feeds, you should go into your theme and add some nice “subscribe” links for your readers. Also want to remind you that your new feeds are in fact Pages, such that you may want to remove them from any automatic Page-listings generated by the
wp_page_menu template tags. For example, you can easily exclude your two feed Pages as follows:
123” and “
456” are the IDs of your Articles and Tumblelog Pages.
Wrapping it up
With the technique described in this article, you now have an easy, sure-fire way of creating custom feeds in WordPress. The code for the feed markup is highly versatile, and may be customized to suit virtually any custom-feed configuration.