WordPressはデフォルトで各種フィードが出力されます(フィード – Wikipedia)。

注意したいのは「一見ブラウザから見えなくても生成されている」という点です。

自分の覚え書きになりますが、WordPressの生成するフィードとその制御方法をおさらいしておきます。

スポンサーサイト

WordPressの生成するフィード

一口にWordPressのフィードと言っても、配信される範囲(投稿、コメントなど)とフィードの形式(RSS 2.0Atomなど)とによって分類されます。

  • 本家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 で実行している関数を探します。RSS2.0のフィードであれば、do_feed_rss2 関数です。これを探すと wp-includes/functions.php の1000行目以降でフィードの形式にあわせたテンプレートを呼び出しています。

このうち、do_feed_rss2do_feed_atom では渡された引数(コメントのフィードであるかどうか)を元に呼び出すテンプレートファイルを変えています。

<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_linksfeed_links_extra という関数を実行します。

feed_linksではサイト全体のフィードと全てのコメントのフィードを、feed_links_extraでは条件に応じたフィードのリンクを作成しています。

add_theme_support( 'automatic-feed-links' ); を削除すればフィードのリンクは作成されなくなりますが、書かれていたとしても、テーマのfunctions.phpなどで

とすればリンクは削除されます。
また、特定のフィードのみリンクを残したい(追加したい)場合は、上記のコードで一旦全てのリンクを削除後、個別に追記する形になります。
例として、テーマのfunctions.phpに以下のコードを書けば、サイト全体のフィードへのリンクのみ出力されます。

なお、タグ内に記述されるフィードの形式はデフォルトでRSS2.0となります(wp-includes/feed.phpの65〜68行目に記述)。

そして注意したいのは

  1. デフォルトはRSS2.0だが、他の形式のフィードも生成されている
  2. 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 あるいはプラグインファイルでフックするようにします。

  • 追記2012.10.16:コメントで404の方が良いよとの指摘をいただいたので、修正しました。あわせてwp_die()の場合も書いておきます。
  • 追記2012.10.17:大曲(@jim0912)さんのブログにもっと簡単な方法が載っていました。WordPressでフィード配信を完璧に止める方法 | Simple Colors
    parse_queryにフックさせる形に見直してみました。

まず、do_feed_rss2 などのアクションにフックさせ、独自の関数 lf_disable_our_feeds を呼ぶようにしています。
lf_disable_our_feeds 関数ではコメントフィードへのアクセスだった場合( is_comment_feed() == TRUE )、ホームURLへ301リダイレクトさせています( wp_redirect( home_url('/'), 301) )。

2〜11行目でフィードに関するクエリーを呼ぶ条件が設定された時(クエリーが発行される前)に、コメントフィードであれば wp_die でWordPressを停止します。この時レスポンスヘッダーは404を返すようにしています。
条件分岐タグが使えますので、「投稿者アーカイブのフィードを停止する」ということが可能です。

停止したフィードとそのレスポンス
停止したフィードとそのレスポンス

13〜20行目はフィードの任意の形式を停止したいときに使います(必要無いかも知れません)。

22〜26行目でタグ内にフィードのリンクが出力されないようにしています。

逆に28〜34行目ではタグ内に出力したいフィードのリンクを作成しています。

全てのフィードが必要でなければ6行目の条件を外せばいいですし、wp_die() でWordPressのエラー画面を出す、カテゴリーアーカイブではそのフィードも出力するなど、好みに合わせて変更すれば良いと思います。

長くなりましたが、要点をまとめると、WordPressのフィードが生成されるアルゴリズムと、<head>タグ内にリンクが出力されるアルゴリズムは別です。
どちらか一方だけでは片手オチとなりますので、ご注意ください。

今回参考にしたサイト

さらなる発展系として、出力されるフィードをカスタマイズしたい場合は

もご覧ください。

WordPressのフィードに関する覚え書き」への5件のフィードバック

  1. コメントフィードを使わない場合ですが

    のようにして 404 を返してやった方が、より親切だと思います。

    1. ありがとうございます。
      早速、Gistのコードに反映してみました。
      正直301を返すか404にするか迷っていました。
      exit; を追加したんですけど、これって要ります?

      1. exit が無いと $wp_query がよしなに 404.php テンプレートを返してくれるから、要らないかもです!
        処理重くなるのが嫌なら、wp_die(“コメントフィードは無いんだよ!”); とかしとくと良いかもです!

        1. ありがとうございます。
          404が返るようにしたんですけど、テンプレートの404.phpではなく、フィードのテンプレートを使って404表示になってしまったので、wp_die()にしてみました(苦笑)
          プラグインではできているものがあったのでフックの場所なのかなぁと思っています。

Comments are closed.