カテゴリー
WordPress

WordPress Twenty Twenty 子テーマ作成。カスタマイザーで設定されていなければテーマデフォルトのロゴを表示する

はじめに

タイトルのことを実現するためにやったことを、以下、ノートしてまいります♪

調査。twentytwenty_site_logo 関数にフックし、その時の引数を確認するためのコード

次のコードで、無事 twentytwenty_site_logo にフックできること、そして、引数を受け取り出力できることを確認しました。

function oki2a24comtwentytwentychild_site_logo( $html, $args, $classname, $contents ) {
    error_log('oki2a24comtwentytwentychild_site_logo!!!!!!!!!!!!!!!!!!');
    error_log('$html: ' . $html);
    error_log('$args: ' . print_r($args, true));
    error_log('$classname: ' . $classname);
    error_log('$contents: ' . $contents);
    error_log('has_custom_logo(): ' . has_custom_logo());
    return $html;
}
add_filter( 'twentytwenty_site_logo', 'oki2a24comtwentytwentychild_site_logo', 10, 4 );

以下、 2 つの状態のログです。

ロゴなしの状態のログ

wordpress_1  | [Thu Jan 23 22:04:15.839704 2020] [php7:notice] [pid 210] [client 172.18.0.1:59748] oki2a24comtwentytwentychild_site_logo!!!!!!!!!!!!!!!!!!, referer: http://localhost:8080/?page_id=2
wordpress_1  | [Thu Jan 23 22:04:15.839751 2020] [php7:notice] [pid 210] [client 172.18.0.1:59748] $html: <h1 class="site-title"><a href="http://localhost:8080/">sample</a></h1>, referer: http://localhost:8080/?page_id=2
wordpress_1  | [Thu Jan 23 22:04:15.839761 2020] [php7:notice] [pid 210] [client 172.18.0.1:59748] $args: Array\n(\n    [logo] => %1$s<span class="screen-reader-text">%2$s</span>\n    [logo_class] => site-logo\n    [title] => <a href="%1$s">%2$s</a>\n    [title_class] => site-title\n    [home_wrap] => <h1 class="%1$s">%2$s</h1>\n    [single_wrap] => <div class="%1$s faux-heading">%2$s</div>\n    [condition] => 1\n)\n, referer: http://localhost:8080/?page_id=2
wordpress_1  | [Thu Jan 23 22:04:15.839767 2020] [php7:notice] [pid 210] [client 172.18.0.1:59748] $classname: site-title, referer: http://localhost:8080/?page_id=2
wordpress_1  | [Thu Jan 23 22:04:15.839772 2020] [php7:notice] [pid 210] [client 172.18.0.1:59748] $contents: <a href="http://localhost:8080/">sample</a>, referer: http://localhost:8080/?page_id=2
wordpress_1  | 172.18.0.1 - - [23/Jan/2020:22:04:15 +0000] "GET / HTTP/1.1" 200 10308 "http://localhost:8080/?page_id=2" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
wordpress_1  | 172.18.0.1 - - [23/Jan/2020:22:04:16 +0000] "GET /wp-content/themes/oki2a24com-twentytwenty-child/assets/images/cropped-site_icon-32x32.jpg HTTP/1.1" 200 1455 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
wordpress_1  | [Thu Jan 23 22:27:53.719626 2020] [php7:notice] [pid 286] [client 172.18.0.1:59984] has_custom_logo(): , referer: http://localhost:8080/

ロゴありの状態のログ。(cropped-site_icon.jpg というファイルをアップロードし、ロゴに設定)

wordpress_1  | [Thu Jan 23 22:18:29.894657 2020] [php7:notice] [pid 286] [client 172.18.0.1:59920] oki2a24comtwentytwentychild_site_logo!!!!!!!!!!!!!!!!!!, referer: http://localhost:8080/
wordpress_1  | [Thu Jan 23 22:18:29.894704 2020] [php7:notice] [pid 286] [client 172.18.0.1:59920] $html: <div class="site-logo faux-heading"><a href="http://localhost:8080/" class="custom-logo-link" rel="home"><img width="512" height="384" src="http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon.jpg" class="custom-logo" alt="sample" srcset="http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon.jpg 512w, http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon-300x225.jpg 300w" sizes="(max-width: 512px) 100vw, 512px" /></a><span class="screen-reader-text">sample</span></div>, referer: http://localhost:8080/
wordpress_1  | [Thu Jan 23 22:18:29.894716 2020] [php7:notice] [pid 286] [client 172.18.0.1:59920] $args: Array\n(\n    [logo] => %1$s<span class="screen-reader-text">%2$s</span>\n    [logo_class] => site-logo\n    [title] => <a href="%1$s">%2$s</a>\n    [title_class] => site-title\n    [home_wrap] => <h1 class="%1$s">%2$s</h1>\n    [single_wrap] => <div class="%1$s faux-heading">%2$s</div>\n    [condition] => \n)\n, referer: http://localhost:8080/
wordpress_1  | [Thu Jan 23 22:18:29.894722 2020] [php7:notice] [pid 286] [client 172.18.0.1:59920] $classname: site-logo, referer: http://localhost:8080/
wordpress_1  | [Thu Jan 23 22:18:29.894726 2020] [php7:notice] [pid 286] [client 172.18.0.1:59920] $contents: <a href="http://localhost:8080/" class="custom-logo-link" rel="home"><img width="512" height="384" src="http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon.jpg" class="custom-logo" alt="sample" srcset="http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon.jpg 512w, http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon-300x225.jpg 300w" sizes="(max-width: 512px) 100vw, 512px" /></a><span class="screen-reader-text">sample</span>, referer: http://localhost:8080/
wordpress_1  | 172.18.0.1 - - [23/Jan/2020:22:18:29 +0000] "GET / HTTP/1.1" 200 13695 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
wordpress_1  | [Thu Jan 23 22:26:44.554334 2020] [php7:notice] [pid 199] [client 172.18.0.1:59928] has_custom_logo(): 1, referer: http://localhost:8080/

