できる!Snow Monkey カスタマイズ – ブログカード編

この記事は、不定期連載「できる!Snow Monkey カスタマイズ 」の第5回目です。

今回の記事のテーマ

Snow Monkeyのテーマには、別のサイトやページのタイトルや詳細をリッチにリンク表示する為のブログカードと言う仕組みがあります。
今回は、そのブログカードのカスタマイズについて解説を行います。

ブログカードの表示をプラグインでカスタマイズ

My Snow Monkeyプラグインを使用してブログカードの表示を変更する方法を解説します。Snow Monkey v7現在、テーマフックでは出来ない部分をご紹介します。

ブログカードとは?

WordPressにはEmbedという機能があり、リンク先URLがoEmbedというプロトコルに準拠している場合には自動的にカード表示に変換される仕様になっています。その変換されたカード表示部分のことをブログカードと呼んでいます。

ルミェール

下記のようなカード表示がブログカードだよ!

ルミェール(アイコン01)
テネーブル

正常に表示されるブログカードには5つほど要素があります。

テネーブル(アイコン01)
ブログカード説明

ブログカードを記事で使う方法

下記のSnow Monkey公式サイトのマニュアルページを参考にしてみてください。

テネーブル

ブロックエディターの場合は「埋め込み」カテゴリーの「埋め込み」ブロックでURLを埋め込むと、ブログカードに変換されます。エディター内では表示がおかしくなる場合もありますが、実際の記事画面では正しくブログカードに変換されていると思います。

テネーブル(アイコン03)
ルミェール

段落ブロックでもURLだけ書けば、通常は埋め込まれるよ!ただ、ブロックエディターのバージョンによっては正しく動作しない場合があるんだ…。埋め込みできちんと変換するのがオススメかも!

ルミェール(アイコン05)

Snow Monkeyのカード表示について

WordPressの標準機能のままでは、リンク先URLが外部の場合は正しくブログカードになりません。その為、Snow MonkeyテーマではWP oEmbed Blog Cardと言うライブラリを使用され、外部のリンク先URLでもoEmbedプロトコルに準拠している場合はカード表示に変換されるようになっています。

テネーブル

WP oEmbed Blog Cardライブラリの制作者も、Snow Monkey制作者のキタジマ タカシ氏です。

テネーブル(アイコン01)
ルミェール

WP oEmbed Blog Cardライブラリで表示しているブログカード部分はテンプレートの置換などではカスタマイズ出来ないみたい。このライブラリの仕様に合わせてカスタマイズしよう!

ルミェール(アイコン01)

カード表示のパターンについて理解しよう

カード表示は3パターン

Snow Monkeyのブログカード(WP oEmbed Blog Card)では、下記の3つのパターンがあります。

  • 取得前、取得時(リンク先URLのoEmbedを取得する前、取得中)
  • 取得失敗時(通常リンク表示)
  • 取得成功時(ブログカード表示)

3パターンの表示HTMLについて

取得前、取得時

ロード中の場合、ブログカード中のURLは下記のHTMLに変換されます。

<div class="js-wp-oembed-blog-card">
	<a class="js-wp-oembed-blog-card__link" href="リンク先URL" target="_selfまたは_blank">リンク先URL</a>
</div>

target要素は、リンク先URLが同一のサイトであれば_self、それ以外は_blankとなります。

テネーブル

このようなHTML記述をカスタムHTMLブロック等で記述した場合でも自然にブログカードに変換されます。
後述のPHPでのブログカード処理が難しい場合は、こちらの記述を埋め込むのも手でしょう。

テネーブル(アイコン01)

取得失敗時

取得失敗時には、通常のリンクとして下記のようなHTMLに変換されます。

<p class="wp-oembed-blog-card-url-template">
	<a href="リンク先URL" target="_blank">リンク先URL</a>
</p>

target要素は_blank固定です。

取得成功時

取得成功時には、ブログカードとして下記のようなHTMLに変換されます。

<div class="wp-oembed-blog-card" data-cached-time="キャッシュ時間">
	<a href="リンク先URL" target="_selfまたは_blank">
		<div class="wp-oembed-blog-card__figure">
			<img src="サムネイル画像URL" alt="">
		</div>
		<div class="wp-oembed-blog-card__body">
			<div class="wp-oembed-blog-card__title">
				リンク先の記事タイトル
			</div>
			<div class="wp-oembed-blog-card__description">
				リンク先の説明文字列(160文字で…省略)
			</div>
			<div class="wp-oembed-blog-card__domain">
				<img class="wp-oembed-blog-card__favicon" src="リンク先のファビコンのURL" alt="">
				リンク先のドメイン
			</div>
		</div>
	</a>
</div>

