WordPressはデフォルトで各種フィードが出力されます(フィード – Wikipedia)。
注意したいのは「一見ブラウザから見えなくても生成されている」という点です。
自分の覚え書きになりますが、WordPressの生成するフィードとその制御方法をおさらいしておきます。
目次
WordPressの生成するフィード
一口にWordPressのフィードと言っても、配信される範囲(投稿、コメントなど)とフィードの形式(RSS 2.0、Atomなど)とによって分類されます。
- 本家Codex:WordPress Feeds(日本語Codexにもありますが、差分があるので本家Codexのみ紹介します)
Codexに載っている情報からWordPress 3.4.2において生成されるフィードは以下になります。
- ★サイト全体(post_type=post)
- ★コメント(サイト全体)
- コメント(投稿単位)
- カテゴリー・タグ
- 著者
- 検索結果
フィードが呼ばれたときの処理
さすがに全てのソースを読む訳にもいかないので、「WordPressの実行フローを視覚化してみる | Simple Colors」を参照にどのファイルから探すか当たりをつけていきます。
まず、フィードのURLにアクセするとWordPressは do_feed()
という関数を実行します(wp-includes/template-loader.phpの13〜15行目 )。
次に do_feed()
でコアファイルを検索すると wp-includes/functions.php の975行目から関数が定義されています。
do_feed()
関数内では get_query_var( 'feed' )
で取得した値を加工して、フィードの形式を決定し、do_action( 'do_feed_{フィードの形式}', $wp_query->is_comment_feed );
しています。
do_action は add_action で設定された関数を実行する関数です。さらにここでは、$wp_query->is_comment_feed
を引数として渡しています。
続いてdo_feed_rss2
を探すと wp-includes/default-filters.php に他のフィード形式も含め add_action
が定義されています。さらに引数を一つ定義された関数に渡しています。
add_action( 'do_feed_rdf', 'do_feed_rdf', 10, 1 ); add_action( 'do_feed_rss', 'do_feed_rss', 10, 1 ); add_action( 'do_feed_rss2', 'do_feed_rss2', 10, 1 ); add_action( 'do_feed_atom', 'do_feed_atom', 10, 1 );
次に add_action
で実行している関数を探します。RSS2.0のフィードであれば、do_feed_rss2
関数です。これを探すと wp-includes/functions.php の1000行目以降でフィードの形式にあわせたテンプレートを呼び出しています。
このうち、do_feed_rss2
と do_feed_atom
では渡された引数(コメントのフィードであるかどうか)を元に呼び出すテンプレートファイルを変えています。
function do_feed_rss2( $for_comments ) { if ( $for_comments ) load_template( ABSPATH . WPINC . '/feed-rss2-comments.php' ); else load_template( ABSPATH . WPINC . '/feed-rss2.php' ); }
<head>内でのフィードへのリンク
テーマで add_theme_support( 'automatic-feed-links' );
が設定されていれば、★の付いたフィードはすべてのページで、それ以外は表示しているページ(アーカイブ)にあわせて<head>
内にフィードへのリンクが追加されます(フィードのURLはパーマリンク設定によって異なります)。
「設定されていれば」と書きましたが、デフォルトテーマも含め公式に配布されているテーマでは記述することが必須となっています(日本語Codex:Theme Review)。
「なぜ add_theme_support( 'automatic-feed-links' );
を記述してタグ内にフィードリンクを作成するのか」という部分はここでは割愛します。
add_theme_support( 'automatic-feed-links' );
を使うと wp_head()
が呼ばれたとき、 feed_links
と feed_links_extra
という関数を実行します。
add_action( 'wp_head', 'feed_links', 2 ); add_action( 'wp_head', 'feed_links_extra', 3 );
feed_links
ではサイト全体のフィードと全てのコメントのフィードを、feed_links_extra
では条件に応じたフィードのリンクを作成しています。
add_theme_support( 'automatic-feed-links' );
を削除すればフィードのリンクは作成されなくなりますが、書かれていたとしても、テーマのfunctions.phpなどで
remove_action( 'wp_head', 'feed_links', 2 ); remove_action( 'wp_head', 'feed_links_extra', 3 );
とすればリンクは削除されます。
また、特定のフィードのみリンクを残したい(追加したい)場合は、上記のコードで一旦全てのリンクを削除後、個別に追記する形になります。
例として、テーマのfunctions.phpに以下のコードを書けば、サイト全体のフィードへのリンクのみ出力されます。
function lf_custom_feeds_alternate() { echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr(get_bloginfo('name')) . 'のフィード" href="' . get_feed_link() . " />n"; } add_action( 'wp_head', 'lf_custom_feeds_alternate' );
なお、タグ内に記述されるフィードの形式はデフォルトでRSS2.0となります(wp-includes/feed.phpの65〜68行目に記述)。
2017.11.27 追記
ver 4.4 以降 feed_links にフィルターフックが追加されているので、コメントフィードだけ消したい場合などは remove_action
せずともフィルターフックのみで対応できます。
<?php // Disable comments feed link add_filter( 'feed_links_show_comments_feed', function() { return false; } );
そして注意したいのは
- デフォルトはRSS2.0だが、他の形式のフィードも生成されている。
add_theme_support( 'automatic-feed-links' );
を記述しなくても、remove_actionでリンクを出力しないようにしても、フィードは生成されている。
という点です。
テンプレートファイル内でフィードへのリンク(<head>以外)
テンプレートファイル内でフィードへのリンクを作成するには、以下のテンプレートタグを使います。
サイト全体及び全てのコメント | bloginfo() または get_bloginfo() |
---|---|
コメント(投稿単位) | get_post_comments_feed_link() |
カテゴリー | get_category_feed_link() |
タグ | get_tag_feed_link() |
著者 | get_author_feed_link() |
検索結果 | get_search_feed_link() |
フィードを使わない(配信・生成自体をカスタマイズ)
WordPressをCMS的に使いたい場合、コメントのフィードなど必要としないフィードが出てくると思います。
前述したフィードが呼ばれたときの処理に沿ってテーマの funcitons.php あるいはプラグインファイルでフックするようにします。
https://gist.github.com/3897653
- 追記2012.10.16:コメントで404の方が良いよとの指摘をいただいたので、修正しました。あわせてwp_die()の場合も書いておきます。
- 追記2012.10.17:大曲(@jim0912)さんのブログにもっと簡単な方法が載っていました。WordPressでフィード配信を完璧に止める方法 | Simple Colors
parse_queryにフックさせる形に見直してみました。 - 追記2017.11.27 : 前述の通り、4.4以降追加されたフィルターフックを使うように変更
まず、do_feed_rss2
などのアクションにフックさせ、独自の関数 lf_disable_our_feeds
を呼ぶようにしています。
lf_disable_our_feeds
関数ではコメントフィードへのアクセスだった場合( is_comment_feed() == TRUE
)、ホームURLへ301リダイレクトさせています( wp_redirect( home_url('/'), 301)
)。
10〜16行目でフィードに関するクエリーを呼ぶ条件が設定された時(クエリーが発行される前)に、コメントフィードであれば wp_die でWordPressを停止します。この時レスポンスヘッダーは404を返すようにしています。
条件分岐タグが使えますので、「投稿者アーカイブのフィードを停止する」ということが可能です。
13〜20行目はフィードの任意の形式を停止したいときに使います(必要無いかも知れません)。
全てのフィードが必要でなければ12行目の条件を外せばいいですし、wp_die() でWordPressのエラー画面を出す、カテゴリーアーカイブではそのフィードも出力するなど、好みに合わせて変更すれば良いと思います。
長くなりましたが、要点をまとめると、WordPressのフィードが生成されるアルゴリズムと、<head>タグ内にリンクが出力されるアルゴリズムは別です。
どちらか一方だけでは片手オチとなりますので、ご注意ください。
今回参考にしたサイト
- WordPressの実行フローを視覚化してみる | Simple Colors
- WordPressでフィード配信を完璧に止める方法 | Simple Colors
- 適切なフィルタフックを探す | dogmap.jp
- WordPress Disable RSS Feed
さらなる発展系として、出力されるフィードをカスタマイズしたい場合は
もご覧ください。