So. I created a gmail rss feed with php that I placed in a custom page. I used this snippet:

 function checkGmail($username, $password)
 $url = "https://mail.google.com/mail/feed/atom"; 

 $curl = curl_init();
 curl_setopt($curl, CURLOPT_URL, $url);
 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
 curl_setopt($curl, CURLOPT_USERPWD, $username . ":" . $password);
 curl_setopt($curl, CURLOPT_ENCODING, "");
 $mailData = curl_exec($curl);

 return $mailData;

 header('Content-Type:text/xml; charset=UTF-8');
 $feed = checkGmail("[email protected]", "password");
 echo $feed;

And it outputs the xml on my site. Great. Then I tried to create a validated feed from this, and this is where Im stucked. I tried to create a custom rss feed by this:

 add_action( 'after_setup_theme', 'my_rss_template' );
* Register custom RSS template.
function my_rss_template() {
add_feed( 'short', 'my_custom_rss_render' );

* Custom RSS template callback.
function my_custom_rss_render() {
get_template_part( 'feed', 'short' );

Then I tried to call it all by http://website.com/?feed=feed-short but It says something in the lines of not a valid feedtemplate. It does output the xml on the custom page if I navigate to it by it´s slug. So what do I do here?

1 Answer 1


You can take a look at

ABSPATH . WPINC . 'feed-*.*';

to see examples. WP core has feed tempaltes for the following protocols:

  • Atom
  • RDF
  • RSS
  • RSS2

When writing a plugin, you can take the following quick test plugin as base. It adds a feed name custom-feed to the list of feeds.

/* Plugin Name: (WPSE) #172796 Custom Feed */

add_action( 'init', function()
    add_feed( 'custom-feed', function()
        /** @var \WP_Query $wp_query */
        global $wp_query;

        // Custom conditions when to output the feed - and when not
        if ( 'foo' !== get_query_var( 'name' ) )

        load_template( plugin_dir_path( __FILE__ ).'templates/feed-rss2.php' );
    } );
} );

To get a quick look at the default feeds, simply dump them

var_dump( $GLOBALS['wp_rewrite']->feeds );

When you activate above test plugin, you should find custom-feed as last entry in the array.

Inside any callbacks you should check if you are actually working on the new custom feed:

$wp_query->is_feed( [ 'custom-feed', ] );

To get a valid feed, you will have to set a header. Core does it like the following:

header( sprintf( 
    'Content-Type: %s; charset=%s',
    feed_content_type( 'rss-http' ),
    get_option( 'blog_charset' )
), true );

Then there's the actual XML opening tag:

echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>';

after that, there's a place to allow plugins to hook in:

do_action( 'rss_tag_pre', 'rss2' );

Finally there is the <rss version="2.0" ... tag opening and another hook to add custom namespaces

do_action( 'rss2_ns' );

The list goes on and on. The best you can do is to take the core files as blueprint for your own feeds (copy/paste them to your plugin and alter the output).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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