target要素は、リンク先URLが同一のサイトであれば_self、それ以外は_blankとなります。
サムネイル画像が存在しない場合はwp-oembed-blog-card__figureクラスのdivタグは出力されません。
ファビコンが存在しない場合はwp-oembed-blog-card__faviconクラスのimgタグは出力されません。

ブログカード表示をカスタマイズしてみよう

テンプレート置換ではない表示カスタマイズ

ルミェール

テンプレート置換でカスタマイズする場合、対象のテンプレートに対するフックを使用して書き換えるんだけど、ブログカードは何処にでも貼る事が出来るんだ。
テンプレート置換をしようとしても凄く大変になるよね。

ルミェール(アイコン01)
テネーブル

表示パターンも3つありますからね…。
ブログカードの表示カスタマイズは、ライブラリで用意されているフックを使用してカスタマイズが可能です!

テネーブル(アイコン04)

取得前、取得時の表示をカスタマイズする為には

wp_oembed_blog_card_loading_templateと言うフックが用意されています。
渡される引数はHTMLとURLとなり、返却値にはHTMLを渡します。

標準のブログ表示HTMLであれば、下記のような形になります。

add_filter(
	'wp_oembed_blog_card_loading_template',
	function( $html, $url ) {
		if ( 0 === strpos( $url, home_url() ) ) {
			$target = '_self';
		} else {
			$target = '_blank';
		}
		return sprintf(
			'<div class="js-wp-oembed-blog-card"><a class="js-wp-oembed-blog-card__link" href="%1$s" target="%2$s">%1$s</a></div>',
			esc_url( $url ),
			esc_attr( $target )
		);
	},
	100,
	2
);

このコードをベースにカスタマイズをすると良いでしょう。

テネーブル

しかし、js-wp-oembed-blog-cardなどのclass部分は変更してはいけないようです。
oEmbed情報が正しく取得された状態に、ブログカード表示に正常に切り替わらなくなってしまう場合があります。
カスタマイズする場合は、class名を追加する等のカスタマイズに留めておく必要があるでしょう。

テネーブル(アイコン05)

取得失敗時の表示をカスタマイズする為には

wp_oembed_blog_card_url_templateと言うフックが用意されています。
渡される引数はHTMLとURLとなり、返却値にはHTMLを渡します。

標準のブログ表示HTMLであれば、下記のような形になります。

add_filter(
	'wp_oembed_blog_card_url_template',
	function( $html, $url ) {
		return sprintf(
			'<p class="wp-oembed-blog-card-url-template"><a href="%1$s" target="_blank">%1$s</a></p>',
			esc_url( $url )
		);
	},
	100,
	2
);

このコードをベースにカスタマイズをすると良いでしょう。

ルミェール

wp-oembed-blog-card-url-templateclass部分は変更しない方が良いみたい。

ルミェール(アイコン01)

取得成功時の表示をカスタマイズする為には

wp_oembed_blog_card_blog_card_templateと言うフックが用意されています。
渡される引数はHTMLと取得されたEmbed情報配列となり、返却値にはHTMLを渡します。

標準のブログ表示HTMLであれば、下記のような形になります。

add_filter(
	'wp_oembed_blog_card_blog_card_template',
	function( $html, $cache ) {
		if ( 0 === strpos( $url, home_url() ) ) {
			$target = '_self';
		} else {
			$target = '_blank';
		}
		$cached_time = isset( $cache['cached_time'] ) ? date_i18n( 'd/m/y H:i:s', $cache['cached_time'] ) : null;
		ob_start();
?>
		<div class="wp-oembed-blog-card" data-cached-time="<?php echo esc_attr( $cached_time ); ?>">
			<a href="<?php echo esc_url( $url ); ?>" target="<?php echo esc_attr( $target ); ?>">
				<?php if ( $cache['thumbnail'] ) : ?>
					<div class="wp-oembed-blog-card__figure">
						<img src="<?php echo esc_url( $cache['thumbnail'] ); ?>" alt="">
					</div>
				<?php endif; ?>
				<div class="wp-oembed-blog-card__body">
					<div class="wp-oembed-blog-card__title">
						<?php echo esc_html( $cache['title'] ); ?>
					</div>
					<div class="wp-oembed-blog-card__description">
						<?php
						if ( function_exists( 'mb_strimwidth' ) ) {
							echo esc_html( mb_strimwidth( $cache['description'], 0, 160, '…', 'utf-8' ) );
						} else {
							echo esc_html( $cache['description'] );
						}
						?>
					</div>
					<div class="wp-oembed-blog-card__domain">
						<?php if ( $cache['favicon'] ) : ?>
							<img class="wp-oembed-blog-card__favicon" src="<?php echo esc_url( $cache['favicon'] ); ?>" alt="">
						<?php endif; ?>
						<?php echo esc_html( $cache['domain'] ); ?>
					</div>
				</div>
			</a>
		</div>
<?php
		return ob_get_clean();
	},
	100,
	2
);

