サポートフォーラムでの要望

公開しているプラグイン、Markup (JSON-LD) structured in schema.orgサポートフォーラムで増えてきた問合せがありまして、「ArticleやBlogPosting、NewsArticleのschema.orgタイプでImageObjectを出力したいが、アイキャッチ画像を設定していなので出力されない。」というもの。AMPでは必須のこの項目ですが、AMPでなければ推奨なので設定しなくても問題はないはずなのですが、Googleの構造化テストツールでエラー(警告)が出てしまうので気持ち悪い。ImageObjectの定義は以下の通り。

"image": {
  "@type": "ImageObject",
  "url": 画像のURL,
  "width": 画像の幅,
  "height": 画像の高さ
}

アイキャッチが設定してある場合は、その画像のURLをwp_get_image_editor関数の引数として渡して、画像のサイズ(幅・高さ)を取得してセットしています。以前、「画像サイズの取得にWP_Image_Editorクラスを使う」という記事でもまとめた内容です。
そこで、投稿記事内に含まれる最初のimgタグのURL(src属性)を正規表現で抜き出して、アイキャッチ画像と同じようにサイズを取得してセットできるようにしようと思います。

preg_match関数で正規表現

PHPの関数、preg_matchを使用して投稿記事内の最初のimgタグにマッチする正規表現を書きました。

※PHP:メタ文字参照

$pattern = '/<img.*?src\s*=\s*[\"|\'](.*?)[\"|\'].*?>/i';
preg_match( $pattern, $content, $images );
  • $pattern ・・・ 正規表現のパターン文字列
  • $content ・・・ 投稿記事全文(HTML)
  • $image ・・・ 正規表現の結果配列保存変数

正規表現のポイントは、(.*?)の部分。正規表現のサブパターンでキャプチャされる部分にsrc属性の値を設定しています。これで、imgタグ全体とsrc属性の値が取得できる…はず。

出力例は以下のようになりました。

array (size=2)
  0 => string '<img src="http://vccw.dev/wp-content/uploads/2017/02/kinoko-300x199.jpg" alt="" width="300" height="199" class="alignnone size-medium wp-image-2259" />' (length=151)
  1 => string 'http://vccw.dev/wp-content/uploads/2017/02/kinoko-300x199.jpg' (length=61)

とれた!\(^o^)/
配列の0番目にimgタグ全体、1番目にsrc属性の値がちゃんと取得できました。あとは、これを関数化して使いやすくしたかったので(src属性の値を返すだけの関数)、以下のような関数にしてみました。

public function get_content_image ( $content ) {
	$pattern = '/<img.*?src\s*=\s*[\"|\'](.*?)[\"|\'].*?>/i';

	if ( preg_match( $pattern, $content, $images ) ){
		if ( is_array( $images ) && isset( $images[1] ) ) {
			return $images[1];
		} else {
			return false;
		}
	} else {
		return false;
	}
}

引数に投稿記事の文字列を渡して、文字列内の最初のimgタグのsrc属性の値を返す関数。いろいろ使えそう。

preg_match_all関数

preg_match関数は、最初に正規表現でマッチした文字列を取得しますが、preg_match_all関数は、マッチした文字列を全て取得します。投稿記事内にimgタグを全て取得したい場合にはこちらを使用します。先程のpreg_match関数をpreg_match_all関数に変えるだけでOKです。

$pattern = '/<img.*?src\s*=\s*[\"|\'](.*?)[\"|\'].*?>/i';
preg_match( $pattern, $content, $images );

これを出力すると…

array (size=2)
  0 => 
    array (size=3)
      0 => string '<img src="http://vccw.dev/wp-content/uploads/2017/02/kinoko-300x199.jpg" alt="" width="300" height="199" class="alignnone size-medium wp-image-2259" />' (length=151)
      1 => string '<img src="http://vccw.dev/wp-content/uploads/2011/07/cropped-dscn33161-300x300.jpg" alt="" width="300" height="300" class="alignnone size-medium wp-image-2221" />' (length=162)
      2 => string '<img src="http://vccw.dev/wp-content/uploads/2013/03/featured-image-horizontal-300x155.jpg" alt="Horizontal Featured Image" width="300" height="155" class="alignnone size-medium wp-image-1022" />' (length=195)
  1 => 
    array (size=3)
      0 => string 'http://vccw.dev/wp-content/uploads/2017/02/kinoko-300x199.jpg' (length=61)
      1 => string 'http://vccw.dev/wp-content/uploads/2011/07/cropped-dscn33161-300x300.jpg' (length=72)
      2 => string 'http://vccw.dev/wp-content/uploads/2013/03/featured-image-horizontal-300x155.jpg' (length=80)

このように2次元配列で取得できました。こちらも使用する機会がありそうなのでおぼえておくことにします。

4.1.0リリース

この正規表現を使用したMarkup (JSON-LD) structured in schema.orgのバージョン4.1.0をリリースしました。サポートフォーラムから学ぶこと多い。