Home > blog > wordpressで非公開コミュニティサイトを作る(4)feedのカスタマイズ

wordpressで非公開コミュニティサイトを作る(4)feedのカスタマイズ

  • 2009-04-28 (火) 15:39
  • blog
  • |
Google Adsense

wordpress!

前回保留にした、アクセス制限した状態でのfeedをどうするかという問題を考えていく。

前回、ログイン確認にfunctions.phpからアクションフックを利用してリダイレクトする方法に変更し、そのおかげでfeedも認証が必要になった。
ところがwordpressの認証にはcookieを利用している事から、cookieを判別出来ないfeed readerではアクセス出来ない問題が残ったので、これについて考えて見る。

参考:wordpressで非公開コミュニティサイトを作る(3)続・ユーザーレベルで表示内容を変更 – atl*weblog

feedはどんな風に利用されるか

クローズドなサイトを作るのが今回の目的なので、通常のblogのように全文配信したりといった、feed自体の質にはそこまでこだわる必要はないかなと思っている。(特に根拠がないどころか、質がいいに決まってるんだけど)
ログインする、という手間がかかるので更新されたかどうかの通知は必須になる。
なのでfeedは必要であるものの、配信される内容はぶっちゃけタイトルだけでもいい。
コメントのやり取りも想定される事から、出きれば本文とコメント等を纏めて一つのfeedとして配信出来るといいんだけど…、これは無理にやらずに他のfeed纏めるサービス使ったほういいのかなぁ。
けどfeedの配信タイミングが遅れそうな気もするなー。

feedテンプレートってどこにあるの?

feedで吐き出すxmlをカスタムしてしまえば、本文のみ隠したりも出来るし、ひょっとしたらwordpressの関数使ってcookie見てのログイン判別も出来るかもしれない。
なんて淡い期待を込めつつやり方を探すも、どうもfeed用のテンプレートはコアファイルにしか存在しないらしい。

Customizing Feeds « WordPress Codex

ここにfeedのカスタム方法が載っているけど、ここに記載されているwp-rss2.phpだとかwp-atom.phpと同名のファイルでも作ってテーマフォルダにでも置けばテンプレートみたいになるかな、なんて淡い期待を持って無駄な時間をすごしたり。
今現在のwordpress(2.7.x)ではwp-includes内にあるfeed-atom.php、feed-atom-comments.php、feed-rdf.php、feed-rss2.php、feed-rss2-comments.phpとかがテンプレートにあたるようだ。
中身を見るとテンプレートファイルと同様に、様々なfeed用テンプレートタグを利用してfeedの雛形が作られている。

コアファイルを編集する事に抵抗が無いならこれをいじれば簡単に目的達成となるだろう、やり方もテーマの修正と同様なので特にむずかしくもない。
ただ上記の通り、ヴァージョンアップで変わってしまう可能性があるコアファイルのため、俺はこの方法はちょっと避けたい。

feedのカスタマイズの下準備

まずfeedへのアクセスに認証をしないで出来るようにする。

認証周りの処理変更

前回send_headersフックでログイン判別とリダイレクトをさせていて、これでfeed見るにも認証が必要になるぜわっしょいしてたが、ログイン判別にcookieが必要な以上通常のFeedReaderで読めなくなってしまう。
というか薄々気づいていたのだが、どうにも対処方法がわからず、それならば吐き出すfeed自体をどうにかしたほうが現実的という事でこれは一度戻す事に。
とはいえまたheader.phpに直接書くのも芸がないのでget_headerフックで以下のようにfunctions.phpにリダイレクト処理を書いた。

function op_auth() {
	if ( !is_user_logged_in() ) auth_redirect();
}
add_action('get_header', 'op_auth');

このアクションフックはheader.phpが読み込まれる際に動くらしいので、header.phpの最初に記述したのとほぼ同様の効果を得られる。
処理も別の場所に分離できていい感じ。

デフォルトのフィルターをリムーブ→再設定し、feedテンプレートを置き換える

さて、feedをあれこれするのに何かいいフックないかなーと探し幾つかそれっぽいものを見つけたものの、結局何が出来るかどうかすらわからなかった。
日本のcodexはまだ未翻訳、本家のcodexには記事がない。

Plugin API/Action Reference/atom entry « WordPress Codex

こりゃ別の方法かなー、と思って半ば諦めていたらtwitterでアドバイスを頂いた!

Twitter / wokamoto: @darumen default_filter とし …