このコードをベースにカスタマイズをすると良いでしょう。

ルミェール

$cache配列の要素は、下記の通りだよ!

ルミェール(アイコン01)
説明
titleタイトル
thumbnailサムネイル画像URL
description説明、抜粋
faviconファビコン画像URL
domainドメイン

wp-oembed-blog-cardクラスが付与される

Snow Monkeyのテーマでは前述のフックを利用し、classの文字置換が行われています。

class="js-wp-oembed-blog-card"は、class="js-wp-oembed-blog-card wp-oembed-blog-card"に置換されます。

class="wp-oembed-blog-card-url-template"は、class="wp-oembed-blog-card-url-template wp-oembed-blog-card"に置換されます。

その理由から前述したフック例は優先度を100とし、classの置換処理より前に処理を行うように設定しています。

ルミェール

Snow Monkeyでスタイルを設定する場合は、wp-oembed-blog-cardと言うclassも付与されると言うのも考慮しよう!

ルミェール(アイコン01)

記事以外にブログカードを直接使用する方法

ルミェール

例えば404ページに、ページが見つからない代わりにブログカードを使ってオススメ記事を表示するとかの場合。

PHPで直接ブログカードを呼び出す方法もあるんだ。

ルミェール(アイコン01)

PHPで使用する場合は、下記のように記述を行います。

use Inc2734\WP_OEmbed_Blog_Card;

$_url = 'ブログカード表示を行いたいリンク先URL';
$_blog_card_html = '<a href=' . $_url . '>' . $_url . '</a>';
$_blog_card = new WP_OEmbed_Blog_Card\Bootstrap();
if ( method_exists( $_blog_card, '_embed_html_for_no_oembed' ) ) {
	$_blog_card_html = $_blog_card->_embed_html_for_no_oembed( null, $_url );
}
echo $_blog_card_html;
ルミェール

WP OEmbed Blog Cardを使用する為に名前空間のInc2734\WP_OEmbed_Blog_Cardを使用するように設定するんだ。
WP_OEmbed_Blog_Card\Bootstrap()はブログカードのクラスだよ。
_embed_html_for_no_oembedは、第一引数が出力、第二引数がリンク先URLになるんだ。第一引数は基本的にnullでも問題ないよ!
実行した場合、取得成功時または取得失敗時のHTMLが返却されるんだ。実行されていない場合に備えて返却される変数にはaタグで初期化しておくと良いかも。

ルミェール(アイコン01)
テネーブル

_embed_html_for_no_oembedは、以前は_wp_embed_handlerと言うメソッドが使用されていましたが、現在のバージョンには存在しなくなりました。

テネーブル(アイコン05)
ルミェール

第一回Snow Monkeyミートアップで作者のキタジマさんから「ソースコードを整理してると、メソッド名が変わるのはライブラリでは度々あるので、メソッド存在チェック(method_exists)は書いておいた方が良いです」との事!

現在はメソッド名の変更も無くなってきているけど、メソッドの存在チェックは、可能な限り行う事を推奨されてるみたい。

ルミェール(アイコン05)
テネーブル

WordPressのEmbed機能の仕様変更に合わせてライブラリの仕様も変更される可能性もありますので、ブログカードに関しましてはメソッド存在チェックなどは行う方が良いですね。

テネーブル(アイコン03)

ライブラリが格納されているディレクトリについて

テネーブル

ここまで解説しているWP oEmbed Blog Cardライブラリは、Snow Monkeyテーマの何処に格納されているのかを見てみましょう。

テネーブル(アイコン01)

Snow Monkeyテーマでは、

テーマディレクトリ

vendor

inc2734

wp-oembed-blog-card

のディレクトリにWP oEmbed Blog Cardライブラリが格納されています。

assetsディレクトリには、ブログカードに使用されるスクリプトやスタイルシートが格納されています。ブログカードの動作や表示スタイルを変更する場合には、このディレクトリ内のリソースを参考にすると良いでしょう。

テネーブル

PHPに理解のある方であれば、このディレクトリを参照すればブログカードの仕組みを理解できると思います。しかし、テーマの標準動作に影響を及ぼす場合もある為、良く解らない場合はvendorディレクトリ内の下位リソースは上書きしないようにしましょう。

テネーブル(アイコン01)

第5回の記事を振り返って

記事アンケート(第5回の記事を振り返って)

第5回の記事はどうでしたか?

回答いただき、ありがとうございました!
回答結果は、次回の記事制作の参考にさせていただきます。