ログ出力と親テーマの関数 twentytwenty_site_logo からわかったこと。

結果、has_custom_logo()true ならロゴ設定済み、 false ならロゴ未設定、と判定できそうです。

https://github.com/WordPress/twentytwenty/blob/d97e6cea0079215bb86988a94ad114bf1fe722be/inc/template-tags.php#L58-L64 の次のコード、

	if ( has_custom_logo() ) {
		$contents  = sprintf( $args['logo'], $logo, esc_html( $site_title ) );
		$classname = $args['logo_class'];
	} else {
		$contents  = sprintf( $args['title'], esc_url( get_home_url( null, '/' ) ), esc_html( $site_title ) );
		$classname = $args['title_class'];
    }

を見ると、カスタマイザーでロゴを設定している場合は、その URL である $logo を取得してロゴとして出力するべく使用しています。 ということは、カスタマイザーでロゴ設定されていない場合に、この部分のコードを流用し、ただし、ロゴの URL のみテーマデフォルトのロゴのものに差し替えてやれば良さそうです。

では $logo はどのように作られているでしょうか?

https://github.com/WordPress/twentytwenty/blob/d97e6cea0079215bb86988a94ad114bf1fe722be/inc/template-tags.php#L33 に $logo = get_custom_logo(); とありました。

WordPress の get_custom_logo 関数ということなので、見てみましょう。さらにこれを利用できるかもしれません。

https://developer.wordpress.org/reference/functions/get_custom_logo/#source に get_custom_logo 関数のソースがあります。 画像、 <img> を出力するために、 wp_get_attachment_image 関数を使用しているそうです。 wp_get_attachment_image( $custom_logo_id, 'full', false, $custom_logo_attr ) というコードです。 <img> の出力は、これを使えばベタがきしないで済むかもしれません。と思ったのですが、これはアップロードした画像を取得する関数ですので、使えません。ベタがきするのが良さそうです。

それでは、 get_custom_logo 関数の出力する文字列を確認しましょう。先ほどのコードの $contents = sprintf( $args['logo'], $logo, esc_html( $site_title ) ); を手掛かりにログ出力の中から $logo 部分を見つけ出しました。次の部分です。

<a href="http://localhost:8080/" class="custom-logo-link" rel="home"><img width="512" height="384" src="http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon.jpg" class="custom-logo" alt="sample" srcset="http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon.jpg 512w, http://localhost:8080/wp-content/uploads/2020/01/cropped-cropped-site_icon-300x225.jpg 300w" sizes="(max-width: 512px) 100vw, 512px" /></a><

画像の縦横サイズを変えて、もう一つロゴを設定してみました。画像のサイズに合わせて width が変わるので、 Twenty Twenty の定めるロゴの縦横サイズがわかりません。もう少し調べる必要がありそうです。

カスタムロゴについての公式ページです。これを見ると、 add_theme_support( 'custom-logo', $defaults );$default の配列で width と height を設定し、これがロゴのサイズになるようです。

Twenty Twenty の次の部分に、ロゴのサイズについての記述がありました。

  • https://github.com/WordPress/twentytwenty/blob/9ac5ba33839cf2e5f87d9fe39c81ec5aca19493f/functions.php#L66-L84

retina_logo あたりの記述を見るに、最大 width: 240, height: 180 で良さそうです。あとは、このサイズの画像をアップロードし、その時に出力される HTML を真似て、デフォルトのロゴの HTML を作れば良さそうです。

次は、 width: 240, height: 180 の画像をアップロードしてロゴに設定した時の実際の HTML を探してみました。

<a href="http://localhost:8080/" class="custom-logo-link" rel="home"><img width="240" height="180" src="http://localhost:8080/wp-content/uploads/2020/01/240x180.jpeg" class="custom-logo" alt="sample" /></a>

