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で指定する