2026年6月29日

2026年6月29日

WordPressのRSSフィードをコードで拡張する方法(投稿タイプ追加・独自要素・独自フィード)

WordPress は https://example.com/feed/ で RSS 2.0 のフィードを自動で出力します。表示する件数や全文・抜粋の切り替えは管理画面で変えられますが、「カスタム投稿タイプも含めたい」「価格などのカスタムフィールドを載せたい」「特定のカテゴリーだけの別フィードを作りたい」といった変更にはコードが必要です。

この記事では、WordPress のフック(アクションとフィルター)を使ってフィードを拡張する方法を、目的別に説明します。コードは WordPress 6.9 で動作を確認しています(2026年11月時点)。

コードを書く前に:設定やURLでできること

コードを書く前に、標準の機能で足りないかを確認します。

やりたいこと 標準の方法
フィードの件数を変える 「設定」→「表示設定」の「RSS/Atom フィードで表示する最新の投稿数」
全文か抜粋かを切り替える 同じ画面の「フィードの各投稿に含める内容」(「全文を表示」か「抜粋」)
カテゴリーだけのフィード https://example.com/category/カテゴリーのスラッグ/feed/
タグだけのフィード https://example.com/tag/タグのスラッグ/feed/
カスタム投稿タイプのフィード アーカイブが有効(has_archive)なら https://example.com/投稿タイプのアーカイブ/feed/

これで足りない場合に、以下のコードを使います。

コードを置く場所

コードは子テーマの functions.php か、自作のプラグインに書きます。親テーマの functions.php に書くと、テーマの更新で消えます。テーマを切り替えてもフィードの仕様を保ちたい場合は、wp-content/mu-plugins/ に PHP ファイルを置く方法(Must-Use プラグイン。有効化の操作なしで常に読み込まれる)も使えます。

本番サイトで編集する前にバックアップを取り、できればステージング環境で試してください。PHP の書き間違いがあるとサイト全体が表示されなくなります。

以下のコードでは、関数名の衝突を避けるため myprefix_ という接頭辞を付けています。自分のサイトに合わせた名前に変えてください。

メインのフィードに投稿タイプを追加し、カテゴリーを除外する

メインのフィード(/feed/)に表示する記事は、pre_get_posts アクションでメインクエリを変更して調整します。カテゴリー別のフィードやコメントのフィードまで変わらないように、条件を絞ることが大切です。

add_action( 'pre_get_posts', function ( $query ) {
	if ( is_admin() || ! $query->is_main_query() || ! $query->is_feed() ) {
		return;
	}
	// カテゴリー別・検索・個別記事のコメントなどのフィードは変更しない
	if ( $query->is_archive() || $query->is_search() || $query->is_singular() || $query->is_comment_feed() ) {
		return;
	}
	// 後述の独自フィード(news-digest)は別に扱う
	if ( 'news-digest' === $query->get( 'feed' ) ) {
		return;
	}

	// 通常の投稿に加えてカスタム投稿タイプ book も載せる
	$query->set( 'post_type', array( 'post', 'book' ) );

	// ID が 3 のカテゴリーの記事は載せない
	$query->set( 'category__not_in', array( 3 ) );
} );

カテゴリーの ID は、「投稿」→「カテゴリー」で対象のカテゴリーの編集画面を開き、URL の tag_ID= の後ろの数字で確認できます。book は例なので、実際の投稿タイプ名に置き換えてください。

各記事に独自の要素とアイキャッチ画像を追加する

RSS 2.0 に独自の要素を加えるときは、名前空間を宣言してその接頭辞を付けるのが決まりです。rss2_ns アクションで <rss> 要素に名前空間を追加し、rss2_item アクションで各 <item> の中に要素を出力します。

次の例は、カスタムフィールド price の値と、アイキャッチ画像を media:content として追加します。

// <rss> 要素に名前空間を追加する
add_action( 'rss2_ns', function () {
	echo 'xmlns:media="http://search.yahoo.com/mrss/"' . "\n\t";
	echo 'xmlns:myprefix="https://example.com/ns/myprefix/1.0/"' . "\n";
} );

// 各 <item> に要素を追加する
add_action( 'rss2_item', function () {
	$price = get_post_meta( get_the_ID(), 'price', true );
	if ( '' !== $price ) {
		printf( "\t\t<myprefix:price>%s</myprefix:price>\n", esc_xml( $price ) );
	}

	if ( has_post_thumbnail() ) {
		$image = wp_get_attachment_image_src( get_post_thumbnail_id(), 'large' );
		if ( $image ) {
			printf(
				"\t\t<media:content url=\"%s\" medium=\"image\" width=\"%d\" height=\"%d\" />\n",
				esc_url( $image[0] ),
				(int) $image[1],
				(int) $image[2]
			);
		}
	}
} );

