rssショートコードにサイト名かドメイン名を追加する方法

Cocoonカスタマイズ集
この記事は約6分で読めます。
記事内に広告が含まれています。

Cocoon 2.9.1でサポートされたサイト名表示は、RSS配信元の<channel>タグに含まれるサイト名を取得する仕様です。
一方、本コードは、各記事アイテムごとに外部サイトのOGP情報まで参照します。
ただし、対象ページにog:site_nameが設定されていない場合は表示されません。

はじめに

以下の質問に回答します。

RSS仕様では、各アイテムにサイト名は含まれていません。

そのため、rssショートコードでは各アイテムのOGPを取得してog:site_nameを表示します。
また、og:site_nameは任意のため、存在しない場合はドメイン名を使用します。

この記事では、この方法について説明します。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

add_filter('cocoon_part_args__tmp/rss-card', function ($args, $name) {
  $url = isset($args['url']) ? $args['url'] : '';

  if (empty($url)) {
    return $args;
  }

  // キャッシュデータを取得
  $cache_key = 'rss_ogp_site_name_' . md5($url);
  $site_name = get_transient($cache_key);

  if ($site_name !== false) {
    $args['site_title'] = $site_name;

    return $args;
  }

  // 自身のサイト、リンク先のドメイン名を取得
  $my_host   = parse_url(home_url(), PHP_URL_HOST);
  $link_host = parse_url($url, PHP_URL_HOST);

  // 自サイトの場合
  if ($link_host === $my_host) {
    $site_name = get_bloginfo('name');
  } else {
    // 外部サイトの場合はOGPから取得
    $ogp = class_exists('OpenGraphGetter') ? OpenGraphGetter::fetch($url) : null;

    // site_nameがない場合はドメイン名を設定
    if ($ogp && !empty($ogp->site_name)) {
      $site_name = $ogp->site_name;
    } else {
      $site_name = $link_host ? $link_host : '';
    }
  }

  // キャッシュ時間を計算(デフォルト: 60分)
  $cache_minutes = isset($args['cache_minute']) ? (int) $args['cache_minute'] : 60;

  // キャッシュデータを保存
  set_transient($cache_key, $site_name, 60 * $cache_minutes);

  $args['site_title'] = $site_name;

  return $args;
}, 10, 2);

参考:サイトタイトルを自動追加する方法

「RSS」ウィジェットでは、指定したURLに対応するサイトタイトルが自動的に表示されます。
そこで、rssショートコードでも同じように、取得したサイトタイトルを出力に追加します。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

add_filter('do_shortcode_tag', function ($output, $tag, $attr) {
  if ($tag !== 'rss') {
    return $output;
  }

  $rss_url = isset($attr['url']) ? $attr['url'] : null;

  if (!$rss_url) {
    return $output;
  }

  // キャッシュデータを取得
  $cache_minute = isset($attr['cache_minute']) ? (int) $attr['cache_minute'] : 60;
  $cache_key = 'rss_site_info_' . md5($rss_url);
  $site_info = get_transient($cache_key);

  // キャッシュがない場合は取得
  if ($site_info === false) {
    // channelのtitleおよびlinkを取得
    include_once(ABSPATH . WPINC . '/feed.php');
    $rss = fetch_feed($rss_url);

    $site_info = ['title' => '', 'link' => ''];

    if (!is_wp_error($rss)) {
      $site_info['title'] = $rss->get_title() ?: '';
      $site_info['link']  = $rss->get_permalink() ?: $rss->get_link() ?: '';
    }

    // キャッシュデータを保存
    set_transient($cache_key, $site_info, 60 * $cache_minute);
  }

  // タイトルがない場合
  if (empty($site_info['title'])) {
    return $output;
  }

  $title_html = esc_html($site_info['title']);
  $link       = esc_url($site_info['link']);

  $inner = $link
    ? '<a href="' . $link . '" target="_blank" rel="noopener noreferrer">' . $title_html . '</a>'
    : $title_html;

  return '<h2 class="rss-site-name">' . $inner . '</h2>' . $output;
}, 10, 3);

さいごに

今回紹介した方法を使えば、rssショートコードで表示される記事一覧に、自動でサイト名やドメイン名を追加でき、どのサイトの記事かが一目で分かるようになります。
OGP情報がなくてもドメイン名を表示するため、見た目の統一性も保てます。

投稿タイトルにサイト名が含まれている場合もあり、またog:site_name自体は任意の項目なので、無理にこだわる必要はないのでは?

タイトルとURLをコピーしました