I've had a request from a client which is causing me a bit of a headache! They want an RSS feed which shows content that isn't featured anywhere on the website.

I've registered a new custom post type (stripped down code);

$alert_args = array( 
    'public' => false, 
    'show_ui' => true,
    'label' => 'Alerts', 
    'has_archive' => true, 
    'supports' => array( 'title', 'editor' ),
register_post_type( 'alerts', $alert_args );

For the RSS feed to work, it appears I need the public argument set to TRUE but I don't want these posts to be indexed by Google or to be used by website visitors. Any idea how I can get the RSS feed to work on it's own?

Thanks, Dan.


Please note, in the end I had the change get_post_type() to get_query_var( 'post_type' ) because the former doesn't work with archive template pages. See code;

if( 'alerts' === get_query_var( 'post_type' ) && ! is_feed() )
    $GLOBALS[ 'wp_query' ]->set_404();
    status_header( 404 );

1 Answer 1


You could try forcing a 404 using this method:

 * Force 404 on all "alerts" custom post type pages except for the feed
 * @see https://wordpress.stackexchange.com/a/162303/26350

add_action( 'template_redirect', function() {
    if( 'alerts' === get_post_type() && ! is_feed() )
        status_header( 404 );
} );

with the following setup:

$alert_args = array( 
    'public'              => true, 
    'show_ui'             => true,
    'has_archive'         => true, 
    'exclude_from_search' => true,
    'label'               => 'Alerts', 
    'supports'            => array( 'title', 'editor' ),

register_post_type( 'alerts', $alert_args );

to allow only access to the feed for the the alerts custom post type.

You might also want to consider adding an extra ! is_user_logged_in() check, if you want to allow logged in users view the alerts or ! current_user_can( 'some_capability' ) for some user capability requirement.

  • This appears to work very well, thank you very much for the fast and effective answer. I never knew about the status_header() and nocache_headers() functions, so I'm pleased I asked the question.
    – Dan
    Sep 23, 2014 at 13:30
  • see my minor change to code. Does that look ok to you?
    – Dan
    Sep 23, 2014 at 18:58
  • @Dan I tested it on the default 2012 theme for the post post type and that seems to block all archive pages as well. If you're using some attached taxonomy to the alerts, your method might not work there or with the post post type. Can you share the url structure where this didn't work for you?
    – birgire
    Sep 24, 2014 at 9:31
  • I wanted the post type archive blocking too, which is why I changed that code. domain.com/alerts/ would have been the URL in question, just the post type's archive.
    – Dan
    Sep 24, 2014 at 13:42
  • @Dan strange, example.com/alerts/ is blocked on my 2012 theme install using the get_post_type() version. Then there's always the possibility of using specific template tags like: is_post_type_archive( 'alerts' ).
    – birgire
    Sep 24, 2014 at 13:54

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.