サイトにtwitter cardを実装する

サイトのURLをツイートしたときにtwitter cardが表示されるようにしたのでメモ。
プラグインは使ってないよ!

まずはtwitterカードのコードを書くファイル「twitter-card.php」を作成して、header.phpと同じ場所に置く。で、それを読み込ませるコードを「header.php」の<head>~</head>内に書く。

    <?php get_template_part('twitter-card');?>

次は肝心の「twitter-card.php」の中身。

投稿にアイキャッチ画像が設定されている場合はアイキャッチ画像を、アイキャッチ画像がない場合は投稿の中の最初の画像を、投稿の中にも画像がない場合は任意の代替画像をtwitterカードに表示する。

<?php
  $my_id = get_queried_object_id();
  $my_post = wp_get_single_post($my_id)->post_content;
  $thumb_id = get_post_thumbnail_id($my_id);

  $my_card_summary = str_replace(array("\r", "\n"), '',
   mb_substr(strip_tags($my_post), 0,150,'UTF-8'));

if(has_post_thumbnail($my_id)){
 // ↑ 投稿にアイキャッチ画像があるか調べる

$thumb_url = wp_get_attachment_image_src($thumb_id,'full');}

else{
$str = $post->post_content;
$searchPattern = '/<img.*?src=(["\'])(.+?)\1.*?>/i';
// ↑ 投稿にイメージがあるか調べる

    if (preg_match( $searchPattern, $str, $imgurl )) {
   $thumb_url[0] =  $imgurl[2];
  }
    else{
    $thumb_url[0] = '【代替する画像のURL】';
   }
}

?>

<meta property="og:url" content="<?php echo get_permalink($my_id); ?>">
<meta property="og:title" content="<?php single_post_title(); ?>">
<meta property="og:description" content="<?php echo $my_card_summary; ?>">
<meta property="og:image" content="<?php echo $thumb_url[0]; ?>">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@【管理者のtwitterID】">

タイトルとかサマリーはコピペで問題ないとして、「アイキャッチ画像がない場合は最初の画像を表示する」の処理が大変だった(参考にした記事が古くて)。

まずはhas_post_thumbnail()で「アイキャッチ画像がある場合」の処理を済ませる。

次に「ない場合」についてはpreg_match()関数で投稿内に画像があるかどうかを調べる……つまり、htmlの中に「<img src=”~~”>」が含まれるかどうかを調べる。

preg_match()
「ある文字列から正規表現で指定したパターンにマッチした文字列を検索」する。
パターンにマッチした場合は1を返し、マッチしなかったら0を返す。

preg_match(/正規表現パターン/,検索対象の文字列,[配列],[動作フラグ],[検索開始位置])

「正規表現パターン」が難しいけど、ググるときのキーワードだと思っておけば今はOK。

今回のやり方では「正規表現パターン」を一度$searchPatternという変数に代入、「検索対象の文字列」も一度$strという変数に代入している。これで見た目がスッキリ。

$str = $post->post_content;
$searchPattern = '/<img.*?src=(["\'])(.+?)\1.*?>/i';

preg_matchはマッチ結果が入る配列(今回は「imgurl[]」)にマッチ部分の文字列が格納される。

分からないのは最初の画像のURLが $imgurl[2] の中に勝手に入ってくれてる部分なんだけど…正規表現パターンをちゃんと理解していたら分かるのかもしれない。今回はパス。

動けばよかろう!!

あとは、投稿内に画像がない場合の処理…つまり代替画像のURLを指定。

最後に、card validatorで動作確認とかして完了。

というわけで、また何か動作がヘンなとこ見つけたらその時に調べようと思う。おわり。

2023/7/4 追記

上記は「何らかの画像を含む投稿ページ」or「それ以外」で場合分けするだけだったんだけど、それにプラスして固定ページにアイキャッチ画像を設定している場合はそれを表示できるようにちょっとだけ改良。

一番最初に「固定ページかどうか」で分岐させるif文を追加した。

<?php
  $my_id = get_queried_object_id();
  $my_post = wp_get_single_post($my_id)->post_content;
  $thumb_id = get_post_thumbnail_id($my_id);

  $my_card_summary = str_replace(array("\r", "\n"), '',
   mb_substr(strip_tags($my_post), 0,150,'UTF-8'));

//↓ ここからが追加された部分

if(is_page()){

    if(has_post_thumbnail($my_id)){
         $thumb_url[0] = get_the_post_thumbnail_url( $post->ID );
    }

    else{
    $thumb_url[0] = '【代替画像のURL】';
    $description = '';
        }
}

//↑ ここまでが追加分
//↓ 続きの分岐をelseif文で処理

elseif(has_post_thumbnail($my_id)){
 //↑ 投稿にアイキャッチ画像があるか調べる

$thumb_url = wp_get_attachment_image_src($thumb_id,'full');
	$description = $my_card_summary; 
}

else{
$str = $post->post_content;
$searchPattern = '/<img.*?src=(["\'])(.+?)\1.*?>/i';
// ↑ 投稿にイメージがあるか調べる

    if (preg_match( $searchPattern, $str, $imgurl )) {
   $thumb_url[0] =  $imgurl[2];
  }
    else{
    $thumb_url[0] = '【代替する画像のURL】';
   }
}

?>

<meta property="og:url" content="<?php echo get_permalink($my_id); ?>">
<meta property="og:title" content="<?php single_post_title(); ?>">
<meta property="og:description" content="<?php echo $my_card_summary; ?>">
<meta property="og:image" content="<?php echo $thumb_url[0]; ?>">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@【管理者のtwitterID】">

投稿一覧(アーカイブ)ページでは最新の投稿で使っている画像を表示する、とかしたいけども…まあいずれそのうち。