@darumen default_filter として do_feed_rss, do_feed_rss2, … ってフィルタをフックして、ロードするテンプレートを指定しているので、これらをリムーブ後、新たにフィルタを add すれば、好きなテンプレートをロードできます。

しかもサンプルコードまで書いてもらってしまった…!
(共有メモサービスでコード提示してもらったけど、一応そっちのアドレスは伏せ)

// フィルタリムーブ
remove_filter('do_feed_rdf', 'do_feed_rdf', 10);
remove_filter('do_feed_rss', 'do_feed_rss', 10);
remove_filter('do_feed_rss2', 'do_feed_rss2', 10);
remove_filter('do_feed_atom', 'do_feed_atom', 10);

// フィルタ追加
function custom_feed_rdf() {
  load_template( get_template_directory() . '/feed-rdf.php' );
}
add_action('do_feed_rdf', 'custom_feed_rdf', 10, 1);

function custom_feed_rss() {
  load_template( get_template_directory() . '/feed-rss.php' );
}
add_action('do_feed_rss', 'custom_feed_rss', 10, 1);

function custom_feed_rss2( $for_comments ) {
  if ( $for_comments )
    load_template( get_template_directory() . '/feed-rss2-comments.php' );
  else
    load_template( get_template_directory() . '/feed-rss2.php' );
}
add_action('do_feed_rss2', 'custom_feed_rss2', 10, 1);

function custom_feed_atom( $for_comments ) {
  if ($for_comments)
    load_template( get_template_directory() . '/feed-atom-comments.php');
  else
    load_template( get_template_directory() . '/feed-atom.php' );
}
add_action('do_feed_atom', 'custom_feed_atom', 10, 1);

をかもとさんありがとうございます!(2日ほどハマってました)

コードの検証

動作確認も出来たのですぐにでも使えてしまうレベルのコードだけど、折角なのでどういう事をしているのか調べて見る。
feedが表示される際、アクセスされたfeedの種類によってdo_feed_~~というフックが動いて何かするんで、それをremove_filterで無しにした後、新たにそれぞれにadd_actionで処理を再設定している。
処理自体はテーマフォルダ内の同名テンプレートを取得する事によって、本来コアファイルに含まれるfeed用テンプレートをテーマフォルダ内にある自作テンプレートに置き換えている。
rss2とatomはコメントのfeedのケースもあるんで、引数で渡された$for_commensの真偽でどちら用のテンプレートを使うかを判別している。
…のかな、たぶん。

分からないのは、remove_filterで指定してるフックと関数名が同じだけど、どういう事だろうって点と、こういう事をする場合関数ってどうやって調べるんだろう、という二点。

まずremove_filterで指定してるフック、do_feed_~~だがこんな感じのもの。
プラグイン API/アクションフック一覧 – WordPress Codex 日本語版

do_feed_フィード名
アクション関数引数: フィードの種類(コメントフィードならtrue、投稿記事フィードならfalse)
RSS2、Atom、RDFなどのフィードが生成される直前に実行する。フィード名には rss2、atom などフィードの種類を入れる。

feedが生成される直前に実行されるってのはあってるようだ。

で関数のほうはwp-includes/functions.phpの1481行からあった!

/**
 * Load the RDF RSS 0.91 Feed template.
 *
 * @since 2.1.0
 */
function do_feed_rdf() {
  load_template( ABSPATH . WPINC . '/feed-rdf.php' );
}

/**
 * Load the RSS 1.0 Feed Template
 *
 * @since 2.1.0
 */
function do_feed_rss() {
  load_template( ABSPATH . WPINC . '/feed-rss.php' );
}

/**
 * Load either the RSS2 comment feed or the RSS2 posts feed.
 *
 * @since 2.1.0
 *
 * @param bool $for_comments True for the comment feed, false for normal feed.
 */
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' );
}

/**
 * Load either Atom comment feed or Atom posts feed.
 *
 * @since 2.1.0
 *
 * @param bool $for_comments True for the comment feed, false for normal feed.
 */
function do_feed_atom( $for_comments ) {
  if ($for_comments)
    load_template( ABSPATH . WPINC . '/feed-atom-comments.php');
  else
    load_template( ABSPATH . WPINC . '/feed-atom.php' );
}

結論:単にフックと同名の関数があるだけだった。

そしての調べ方だが、恐らくケースによるのだろうけれど、をかもとさんのアドバイスによるとdefault_filter として~~というくだりがあるので、とりあえずwp-includes/default_filters.phpを見てみたりして、目的のフックで実行されている関数があればwp-includes/functions.phpで探せばいいのかな。

