rss

WordPress RSS/Atomフィード カスタマイズ

はじめに

やりたいこと

  1. コメントフィードをなくす
  2. 投稿フィードの内容をアイキャッチ画像+記事抜粋にする
  3. 著者を書き換える
  4. カスタムタクソノミーのフィードを追加

環境

  • WordPress 4.2

参考にしたサイト

0.WordPressの実装を確認

フィードのテンプレートは /wp-includes の下にありました。

  • feed-atom.php
  • feed-atom-comments.php
  • feed-rdf.php
  • feed-rss.php
  • feed-rss2-comments.php

ヘッダーのフィードリンクの出力は /wp-includes/general-templage.php にありました。

feed_linksでは下記2つのフィードを出力しています。

  • 全ページにサイト全体の投稿フィード
  • 全ページにサイト全体のコメントのフィード

/**
 * Display the links to the general feeds.
 *
 * @since 2.8.0
 *
 * @param array $args Optional arguments.
 */
function feed_links( $args = array() ) {
	if ( !current_theme_supports('automatic-feed-links') )
		return;

	$defaults = array(
		/* translators: Separator between blog name and feed type in feed links */
		'separator'	=> _x('»', 'feed link'),
		/* translators: 1: blog title, 2: separator (raquo) */
		'feedtitle'	=> __('%1$s %2$s Feed'),
		/* translators: 1: blog title, 2: separator (raquo) */
		'comstitle'	=> __('%1$s %2$s Comments Feed'),
	);

	$args = wp_parse_args( $args, $defaults );

	echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( sprintf( $args['feedtitle'], get_bloginfo('name'), $args['separator'] ) ) . '" href="' . esc_url( get_feed_link() ) . "\" />\n";
	echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( sprintf( $args['comstitle'], get_bloginfo('name'), $args['separator'] ) ) . '" href="' . esc_url( get_feed_link( 'comments_' . get_default_feed() ) ) . "\" />\n";
}

feed_links_extraでは、下記6つのフィードを出力しています。

  • シングルページに、その投稿へのコメントフィード
  • 投稿タイプアーカイブページに、投稿フィード
  • カテゴリアーカイブページに、投稿フィード
  • タグアーカイブページに、投稿フィード
  • 作成者アーカイブページに、投稿フィード
  • 検索ページに、投稿フィード

/**
 * Display the links to the extra feeds such as category feeds.
 *
 * @since 2.8.0
 *
 * @param array $args Optional arguments.
 */