これと同じ形になるように、 $logo を作ってやれば良さそうです。

コードを書く準備がようやくできました。書いていきましょう♪

完成したコード

これをもとに次のコードを書きました。

/**
 * デフォルトのサイトロゴを表示します。
 * カスタマイザーで設定された場合はそちらを使用します。
 *
 * @param string $html サイトロゴの HTML .
 * @param array  $args twentytwenty_site_logo 関数の引数となる配列 .
 * @return string $html 引数をもとにしたコンパイル済みの HTML .
 */
function oki2a24comtwentytwentychild_site_logo( $html, $args ) {
	if ( has_custom_logo() ) {
		return $html;
	}

	$logo      = sprintf(
		'<a href="%1$s" class="custom-logo-link" rel="home"><img width="240" height="180" src="%2$s" class="custom-logo" alt="sample" /></a>',
		esc_url( home_url( '/' ) ),
		esc_url( get_stylesheet_directory_uri() . '/assets/images/theme_logo.jpg' )
    );
    $site_title = get_bloginfo( 'name' );
	$contents  = sprintf( $args['logo'], $logo, esc_html( $site_title ) );
	$classname = $args['logo_class'];

	$wrap = $args['condition'] ? 'home_wrap' : 'single_wrap';

	$html = sprintf( $args[ $wrap ], $classname, $contents );
	return $html;
}
add_filter( 'twentytwenty_site_logo', 'oki2a24comtwentytwentychild_site_logo', 10, 2 );

完成コードの解説

カスタマイザーでロゴが設定済みであれば、元々のサイトロゴ HTML を返して終了します。

	if ( has_custom_logo() ) {
		return $html;
	}

本投稿の目的である、デフォルトロゴの HTML を作成します。 %1$s にサイトのホーム URL を エスケースしたものを、 %2$s の箇所にデフォルトロゴファイルの URL をエスケースしたものを <a> タグのテンプレートに当てはめた文字列の変数 $logo を作ります。

なお、この方法は、 get_custom_logo() | Function | WordPress Developer Resources を参考にしました。

次に、 get_bloginfo( 'name' ) でブログタイトルを取得し、 $site_title へ設定します。

	$logo      = sprintf(
		'<a href="%1$s" class="custom-logo-link" rel="home"><img width="240" height="180" src="%2$s" class="custom-logo" alt="sample" /></a>',
		esc_url( home_url( '/' ) ),
		esc_url( get_stylesheet_directory_uri() . '/assets/images/theme_logo.jpg' )
    );
    $site_title = get_bloginfo( 'name' );

これ以降は、親テーマの twentytwenty_site_logo 関数の twentytwenty/template-tags.php at d97e6cea0079215bb86988a94ad114bf1fe722be · WordPress/twentytwenty とほぼ同じことをしています。ログ出力の内容をみながら理解し、コードを組み立てていきました。

$contents を作ります。これはロゴ画像とブログタイトルテキストを合わせた HTML となります。先ほどの $logo$site_title をエスケープしたものを、次のテンプレートに当てはめます。

  • $args['logo']: ‘%1$s<span class="screen-reader-text">%2$s</span>’

$classname は次です。

  • $args['logo_class']: ‘site-logo’

$args['condition'] には truefalse かが入っており、それによって $wrap に ‘home_wrap’ または ‘single_wrap’ が設定されます。

ようやく $html を作ります。ロゴ画像とブログタイトルテキストを合わせた HTML を <div> で囲む、というのがその内容となります。今までで作ってきた $classname$contents を次のテンプレートのどちらかに当てはめます。

  • $args['home_wrap']: ‘<h1 class="%1$s">%2$s</h1>’
  • $args['single_wrap']: ‘<div class="%1$s faux-heading">%2$s</div>’
	$contents  = sprintf( $args['logo'], $logo, esc_html( $site_title ) );
	$classname = $args['logo_class'];

	$wrap = $args['condition'] ? 'home_wrap' : 'single_wrap';

	$html = sprintf( $args[ $wrap ], $classname, $contents );
	return $html;

おわりに

が去年の投稿です。この時は、ロゴ出力関数を定義して、ウェブサイトのヘッド部分を実際に出力するテンプレートでカスタマイザーのロゴがあるかどうかを判定してなければロゴ出力関数の結果を表示する、というアプローチでした。

今回は、全く異なるアプローチとなりました。たまたま親テーマにロゴ出力の関数があり、それにフックできる作りとなっていました。ですので親テーマのロゴ出力関数をフックしてカスタマイザーのロゴがなければ HTML を差し替える、というアプローチです。

同じロゴを出力したいだけですけれども、親テーマを作る考え方で、子テーマでデフォルトロゴを出力するやり方も複数取れる、ということを実感したのでした。

以上です。

コメントを残す