ちなみにこの場合Codexは本家のほうをしっかり読み込んでれば大丈夫だと思うんだけど、俺のように怠けて辞書代わりに使ってる場合本家codexにも記述のない項目が結構あるので見つからなかったりする。

feedテンプレートのカスタマイズ

という事でアドバイスもあって見事にテーマフォルダにfeed用テンプレートファイルを持つ事が出来るようになった。
wp-includesディレクトリ下にある各種テンプレートファイルを利用中のテーマフォルダにコピーし、これを改良していく。

認証は無理だった

まず認証についてだが、案の定判別はむずかしいようだ。
利用するFeedReader次第ではあるのだが、やはり別の方法で情報隠蔽を考えたほうがいいみたい。
また、ユーザーレベルでの振り分けもどうやら無理なようだ、普通にブラウザでfeedを表示する場合には適用されるケースもあるのだが、やはりFeedReaderで見ると全てユーザーレベル0での挙動しかしないので、振り分ける意味はあまりなかった。

本文をrssに表示させない

本来概要くらいは表示させておいてもいいのだが、利用者と想定している層が<!--more-->すら使ってくれなそうなので、タイトルとメタ情報のみの配信にしておきたい。
なのでfeed用テンプレートの本文部分を無くしておく。
さらにデフォではコメントへのリンクもあるのでこれもはずしておく。

feed-rss2.phpのコメント部分は以下。

<comments><?php comments_link(); ?></comments>

feed-rss2.phpの本文部分は以下。

<?php if (get_option('rss_use_excerpt')) : ?>
		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
<?php else : ?>
		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
	<?php if ( strlen( $post->post_content ) > 0 ) : ?>
		<content:encoded><![CDATA[<?php the_content() ?>]]></content:encoded>
	<?php else : ?>
		<content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
	<?php endif; ?>
<?php endif; ?>

これらを削除すればいい。他のatomとか別のfeedも似たような感じなので同様に。

結局のところ…

思いもかけないアドバイスもいただき凄く勉強になったものの、今回の目的からすればfeedをテンプレートとして持つほどの修正は必要なかった感じがする。
というのも前回やったthe_contentフィルターフックによる記事本文、そしてcomment_textフィルターフックによるコメント文の差し替えはfeedにも効いているからだ。
なので、体験用メンバーの権限のユーザーレベルを0から1に引き上げてやり、feedからの閲覧は自動的にユーザーレベル0扱いにする事によって、全ての記事の本文・コメント文を非表示ないし文言置き換えをする事が可能だからだ。
ただちょっと面倒そうなのでスルーしたが、feedテンプレートを持つ事が出来たおかげで今後頑張れば本文とコメント両方の更新を一つのfeedで受信できるようにカスタムしたり、その場合はコメント用feedは一本化したほうのfeedにリダイレクトしたり、といった事が出来るかなーと思えるようになった。

しかし不安なのは、適当にfeedから本文部分を削除したけど、正しいRSS構文とかそういった観点から見るとどうなんだろう?
今まで直接xmlをいじる機会がなかったけど、そのうちこれも勉強しないと><

Trackbacks (Close):4

trackback from dogmap.jp 09-04-30 (木) 12:44

各種フィード用テンプレートの変更

だるまんさんが、Twitter 上で「なんでwpにfeedのテンプレートがないんだぜ?」とつぶやいていました。
確かに WordPress では、テーマ変更で見栄えがガラッと変わるのに feed は色気の無い画…

pingback from wordpressで非公開コミュニティサイトを作る(7)feedのカスタマイズ2(失敗) - atl*weblog 09-05-22 (金) 6:57

[...] 参考:wordpressで非公開コミュニティサイトを作る(4)feedのカスタマイズ – atl*weblog [...]

pingback from フィードのテンプレートをカスタマイズしたい!【WordPress】 | ウェブなとき。 10-07-02 (金) 13:57

[...] 【atl*weblog】wordpressで非公開コミュニティサイトを作る(4)feedのカスタマイズ 【dogmap.jp】各種フィード用テンプレートの変更 [...]

pingback from WordPressでベーシック認証させる方法まとめ 11-04-15 (金) 19:23

[...] wordpressで非公開コミュニティサイトを作る(4)feedのカスタマイズ http://weblog.atl-r.net/blog/t……nitysite4/ [...]

Home > blog > wordpressで非公開コミュニティサイトを作る(4)feedのカスタマイズ

Calendar
« 2017 年 8月 »
M T W T F S S
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Search
ABM | AnotherBookmark™
heteml
heteml
amadana
amadana(アマダナ)
feed
Meta

Return to page top