【WordPress】画像のカスタムフィールドをカテゴリ、タグ、カスタムタクソノミーで実装する方法【プラグインなし】

この記事は最終更新から3年以上が経過しています。情報が古くなっている可能性があります。

こんにちは、しばです。
最近WordPressで、カテゴリやタグ・カスタム分類に画像のカスタムフィールドを実装したいなぁと思い、色々調べる機会がありました。

情報は落ちてるは落ちてるんですが、どれもプラグインを使った方法ばかり(´・ω・`)

サイト全体でカスタムフィールドをバンバン使うならまだしも、その箇所しか使わない予定だったので、無闇にプラグインを増やしたくないなぁと思いプラグインを使わない実装方法を調べてみました。

  • functions.php
  • 出力したいテンプレート

この2箇所にコードを書くだけで対応できる方法をまとめたので、同じように困ってる方の参考になれば幸いです!

実装イメージ

まず、どういう時にこの「カテゴリやタグ、カスタム分類に画像のカスタムフィールドを実装」が必要になるかという例をあげてみます。

アーカイブ(一覧)ページの画像(又は背景)を、タームごとに変えたいという場合。
具体的には、以下のようにしたい時です。
※ タームはカテゴリ名やタグ名と呼ばれるそのタクソノミーに所属する項目の名称です。最初カテゴリだと未分類があるんですが、それがターム。

  • カテゴリ「猫」のアーカイブページ→トップビジュアルを猫の写真に変更
  • カテゴリ「犬」のアーカイブページ→トップビジュアルを犬の写真に変更
  • カテゴリ「鳥」のアーカイブページ→トップビジュアルを鳥の写真に変更

タームが固定でこれ以上カテゴリが増えないのなら、テンプレートで画像URL指定にしても問題ないと思います。
でもタームが増減したり、写真の差し替えを簡単に行いたい時ってありますよね。

そういう時、WordPress上でタームごとに画像のカスタムフィールド を用意し、そこに画像をアップロードしたら自動的に反映されたら簡単!
これをプラグインなしに実装するのが今回の目標です。

これを実現するにはいくつかのアクションフックを使って下記の処理を仕込んでおく必要があります。

  • カテゴリ、タグ、カスタムタクソノミー画面で画像のカスタムフィールドを表示する処理(新規登録時/上書き時)
  • カテゴリ、タグ、カスタムタクソノミー画面で登録した画像を保存する処理(新規登録時/上書き時)
  • メディアアップローダー起動のためのスクリプト

アクションフックがどれがいいのか…メディアアップロードの処理はどう書けばいいのか…と悩んでたら、英語でまるっと紹介されてる記事があったので、そちらからコードをお借りしました。

そこに書いてあるものをそのままプラグインとして読み込ませてもいいんですが、今回はテーマに含めることを想定して、functions.php、アーカイブページへの書き方を記載してみます。

functions.phpへの記述

長いので別ページに内容を掲載します。別窓に開きつつご覧ください。

functions.phpのコード (別窓)

引用元)Adding an image upload field to categories and taxonomies

こちらのコードでは、カテゴリ、タグ、カスタムタクソノミー(タクソノミースラッグ名○○○)で、同じように画像のカスタムフィールドを登録できるようになっています。

カテゴリ、タグ、カスタムタクソノミーの内どれかを使いたかったら、下記の部分でそれぞれ処理を呼び出しているので、必要なものだけ残したり、書き換えて使ってください。

 public function init() {
    //カテゴリ
   add_action( 'category_add_form_fields', array ( $this, 'add_category_image' ), 10, 2 );
   add_action( 'created_category', array ( $this, 'save_category_image' ), 10, 2 );
   add_action( 'category_edit_form_fields', array ( $this, 'update_category_image' ), 10, 2 );
   add_action( 'edited_category', array ( $this, 'updated_category_image' ), 10, 2 );

    //カスタムタクソノミー(○○○はタクソノミーのスラッグ名を入力)
   add_action( '○○○_add_form_fields', array ( $this, 'add_category_image' ), 10, 2 );
   add_action( 'create_term', array ( $this, 'save_category_image' ), 10, 2 );
   add_action( '○○○_edit_form_fields', array ( $this, 'update_category_image' ), 10, 2 );
   add_action( 'edit_terms', array ( $this, 'updated_category_image' ), 10, 2 );

    //タグ
   add_action( 'post_tag_add_form_fields', array ( $this, 'add_category_image' ), 10, 2 );
   add_action( 'created_post_tag', array ( $this, 'save_category_image' ), 10, 2 );
   add_action( 'post_tag_edit_form_fields', array ( $this, 'update_category_image' ), 10, 2 );
   add_action( 'edited_post_tag', array ( $this, 'updated_category_image' ), 10, 2 );

   add_action( 'admin_enqueue_scripts', array( $this, 'load_media' ) );
   add_action( 'admin_footer', array ( $this, 'add_script' ) );
 }

ここでは「〜_add_form_fields」「created_〜」「〜_edit_form_fields」「edited_〜」の1セットで記載します。
これらのアクションフックの詳細は下記の通り。

○○○_add_form_fields 管理画面で○○○追加フォームが作成される際に実行する。
○○○_edit_form_fields 管理画面で○○○編集フォームが作成される際に実行する。
created_○○○ ○○○が新規作成された際に実行する。
edited_○○○ ○○○が編集された際に実行する。

修正したコードをfunctions.phpの末尾にペーストして保存すると、WordPress側のカテゴリ画面などでは画像フィールドがちゃんと表示されるようになります。

テンプレートでの出力

次に登録した画像を出力したいテンプレートに出力コードを書いていきます。

今回はWordPressの標準テーマ「twentyseventeen」のアーカイブページのトップビジュアルを登録したものに差し替えたいと思います。

このテーマでは、トップビジュアルの画像出力部分が全ページ共通テンプレートのtemplate-parts/header/header-image.php にあり、以下のようなコードになっています。

<div class="custom-header">

		<div class="custom-header-media">
			<?php the_custom_header_markup(); ?>
		</div>

	<?php get_template_part( 'template-parts/header/site', 'branding' ); ?>

</div><!-- .custom-header -->

上記コードの<?php the_custom_header_markup(); ?> はテーマで定義された関数で、出力コードはこちら。

<div id="wp-custom-header" class="wp-custom-header"><img src="http://test.local/wp-content/themes/twentyseventeen/assets/images/header.jpg" width="2000" height="1200" alt="test"></div>

これを利用しつつ、アーカイブページの場合は登録した画像を参照するように書き換えると、次のような感じになります。

<div class="custom-header">

		<div class="custom-header-media">
			<?php if(is_archive()):
				$term_img = get_term_meta(get_queried_object_id(),'category-image-id',true);
				if($term_img){
					$imgurl = wp_get_attachment_image_src($term_img,'full');
					echo '<div id="wp-custom-header" class="wp-custom-header">';
					echo '<img src="'.$imgurl[0].'">';
					echo '</div>';
				}else{
					the_custom_header_markup();	
				}
			else :
				the_custom_header_markup();
			endif;
			?>
		</div>

	<?php get_template_part( 'template-parts/header/site', 'branding' ); ?>

</div><!-- .custom-header -->

別のテーマで使う場合は、前のコードとの差分をとって追記してみてください。

WordPress管理画面から画像を登録

出力の準備も整ったので、あとは画像を登録するだけ!

先ほどの例のように、猫カテゴリに猫画像、犬カテゴリに猫画像を登録してみます。

そうすると…


猫カテゴリのアーカイブページ


犬カテゴリのアーカイブページ

うまく表示されました!

ちなみに今回のコードだと、TOPや鳥カテゴリ(画像カスタムフィールド 未登録)はちゃんとデフォルトの画像が表示されます。

感想

最初は思ったより情報が落ちてなくて「ニーズないのかな〜?」と疑問だったんですが、調べてみると画像のカスタムフィールド はテキスト型のカスタムフィールドを実装するより記述する処理が多い!

簡単なカスタムフィールドは自力orそれ以上カスタムフィールド使いたいならプラグイン、という傾向(だと感じてる)なのも納得だなぁと思いました。

それにしても、こういうマイナーなアクションフックは日本語の情報が少ないですね…。実現してるプラグインがあるからには実装できるんだろうなとは思いつつ、検索してもなかなか見つからなかったので、紹介されてる英語サイトを見つけられて本当に助かりました。

ちゃんと英語で記事を探す癖をつけていこう( `・ω・´)(

以上、画像のカスタムフィールドをカテゴリ、タグ、カスタムタクソノミーで実装する方法でした!