embed

PHP

【WordPress】自サイトのブログカードからiframeを解除して高速化する方法

更新日:2023/03/17

WordPressのブログカードはiframeタグが使用されるため、ブラウザにページが表示された後にWebサーバーから情報を取得します。

この仕組みはページの表示が完了するまでに時間がかかるという問題がありますが、さらに問題なのがブログカードの数だけ余計に通信コストがかかるという点です。

そこで今回は、自サイトのブログカードからiframeを除去することで余計な通信を排除します。
その結果、Webページ表示の高速化にもつながります。

 

wp_embed_register_handler()

wp_embed_register_handler()を使用すると、ブログカードを構成するタグを自作できます。
自作したタグはチェックされないので、htmlのタグを使って自由にブログカードを作成できます。

wp_embed_register_handler()の定義

wp_embed_register_handler( $id, $regex, $callback, $priority = 10 )
  • $id : 他と重複しない文字列ならなんでもいい
  • $regex : 対象URLとマッチする正規表現
  • $callback : マッチしたときに呼び出される関数
  • $priority : 優先順位

ブログカード生成は、最初にwp_embed_register_handler()で登録した$regexと対象URLがマッチするかどうか確認されます。

マッチする場合、$callbackが呼び出され、戻り値がブログカードのタグデータとして利用されます。

何もマッチしない場合は、iframeでのブログカードが生成されます。

この関数を使いこなすには正規表現の知識が必要ですが、今回の使用目的に限るなら後で紹介するコードをコピペするだけで大丈夫です。

今回はこの関数を自サイトURLで使用しますが、他サイトのURLでも利用可能です。

$callbackの形式は、つぎのようになっています。

function callback($matches, $attr, $url, $rawattr)
  • $matches : 対象URLとのマッチ結果
  • $attr : widthとheightがセットされた連想配列。実際のブログカードのサイズと関連は無い
  • $url : 対象URL
  • $rawattr : 空の配列

$attr$rawattrは、ここではあまり意味がないですね。

 

使用例

wp_embed_register_handler()を呼び出す例です。

add_action( 'init' , function(){
	$id = 'my_blogcard_internal_URL';
	$regx = '#^'.get_home_url().'#';
	wp_embed_register_handler( $id ,$regx, 'my_blogcard_internal' );
});

get_home_url()はhttpから始まるサイトURLを取得できます。
これを正規表現に組み込むことで、自サイトのWebページURLとマッチさせています。

'my_blogcard_internal'は、タグデータを生成する関数の名前です。
次項で、記述例を紹介します。

 

オリジナルのブログカードを生成

既存のブログカードを生成するのは少し手間がかかるので、まずはオリジナルブログカードの生成例を紹介します。

次のようなブログカードを生成します。

オリジナルブログカードの生成例
※注:画像なので、クリックしても飛びません。

コードは、次のようになります。

function my_blogcard_internal($matches, $attr, $url, $rawattr){
	global $my_blogcard_internal_flg;

	$post_id = url_to_postid($url); // urlから投稿IDを取得
	if( $post_id === false ) return false;

	if( !isset( $my_blogcard_internal_flg ) ){
		  // スタイルを出力するアクションを登録
		$my_blogcard_internal_flg = true;
		add_action('wp_footer','my_blogcard_internal_css');
	}
	
	$post = get_post($post_id);    // 投稿データ取得
	$title = $post->post_title; // タイトル
	// $excerpt = get_the_excerpt($post); // 概要取得 危険
	$date = get_the_modified_date('Y年m月d日',$post); // 更新日

	$link_before = '<a href="'.esc_url($url).'">';

	$img_url = get_the_post_thumbnail_url( $post  ); // サムネイルURL取得
	$img_tag = $img_url===false ? ''
	            : $link_before.'<img src="'.esc_url($img_url).'"  /></a>';

	return '<div class="my_blogcard_internal">'
			  .'<div class="my_blogcard_internal_image">'.$img_tag.'</div>'
			  .'<div class="my_blogcard_internal_text">'
			    .'<p class="my_blogcard_title">'.$link_before.esc_html($title).'</a></p>'
				.'<p>&nbsp;</p>'
			    .'<p class="my_blogcard_date"> '.$date.'</p>'
			  .'</div>'
			.'</div>';
}

