クラ「WordPressのfeedをカスタマイズしてほしいです。しかもカスタム投稿ごとに内容を変えて。」
ぼく「できらぁ!!」
というわけでやってみました。案外簡単でした。
デフォルトのfeedを無効にする
まず、ややこしいのでWordPressデフォルトのfeedを無効にしておきましょう。functions.phpに以下記述
1 2 3 4 |
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); |
feedのテンプレートをコピー
自分でfeedのphpを書くのは非常にめんどうなので、WordPress本体のものをコピーして使っちゃいましょう。ちなみに、今回コメントのfeedは無視することにします。
“wp-includes”の中に以下4つのfeed用テンプレートがあるので、コピーしてテーマの中に持ってきます。
- feed-atom.php
- feed-rdf.php
- feed-rss
- feed-rss2.php
僕は、テーマの中に”feed”というディレクトリを作り格納しました。
新テンプレートを読み込むようにする
上でテーマ内に持ってきたfeedテンプレートを、WordPressのfeedとして使うようにします。functions.phpに以下記述
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 32 33 34 35 36 37 38 39 |
function custom_feed_rdf() { $template_file = '/feed/feed-rdf.php'; $template_file = ( file_exists( get_stylesheet_directory() . $template_file ) ? get_stylesheet_directory() : ABSPATH . WPINC ) . $template_file; load_template( $template_file ); } add_action('do_feed_rdf', 'custom_feed_rdf', 10, 1); function custom_feed_rss() { $template_file = '/feed/feed-rss.php'; $template_file = ( file_exists( get_stylesheet_directory() . $template_file ) ? get_stylesheet_directory() : ABSPATH . WPINC ) . $template_file; load_template( $template_file ); } add_action('do_feed_rss', 'custom_feed_rss', 10, 1); function custom_feed_rss2( $for_comments ) { $template_file = '/feed/feed-rss2' . ( $for_comments ? '-comments' : '' ) . '.php'; $template_file = ( file_exists( get_stylesheet_directory() . $template_file ) ? get_stylesheet_directory() : ABSPATH . WPINC ) . $template_file; load_template( $template_file ); } add_action('do_feed_rss2', 'custom_feed_rss2', 10, 1); function custom_feed_atom( $for_comments ) { $template_file = '/feed/feed-atom' . ( $for_comments ? '-comments' : '' ) . '.php'; $template_file = ( file_exists( get_stylesheet_directory() . $template_file ) ? get_stylesheet_directory() : ABSPATH . WPINC ) . $template_file; load_template( $template_file ); } add_action('do_feed_atom', 'custom_feed_atom', 10, 1); |
do_feed_atom()あたりをWordPress Codexでさらっと見ておくとわかりやすいです。
feedテンプレートをカスタマイズ
これでようやくカスタマイズの準備が整いました。さっそくカスタマイズ…する前に、もうちょっと事前知識を入れておきましょう。
投稿タイプごとにfeedを表示させるには?
例えば、通常の投稿のfeedであれば、”http://hogehoge.com/feed/”というように、ホームURLの末尾に”/feed/”をつければ表示されます。
では、カスタム投稿”shop”の場合はどうかというと、
というように、”?post_type=[カスタム投稿名]”をパラメータとしてつけることで表示できます。
ということはすなわち、テンプレートに”post_type”というパラメータが渡っていて、それが変数として使われていると推測されます。
そしてWordPressさんのことだから、変数名はきっと”$post_type”だろうと思ってやってみたところ、ドンピシャでした。よかったー、ここわかんなかったらけっこう苦労してたかも。
というわけでカスタマイズ開始
一番簡単な”feed-rss.php”を例にします。デフォルトまんまで開くとこんな感じ
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?php /** * RSS 0.92 Feed Template for displaying RSS 0.92 Posts feed. * * @package WordPress */ header('Content-Type: ' . feed_content_type('rss') . '; charset=' . get_option('blog_charset'), true); $more = 1; echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?> <rss version="0.92"> <channel> <title><?php wp_title_rss(); ?></title> <link><?php bloginfo_rss('url') ?></link> <description><?php bloginfo_rss('description') ?></description> <lastBuildDate><?php $date = get_lastpostmodified( 'GMT' ); echo $date ? mysql2date( 'D, d M Y H:i:s +0000', $date ) : date( 'D, d M Y H:i:s +0000' ); ?></lastBuildDate> <docs>http://backend.userland.com/rss092</docs> <language><?php bloginfo_rss( 'language' ); ?></language> <?php /** * Fires at the end of the RSS Feed Header. * * @since 2.0.0 */ do_action( 'rss_head' ); ?> <?php while (have_posts()) : the_post(); ?> <item> <title><?php the_title_rss() ?></title> <description><![CDATA[<?php the_excerpt_rss() ?>]]></description> <link><?php the_permalink_rss() ?></link> <?php /** * Fires at the end of each RSS feed item. * * @since 2.0.0 */ do_action( 'rss_item' ); ?> </item> <?php endwhile; ?> </channel> </rss> |
なんのことはない、普段よく触るテンプレートとだいたい一緒です。
実際にfeedをブラウザを表示させ、どの関数が何を出力しているのか見ながらやればけっこう簡単に理解できます。
そして、33行目を見てください。そう、これ…あれですよね!普通に記事をループさせてるだけです!
記事をループしているので、いつも通り$postとかも使えちゃいます。
なので、カスタムフィールドもあっさり取得できます。以下は例えばAdvanced Custom Fieldsで取得できる値。
“$post”さえあればいろんな値が取得できます。
で、カスタム投稿タイプは?
肝心のそこですが、例えば
で開かれたfeedには、$post_type という変数に”shop”が格納されています。ありがたいですね。
じゃああとは、$post_typeに入っている値によって場合分けしてやればOKです。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
<?php /** * RSS 0.92 Feed Template for displaying RSS 0.92 Posts feed. * * @package WordPress */ header('Content-Type: ' . feed_content_type('rss') . '; charset=' . get_option('blog_charset'), true); $more = 1; echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?> <rss version="0.92"> <channel> <title><?php wp_title_rss(); ?></title> <link><?php bloginfo_rss('url') ?></link> <description><?php bloginfo_rss('description') ?></description> <lastBuildDate><?php $date = get_lastpostmodified( 'GMT' ); echo $date ? mysql2date( 'D, d M Y H:i:s +0000', $date ) : date( 'D, d M Y H:i:s +0000' ); ?></lastBuildDate> <docs>http://backend.userland.com/rss092</docs> <language><?php bloginfo_rss( 'language' ); ?></language> <?php /** * Fires at the end of the RSS Feed Header. * * @since 2.0.0 */ do_action( 'rss_head' ); ?> <?php if( $post_type == 'shop' ): ?> <?php while (have_posts()) : the_post(); ?> <?php $thumb = get_field('acf_thumb', $post->ID ); ?> <item> <title><?php the_title_rss() ?></title> <?php if( $post->post_content ): ?> <description><![CDATA[<?php the_excerpt_rss() ?>]]></description> <?php endif; ?> <?php if($thumb): ?> <link><?php the_permalink_rss() ?></link> <?php else: ?> <link><?php echo home_url('/'); ?></link> <?php endif; ?> <?php /** * Fires at the end of each RSS feed item. * * @since 2.0.0 */ do_action( 'rss_item' ); ?> </item> <?php endwhile; ?> <?php else: ?> <?php while (have_posts()) : the_post(); ?> <?php $link = get_field('acf_link', $post->ID ); ?> <item> <title><?php the_title_rss() ?></title> <?php if( $link ): ?> <link><?php $link; ?></link> <?php else: ?> <link><?php echo home_url('/') ?></link> <?php endif; ?> <?php /** * Fires at the end of each RSS feed item. * * @since 2.0.0 */ do_action( 'rss_item' ); ?> </item> <?php endwhile; ?> <?php endif; ?> </channel> </rss> |
これでよし。
以上、現場からでした。