ポイントは次のとおりです。

  • 名前空間の URL(https://example.com/ns/myprefix/1.0/)は識別用の文字列で、実際にアクセスできる必要はありません。自分のドメインを使った一意の値にします。
  • 値は esc_xml()(WordPress 5.5 以降)や esc_url() でエスケープします。エスケープしないと、& や < を含む値でフィードが XML として壊れます。
  • <meta> などの HTML タグを本文に足しても、フィードの要素にはなりません。項目として渡したい情報は rss2_item で要素として出力します。

フィードの本文に文章を足す

フィードに出る本文を変えたいときは the_content_feed フィルターを使います。次の例は、本文の末尾に元記事へのリンクを付けます。

add_filter( 'the_content_feed', function ( $content ) {
	$link = sprintf(
		'<p><a href="%s">%s</a></p>',
		esc_url( get_permalink() ),
		esc_html( 'この記事をサイトで読む' )
	);
	return $content . $link;
} );

the_content_feed が使われるのは、「フィードの各投稿に含める内容」が「全文を表示」のときの本文(content:encoded)です。抜粋(description)を変えたい場合は the_excerpt_rss フィルターを使います。

独自のフィードを作る:add_feed

add_feed() を使うと、/feed/news-digest/ のような新しいフィードを追加できます。次の例は、news カテゴリーの記事を20件出すフィードを作ります。出力には WordPress 標準の RSS 2.0 テンプレート(feed-rss2.php)をそのまま使うので、上で追加した名前空間や要素もこのフィードに反映されます。

// フィードを登録する
add_action( 'init', function () {
	add_feed( 'news-digest', 'myprefix_render_news_digest' );
} );

// フィードを出力する(標準の RSS 2.0 テンプレートを使う)
function myprefix_render_news_digest() {
	load_template( ABSPATH . WPINC . '/feed-rss2.php' );
}

// このフィードで出す記事を決める
add_action( 'pre_get_posts', function ( $query ) {
	if ( is_admin() || ! $query->is_main_query() || 'news-digest' !== $query->get( 'feed' ) ) {
		return;
	}
	$query->set( 'category_name', 'news' );
	// フィードでは posts_per_page ではなく posts_per_rss で件数を指定する
	$query->set( 'posts_per_rss', 20 );
} );

コードを追加したら、「設定」→「パーマリンク」を開いて何も変えずに「変更を保存」を押します。add_feed() で増えた URL の書き換えルールは、ルールを作り直すまで有効にならないためです。作り直す前でも https://example.com/?feed=news-digest で表示を確認できます。

フィードでは件数に posts_per_page ではなく posts_per_rss が使われる点に注意してください。WordPress はフィードのとき posts_per_page を表示設定の件数で上書きします。

独自フィードの場所を知らせる

フィードリーダーやブラウザーが独自フィードを見つけられるように、<head> に link 要素を出力します。

add_action( 'wp_head', function () {
	printf(
		'<link rel="alternate" type="application/rss+xml" title="%s" href="%s" />' . "\n",
		esc_attr( get_bloginfo( 'name' ) . ' ニュースまとめ' ),
		esc_url( get_feed_link( 'news-digest' ) )
	);
} );

get_feed_link( 'news-digest' ) は、パーマリンク設定に合わせて /feed/news-digest/ か ?feed=news-digest の形の URL を返します。

動作を確認する

  • ブラウザーかコマンドでフィードを開き、追加した要素や記事が含まれているかを見ます。
curl -s https://example.com/feed/ | head -40
curl -s https://example.com/feed/news-digest/ | grep -c '<item>'
  • XML として正しいかは、W3C の Feed Validation Service で確認できます。
  • フィードリーダーは取得結果を保存しているので、変更がすぐに反映されないことがあります。確認は直接 URL を開いて行います。キャッシュ系のプラグインや CDN を使っている場合は、そのキャッシュも消してから確認してください。

よくある失敗

  • フィードが「XML 解析エラー」になる: functions.php の先頭や末尾の空白・改行が出力に混ざっている、または値をエスケープしていないことが多い原因です。?> の後ろに改行がないかを確認します。
  • 独自フィードが 404 になる: パーマリンクの「変更を保存」をしておらず、URL の書き換えルールが作り直されていない場合です。?feed=news-digest の形で表示できるかを確かめると切り分けられます。
  • カテゴリー別のフィードまで変わった: pre_get_posts の条件で is_archive() などを除外していないと、すべてのフィードに影響します。

まとめ

  • 件数や全文・抜粋、カテゴリー別のフィードは、まず標準の設定と URL で対応する
  • 表示する記事の変更は pre_get_posts で、メインのフィードだけに絞って行う
  • 独自要素は rss2_ns で名前空間を宣言し、rss2_item でエスケープして出力する
  • 本文の変更は the_content_feed、抜粋の変更は the_excerpt_rss
  • 独自フィードは add_feed() で作り、パーマリンクの保存でルールを作り直す。件数は posts_per_rss で指定する

お気軽にご相談ください

お見積りへ お問い合わせへ
▲