巷でよく見かけるカスタム投稿タイプをRSSに反映させるコードはバグがあるので使ってはいけない

カスタム投稿タイプのフィードを表示させようと思ったのですが、下記のような不具合が発生。

  • 特定のカスタム投稿タイプのRSSが取得できない(全てメインフィードと同じフィードになる)
  • WP_DEBUGがtrueのときに特定のカスタム投稿タイプのRSSフィードを表示するとNoticeエラーがでる
    Warning: Illegal offset type in isset or empty in /PATH/TO/wp-includes/post.php on line 828
    
    Notice: Trying to get property of non-object in /PATH/TO/wp-includes/general-template.php on line 665
    
    Notice: Trying to get property of non-object in /PATH/TO/wp-includes/general-template.php on line 665
    

カスタム投稿タイプのフィードを表示するためのURLを間違えたのかと思い、いろいろ調べてみたのですが、フィードのURLには間違いはない模様。ちなみに、以下がカスタム投稿タイプのフィードを取得するURL(例としてカスタム投稿タイプ「news」のフィードを取得する場合)。

  • http://www.example.com/news/feed/
  • http://www.example.com/feed/?post_type=news

原因

コアのコードを読んだり、functions.phpに書き足したコードを調べてみたりしたところ、ネット上で見つけてfunctions.phpに書き加えていた「カスタム投稿タイプをRSSに反映させるコード」が原因だということがわかりました。

// 巷でよく見かけるカスタム投稿タイプをRSSに反映させるコード
function custom_post_rss_set( $query ) {
	if ( is_feed() ) {
		$query->set( 'post_type', array( 'post', 'news', 'videos' ) );
		return $query;
	}
}
add_filter( 'pre_get_posts', 'custom_post_rss_set' );

上記のコードの何が問題かというと、リクエストの種類がフィードであれば「他の条件を無視して全て指定のポストタイプで上書きしてしまっている」という点。そのため、どのような指定をしても、すべてメインフィード(というか上記コードで指定したポストタイプのフィード)が表示されたというわけです。また、本来ポストタイプが一つの場合のりクエストでも、ポストタイプが上書きされて配列で渡ってしまうため、Noticeエラーがでていたようです。

解決策

「他の条件を無視して全て指定のポストタイプで上書きしてしまっている」というのが問題だったので、カスタム投稿タイプの指定があるときはそれを使い、無いときは指定のポストタイプを使うようにすれば良いです。

// 改良したコード
public function custom_post_rss_set( $query ) {
	if ( is_feed() ) {
		$post_type = $query->get( 'post_type' );
		if ( empty( $post_type ) ) {
			$query->set( 'post_type', array( 'post', 'news', 'videos' ) );
		}
		return $query;
	}
}
add_filter( 'pre_get_posts', 'custom_post_rss_set' );

おまけ

今回の原因を探るにあたり、日本語の情報が少なく、また、あったとしても上記に掲載した問題のあるコードの情報ばかりだったので、英語の情報もあたってみました。英語圏ではメインフィードにカスタム投稿タイプを含めるためのコードとして、次のようなコードが目立ちました。

function mysite_feed_request($vars) {
	if ( isset( $vars['feed'] ) && !isset( $vars['post_type'] ) ) {
		$vars['post_type'] = array( 'post', 'news', 'videos' );
	}
	return $vars;
}
add_filter( 'request', 'mysite_feed_request' );

このコードでもカスタム投稿タイプの指定がある場合だけ、という指定がされているので、今回のような不具合は発生しません。日本語の情報ばかりでなく、海外の情報もきちんとチェックしないといけませんね。

  • ブックマーク
  • Feedly

この記事を書いた人

キタジマタカシ

長崎在住、フリーランスのWordPress テーマ / プラグインデベロッパー。 多数のプロダクトをオープンソースで開発・公開しています。現在は WordPress 有料テーマ Snow Monkey を開発・販売しています。