URLを投稿IDに変換して、必要な情報を取得。
それを元に、タグを生成しているだけです。

なお今回はコメントになっていますが、対象URLの投稿内容にURLが含まれるときにget_the_excerpt()を呼び出すと、ブログカードの生成が行われます。そして生成後にブログカードタグが除去されます。
無駄な処理なので、抜粋が必要なときは次のように$post->post_excerptを使用した方がよさそうです。

  // 抜粋データ取得(存在しない時は投稿内容を使用)
$excerpt =  empty($post->post_excerpt) ? $post->post_content : $post->post_excerpt;
  // タグ削除 → 100文字で切り捨て
$excerpt = mb_substr( strip_tags( $excerpt) , 0 , 100 );
  // 改行除去 → htmlエスケープ
$excerpt = esc_html(str_replace(array("\r\n", "\r", "\n"),'',$excerpt));

オリジナルのブログカードタグのスタイルは、wp_footerアクションで出力しています。
このアクションで次の関数を呼び出します。

function my_blogcard_internal_css(){
?>
<style>
.my_blogcard_internal{
	border: 1px solid gray;
	padding: 1em;
	display: flex;
	position:relative;
}
.my_blogcard_internal .my_blogcard_internal_image{
	width: 150px;
	padding: 0;
	margin-right: 15px;
}
.my_blogcard_internal .my_blogcard_internal_text{

}
.my_blogcard_internal .my_blogcard_title a{
	color: #454969;;
	text-decoration: none;
	font-size: 1.2em;
	font-weight: bold;
	line-height: 1.2;
}
.my_blogcard_internal .my_blogcard_date{
	position:absolute;
	font-size:0.8em;
	color:gray;
	bottom:15px;
	right:15px;
}
</style>
<?php
}

 

規定のブログカードを生成

次は、WordPressのデフォルトブログカードをiframeを使用しないで生成します。

生成されたカードは、次のようになります。

WordPressのデフォルトブログカード

なお実際のブログカードには次のようなシェアボタンが設置されます。

ボタンを機能させるには手間が非常にかかりそうなので、今回は非表示にしてあります。
(既存のスクリプトを解析するよりも、スクリプトを自作した方が簡単のような気がします)

では、コードです。

function my_blogcard_internal($matches, $attr, $url, $rawattr){
	global $post;
	global $my_blogcard_internal_flg;

	$post_id = url_to_postid($url);
	if( $post_id === false ) return false;

	if( !isset( $my_blogcard_internal_flg ) ){
		$my_blogcard_internal_flg = true;
		add_action('wp_footer','my_blogcard_internal_css');
	}
	global $wp_embed;
	  // 抜粋に対するthe_contentフィルター対策
	remove_filter('the_content', array( $wp_embed, 'autoembed' ),8);

	$post = get_post($post_id);
	setup_postdata($post);

	ob_start();  // echo出力をバッファ
	echo '<div class="js">';
	  // ブログカードのテンプレートを呼び出す
	get_template_part( 'embed', 'content' );
	echo '</div>';
	$html = ob_get_contents(); // バッファの取得
	ob_end_clean();  // バッファ後始末

	  // 改行→<br>変換対策
	$html = str_replace(array("\r\n", "\r", "\n"),'',$html);

	  // the_contentフィルター復帰
	add_filter('the_content', array( $wp_embed, 'autoembed' ),8);

	return $html;
}

基本的には、規定のブログカードを作成しているテンプレートを読み込んでいるだけです。

規定のブログカードは抜粋の取得が行われます。
抜粋や投稿内容に外部URLがあると、そのURLのブログカード取得がおこなわれます。
ムダな処理なので、該当するフィルターを一時的に削除しています。

スタイルの出力は、次のようになります。

function my_blogcard_internal_css(){
	print_embed_styles();
?>
<style>
.wp-embed-share{
	display:none;		
}
</style>
<?php
}

print_embed_styles()でスタイルを取得しているので、そのまま呼び出しています。

残りのスタイルは、シェアボタンを非表示にしています。

 

素敵なブログカードを作ろう

今回紹介した方法を使用すれば、好みのブログカードが作成できますね。

htmlとcssの知識があればという前提ですが、そこは頑張って勉強しましょう。

WordPressはHTMやCSSの知識も必要。総合的な知識を身につけよう。

更新日:2023/03/17

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。