WordPressの出力を書き換えてimgタグにクラスを付与する

テーマ作っていて、やはりlazyloadは必須だよなぁとか考えて。

まぁプラグインでいいじゃないと言えばそうなのですが、今回はプラグイン不要のテーマを目標に(というか諸事情で必須)なので気合いで対応しようと思い立ちました。

今回使おうとしたのはlazysizes(参考サイト)。これまであまり遅延読み込み系のjsは使ってなかったこともあって、よくわからないけど良さげだったので。

使い方としてはシンプルでclassにlazyloadを追加、srcはdata-srcにするだけの簡単実装。

と思っていたのですが…。

これを対応させるための方法論はいくつか。

  1. 「メディアを追加」段階で遅延読み込み用のソースを書き出す。これはフィルターフックimage_send_to_editorで可能(参考サイト)。しかし当然のごとく「過去記事は編集しなおさないといけない」「別のテーマに乗り換えたら画像表示されなくて詰む」。よってボツ。
  2. フィルターフックget_image_tagを使い書き換え。最初この路線でやろうとしていて、「きれいにimgタグだけ書き換えられるじゃーん」とか思ってたんですが、まさかの出力されたHTMLだけじゃなくエディタにも書き換えが発生することが発覚。これだとテーマが切り替わったときもダメだし、ビジュアルエディタで画像も表示されなくなる…。
  3. jsで書き換え。これはテストしてませんが…結局js使うんかい!みたいな感じでボツ。
  4. コンテンツとして出力されるimgタグを書き換え。結局こうなりました。

functions.php

/*  * lazyload  * imgタグにlazyloadタグを付与、srcをdata-srcに書き換える  */ function add_img_lazyload($string){  $pattern = '/<img class="(.+?)" src/i';  $replacement = '<img class="lazyload ${1}" data-src';  echo preg_replace($pattern, $replacement, $string); } add_filter('the_content', 'add_img_lazyload');

これも厳密にはclass→srcの順で並んでないとアウトなんですが…。改良は出来そうだけど後日。

追記です。

前述のだと順番もそうですがclassが指定されてない時もlazyloadが付与されないので修正しました。


/*
 * lazyload
 * imgタグにlazyloadタグを付与、srcをdata-srcに書き換える
 */
function add_img_lazyload($string){
	//imgタグを検索(配列subjectに格納 ※2重)
	if(preg_match_all('/<img.*?>/i', $string, $subject) > 0){
		//配列foreach(1週目は意味なし)
		foreach ($subject as &$value) {
			$ori = $value;
			foreach($value as &$v){
				if(preg_match('/ class *?= *?".+?"/', $v)){
					$pattern = array();
					$pattern[0] = '/<img(.*?) src *?= *?"(.*?)>/i';
					$pattern[1] = '/<img(.*?) class *?= *?"(.+?)"(.*?)>/i';
					$replacement = array();
					$replacement[0] = '<img${1} data-src="${2}>';
					$replacement[1] = '<img${1} class="lazyload ${2}"${3}>';
					$v = preg_replace($pattern, $replacement, $v);
				} else {
					$pattern = '/<img(.*?) src *?= *?"(.*?)>/i';
					$replacement = '';
					$v = preg_replace($pattern, $replacement, $v);
				}
			}
			$new = $value;
			unset($v);
		}
		unset($value);
		echo str_replace($ori, $new, $string);
	} else {
		echo $string;
	}
}
add_filter('the_content', 'add_img_lazyload');

結局この記事書いてた時から寝てません。変数名が適当ですね。つかれた…。