function feed_links_extra( $args = array() ) {
    $defaults = array(
        /* translators: Separator between blog name and feed type in feed links */
        'separator'   => _x('&raquo;', 'feed link'),
        /* translators: 1: blog name, 2: separator(raquo), 3: post title */
        'singletitle' => __('%1$s %2$s %3$s Comments Feed'),
        /* translators: 1: blog name, 2: separator(raquo), 3: category name */
        'cattitle'    => __('%1$s %2$s %3$s Category Feed'),
        /* translators: 1: blog name, 2: separator(raquo), 3: tag name */
        'tagtitle'    => __('%1$s %2$s %3$s Tag Feed'),
        /* translators: 1: blog name, 2: separator(raquo), 3: author name  */
        'authortitle' => __('%1$s %2$s Posts by %3$s Feed'),
        /* translators: 1: blog name, 2: separator(raquo), 3: search phrase */
        'searchtitle' => __('%1$s %2$s Search Results for &#8220;%3$s&#8221; Feed'),
        /* translators: 1: blog name, 2: separator(raquo), 3: post type name */
        'posttypetitle' => __('%1$s %2$s %3$s Feed'),
    );

    $args = wp_parse_args( $args, $defaults );

    if ( is_singular() ) {
        $id = 0;
        $post = get_post( $id );

        if ( comments_open() || pings_open() || $post->comment_count > 0 ) {
            $title = sprintf( $args['singletitle'], get_bloginfo('name'), $args['separator'], the_title_attribute( array( 'echo' => false ) ) );
            $href = get_post_comments_feed_link( $post->ID );
        }
    } elseif ( is_post_type_archive() ) {
        $post_type = get_query_var( 'post_type' );
        if ( is_array( $post_type ) )
            $post_type = reset( $post_type );

        $post_type_obj = get_post_type_object( $post_type );
        $title = sprintf( $args['posttypetitle'], get_bloginfo( 'name' ), $args['separator'], $post_type_obj->labels->name );
        $href = get_post_type_archive_feed_link( $post_type_obj->name );
    } elseif ( is_category() ) {
        $term = get_queried_object();

        if ( $term ) {
            $title = sprintf( $args['cattitle'], get_bloginfo('name'), $args['separator'], $term->name );
            $href = get_category_feed_link( $term->term_id );
        }
    } elseif ( is_tag() ) {
        $term = get_queried_object();

        if ( $term ) {
            $title = sprintf( $args['tagtitle'], get_bloginfo('name'), $args['separator'], $term->name );
            $href = get_tag_feed_link( $term->term_id );
        }
    } elseif ( is_author() ) {
        $author_id = intval( get_query_var('author') );

        $title = sprintf( $args['authortitle'], get_bloginfo('name'), $args['separator'], get_the_author_meta( 'display_name', $author_id ) );
        $href = get_author_feed_link( $author_id );
    } elseif ( is_search() ) {
        $title = sprintf( $args['searchtitle'], get_bloginfo('name'), $args['separator'], get_search_query( false ) );
        $href = get_search_feed_link();
    } elseif ( is_post_type_archive() ) {
        $title = sprintf( $args['posttypetitle'], get_bloginfo('name'), $args['separator'], post_type_archive_title( '', false ) );
        $post_type_obj = get_queried_object();
        if ( $post_type_obj )
            $href = get_post_type_archive_feed_link( $post_type_obj->name );
    }

    if ( isset($title) && isset($href) )
        echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( $title ) . '" href="' . esc_url( $href ) . '" />' . "\n";
}

1.コメントフィードをなくす

私の仕事で運営しているサイトは会員制で、会員以外にはコメントを公開していないため、コメントフィードを止めます。

ヘッダのコメントフィードを出力しない様にするだけでは直接URLを打ったら見えてしまうため、コメントフィードのページと、ヘッダへのコメントフィード出力の2箇所をカスタマイズします。

コメントフィードのページを停止

フィードのテンプレートをいじるでも良いのですが、複数あって面倒なので、parse_queryフックでwp_dieする方法を採用。


add_action( 'parse_query', 'stop_comment_feed' );
function stop_comment_feed( $request ) {
	if ( $request->is_comment_feed() ) {
		wp_die("このページのフィードはありません。<br>".'<a href="'.home_url('/').'">トップページへ</a>', 'タイトル',array('response' => 200));
	}
}

レスポンスコードは404とかの方が良いかもしれませんが、Googleウェブマスターツールでソフト404検出されてしまったので、200にしてます。

ヘッダーのコメントフィードを出力停止

上記対応でコメントフィードは読めませんが、ヘッダに出力されていると、RSSリーダー等で検知してしまうし、Googleでクロールもされるので、コメントフィードリンクの出力も止めることにします。

general-templage.phpのfeed_linksとfeed_links_extraの両方にコメントフィードリンク出力があるので、それぞれ止めます。

feed_linksは一旦remove_actionして、書き換えたものをadd_actionすることにしました。

feed_links_extraは、コメントフィードを出力しているのはシングルページだけなので、シングルページの場合にremove_actionすることにしました。


add_action('wp','my_comment_feed_links');
function my_comment_feed_links() {
	remove_action('wp_head', 'feed_links', 2);
	add_action('wp_head', 'my_feed_links', 2);
	if (is_singular()){
		remove_action('wp_head', 'feed_links_extra', 3);
	}
}

function my_feed_links($args = array()) {
	
	$defaults = array(
	/* translators: Separator between blog name and feed type in feed links */
	'separator'	=> _x('&raquo;', 'feed link'),
	/* translators: 1: blog title, 2: separator (raquo) */
	'feedtitle'	=> __('%1$s %2$s Feed'),
	);

	$args = wp_parse_args( $args, $defaults );
	echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( sprintf( $args['feedtitle'], get_bloginfo('name'), $args['separator'] ) ) . '" href="' . esc_url( get_feed_link() ) . "\" />\n";

}

wpにフックしてますが、条件分岐タグが使える最初のアクションなのでそうしました。ここからwp_headerまでの間であれば大丈夫なはず。

2.投稿フィードの内容をアイキャッチ画像+記事抜粋にする

仕事で運営しているサイトは会員制で、会員以外には全文公開しておらず、フィールドも本文ではなくカスタムフィールドをメインで使っているためカスタマイズ。また、feedlyで画像が表示されなかったのその対応も合わせて実施。

フィードのテンプレートをいじって対応する方法もありますが、the_excerpt_rss、the_content_feed のアクションフックがあったので、こちらで対応。


add_filter( 'the_excerpt_rss',  'my_feed_content');
add_filter( 'the_content_feed', 'my_feed_content');
function my_feed_content($content) {
	global $post;
	$content = wp_trim_words(get_post_meta($post->ID, 'post_meta_key', true),100);
	if (has_post_thumbnail( $post->ID)) {
		$content = '<p>'.get_the_post_thumbnail($post->ID).'</p>'.$content;
	}
	return $content;
}

3.著者を書き換える

仕事で運営しているサイトでは、投稿者が記事の筆者とは限らないので、筆者の部分をカスタマイズ。

フィードテンプレートをいじるでも良いですが複数あって面倒なので、the_authorにフック。


add_filter('the_author','change_feed_author');
function change_feed_author($name){
	if ( is_feed()) {
		$name = 'John Doe';
	}
	return $name;
}

実際にはカスタム投稿タイプ別に分岐したりして実装しているのですが、上記サンプルコードは単純化してます。

4.カスタムタクソノミーのフィードを追加

仕事で運営しているサイトでは、カスタムタクソノミーを利用しており、そのアーカイブページもあるため、そのフィードを追加。

上記対応で追加したしたファンクションmy_comment_feed_linksにmy_feed_links_extraを実行するフックを追記しています。


add_action('wp','my_comment_feed_links');
function my_comment_feed_links() {
	remove_action('wp_head', 'feed_links', 2);
	add_action('wp_head', 'my_feed_links', 2);
	if (is_singular()){
		remove_action('wp_head', 'feed_links_extra', 3);
	} elseif (is_tax()){
		add_action('wp_head','my_feed_links_extra',3);
	}
}

function my_feed_links($args = array()) {
	
	$defaults = array(
	/* translators: Separator between blog name and feed type in feed links */
	'separator'	=> _x('&raquo;', 'feed link'),
	/* translators: 1: blog title, 2: separator (raquo) */
	'feedtitle'	=> __('%1$s %2$s Feed'),
	);

	$args = wp_parse_args( $args, $defaults );
	echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( sprintf( $args['feedtitle'], get_bloginfo('name'), $args['separator'] ) ) . '" href="' . esc_url( get_feed_link() ) . "\" />\n";

}

function my_feed_links_extra( $args = array() ) {

	$defaults = array(
		/* translators: Separator between blog name and feed type in feed links */
		'separator'   => _x('&raquo;', 'feed link'),
		/* translators: 1: blog name, 2: separator(raquo), 3: tag name */
		'tagtitle'    => __('%1$s %2$s %3$s Tag Feed'),
	);

	$args = wp_parse_args( $args, $defaults );
	
	if ( is_tax() ) {
		$term = get_queried_object();
		if ( $term ) {
			$title = sprintf( $args['tagtitle'], get_bloginfo('name'), $args['separator'], $term->name );
			$href = get_term_feed_link( $term->term_id ,$term->taxonomy);
		}
	}
	if ( isset($title) && isset($href) )
		echo '<link rel="alternate" type="' . feed_content_type() . '" title="' . esc_attr( $title ) . '" href="' . esc_url( $href ) . '" />' . "\n";
}

文言はタグのものを流用してます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です