カスタム投稿、タクソノミーの追加方法の例 – 連想配列

ワードプレス

サイトごとに必要なカスタム投稿タイプを設定するのが面倒くさいなぁ、と常々思っていました。

  • 投稿タイプ、タクソノミーのスラッグ/ラベルの登録
  • 投稿タイプごとのヘッダー画像/ヘッダー背景カラーを設定

等々。

 

作業としては、複製して一部書き換えの単純作業なのですが、それでもやっぱり面倒くさい。

ので、配列に書いておいて、諸々を自動で変更してくれる感じにしたい!と。

追加するカスタム投稿タイプの宣言

if ( !function_exists( 'add_post_types' ) ){
	function add_post_types(){
		global $custom_post_types;
		$custom_post_types = [
			'news'				=> 'ニュース',
//			'information'		=> 'お知らせ',
//			'faq'				=> 'よくある質問',
			'q_and_a'			=> 'よくある質問',
//			'seminar'			=> 'セミナー',
			'event'				=> 'イベント',
//			'movie'				=> '動画',
//			'product'			=> '製品',
//			'example'			=> '製作事例',
			'document'			=> '資料',
//			'interview'			=> 'インタビュー',
//			'staff'				=> 'スタッフ',
//			'facility'			=> '施設情報',
//			'job_description'	=> '職種情報',
			'job_information'	=> '求人情報',
//			'log'				=> 'ログ',
			'memo' => 'メモ書き'
		];
	}
	add_action( 'after_setup_theme', 'add_post_types' );
}

よく使う投稿タイプを列挙しておいて、要らないものはコメントアウト、必要なら書き足し。

追加ループ文

add_action( 'init', 'create_post_type' );
function create_post_type() {

	global $custom_post_types;
	foreach( $custom_post_types as $post_type_name => $post_type_label ){
		$tax1_name = $post_type_name . '_tax1';
		$tax1_label = $post_type_label . '分類1';
		$tax2_name = $post_type_name . '_tax2';
		$tax2_label = $post_type_label . '分類2';
		register_post_type( $post_type_name, array(
			'labels' => array(
				'name' => __( $post_type_label ),
				'singular_name' => __( $post_type_label )
			),
			'description' => '',
			'public' => true,
			'has_archive' => true,
			'show_in_rest' => true,
			'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields' ,'comments' )
		));
		register_taxonomy(
			$tax1_name,
			$post_type_name,
			array(
				'show_in_rest' => true,
				'hierarchical' => true,
				'update_count_callback' => '_update_post_term_count',
				'label' => $tax1_label,
				'singular_label' => $tax1_label,
				'public' => true,
				'show_ui' => true,
				'show_admin_column' => true
			)
		);
		register_taxonomy(
			$tax2_name,
			$post_type_name,
			array(
				'show_in_rest' => true,
				'hierarchical' => true,
				'update_count_callback' => '_update_post_term_count',
				'label' => $tax2_label,
				'singular_label' => $tax2_label,
				'public' => true,
				'show_ui' => true,
				'show_admin_column' => true
			)
		);
	};

}

投稿タイプごとにタクソノミー名、ラベルを変えたりすると複雑になり過ぎて

  • コピペを繰り返す
  • いっそプラグインを使う

ほうがマシ、になっちゃうので「投稿タイプ名_tax1/投稿タイプラベル分類1」「投稿タイプ名_tax2/投稿タイプラベル分類2」で決め打ち。

 

クライアントには「_cat/カテゴリー」「_tag/タグ」あたりの命名の方が分かりやすいと思います。

が、非常に齟齬が発生しやすいので敢えて標準投稿の「カテゴリー/タグ」とは明らかに違う感じにしています。

 

  • 他サイトから投稿データをインポートする際
  • 求人情報とかで、分類が多数必要な場合

等、パターンから外れる場合は、ループ外に手動で追加する必要があります。

例外対応

投稿タイプによってタクソノミー名、ラベルだけ変えるなら、こんな感じの条件分岐だけで対応できます。

if( $post_type_name === 'memo' ){
	$tax1_name = $post_type_name . '_cat';
	$tax1_label = $post_type_label . 'カテゴリー';
	$tax2_name = $post_type_name . '_tag';
	$tax2_label = $post_type_label . 'タグ';
}else{
	$tax1_name = $post_type_name . '_tax1';
	$tax1_label = $post_type_label . '分類1';
	$tax2_name = $post_type_name . '_tax2';
	$tax2_label = $post_type_label . '分類2';
}

このサイトそのものなのですが、「メモ書き投稿・メモ書きカテゴリー・メモ書きタグ」が既に存在していて、パーマリンクが変わるのも嫌なので、このように特例措置をとっています。

分類数も変わるなら、条件分岐の中に「register_taxonomy()」も書き込みます。

 

既存サイトへの適用や、投稿データのインポートが必要な場合は、この辺の処理を慎重に。

呼び出し

折角なら、各所での呼び出しも自動化したい。

 

登録で利用した配列を使って呼び出してもいいんだけど、配列のパターン外で登録したものは呼び出せない。

global $custom_post_types;
foreach( $custom_post_types as $post_type_name => $post_type_label ){
	//処理
}

 

ので、再検索して呼び出したほうが後の手間が掛からない。

$post_types = get_post_types( ['public' => true, '_builtin' => false], 'names', 'and' );
foreach( $post_types as $post_type_name ){
	//処理
}

※ラベルが必要なら、「get_post_type_object( $post_type_name )->label」で取得できる。

例 – 管理画面メニューの並び順指定

function custom_menu_order( $menu_ord ) {
	if( !$menu_ord ) return true;
	$add_menu[] = 'index.php';
	$add_menu[] = 'edit.php?post_type=page'; //固定ページ
	$add_menu[] = 'edit.php'; //投稿
	$post_types = get_post_types( ['public' => true, '_builtin' => false], 'names', 'and' );
	foreach( $post_types as $post_type_name ){
		$add_menu[] = 'edit.php?post_type=' . $post_type_name;
	}
	$add_menu[] = 'upload.php'; //メディア
	$add_menu[] = 'separator1';
	$add_menu[] = 'site_settings'; //サイト設定
	$add_menu[] = 'option_settings'; //求人情報設定
	$add_menu[] = 'options-general.php'; //設定
	$add_menu[] = 'common_settings.php';
	$add_menu[] = 'themes.php'; //テーマ
	$add_menu[] = 'separator2';
	$add_menu[] = 'users.php'; //ユーザー
	$add_menu[] = 'separator3';
	$add_menu[] = 'tools.php'; //ツール
	$add_menu[] = 'plugins.php'; //プラグイン
	return $add_menu;
}
add_filter( 'custom_menu_order', 'custom_menu_order' );
add_filter( 'menu_order', 'custom_menu_order' );

例 – テーマカスタマイザーへの登録

/* ---------- 追加ヘッダー ---------- */
add_action( 'customize_register', 'theme_customize' );
function theme_customize( $wp_customize ){
	$wp_customize->add_section( 'img_section', array(
		'title' => 'タイプ別ヘッダー設定',
		'priority' => 69,
		'description' => '固定ページ、投稿タイプ等のヘッダー設定です。',
	));
	/* ---------- ヘッダー種類定義 ---------- */
	$customizer_items = ['default' => 'デフォルト'];
	$customizer_items += ['page' => '固定ページ'];
	$customizer_items += ['author' => '著者別アーカイブ'];
	$customizer_items += ['home' => '標準投稿トップ'];
	$customizer_items += ['post' => '標準投稿'];
	$post_types = get_post_types( ['public' => true, '_builtin' => false], 'names', 'and' );
	foreach( $post_types as $post_type_name ){
		$post_type_label = get_post_type_object( $post_type_name )->label . '投稿';
		$customizer_items += [$post_type_name => $post_type_label];
	}
	$customizer_items += ['cpt' 	=> 'カスタム投稿デフォルト'];
	$customizer_items += ['other' => 'その他のページ'];
	/* ---------- カスタマイザー定義 ---------- */
	foreach( $customizer_items as $customizer_name => $customizer_label ){
		$header_image = $customizer_name . '_header_image';
		$header_image_label = $customizer_label . 'ヘッダー画像';
		$header_color = $customizer_name . '_header_color';
		$header_color_label = $customizer_label . 'ヘッダーカラー';
		$wp_customize->add_setting( $header_image );
		$wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, $header_image, array(
			'label' => $header_image_label,
			'section' => 'img_section',
			'settings' => $header_image
		)));
		$wp_customize->add_setting( $header_color );
		$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, $header_color, array(
			'label' => $header_color_label,
			'section' => 'img_section',
			'settings' => $header_color
		)));
	}
}
/* ---------- 追加ヘッダーの画像URL・カラーの呼び出し関数 ---------- */
function get_custom_header_image( $header_image ){
	return esc_url( get_theme_mod( $header_image ) );
}
function get_custom_header_color( $header_color ){
	return esc_url( get_theme_mod( $header_color ) );
}

外観 ⇒ カスタマイズに、表示シーン別のヘッダー画像、背景色のUIを追加して、任意の場所で呼び出す、という内容です。

CSSだけでも同じことが出来ますが、エンドユーザーでも勝手にいじれるように。

「description」を追加しようとすると連想配列じゃ間に合わないのでオミット。

例 – カスタマイザーへの登録内容を呼び出す

if( function_exists( 'get_header_image' ) && function_exists( 'get_custom_header_image' ) && function_exists( 'get_custom_header_color' ) ){
	if( get_header_image() ){
		$banner_status = 'true';
		$banner_image = 'background-image: url(' . get_header_image() . ' );';
	}
	if( get_custom_header_color( 'default_header_color' ) ){
		$banner_status = 'true';
		$banner_color = 'background-color: ' . get_custom_header_color( 'default_header_color' ) . ';';
	}
	if( is_page() ){
		if( get_custom_header_image( 'page_header_image' ) ){
			$banner_status = 'true';
			$banner_image = 'background-image: url(' . get_custom_header_image( 'page_header_image' ) . ');';
		}
		if( get_custom_header_color( 'page_header_color' ) ){
			$banner_status = 'true';
			$banner_color = 'background-color: ' . get_custom_header_color( 'page_header_color' ) . ';';
		}
	}elseif( is_author() ){
		if( get_custom_header_image( 'author_header_image' ) ){
			$banner_status = 'true';
			$banner_image = 'background-image: url(' . get_custom_header_image( 'author_header_image' ) . ');';
		}
		if( get_custom_header_color( 'author_header_color' ) ){
			$banner_status = 'true';
			$banner_color = 'background-color: ' . get_custom_header_color( 'author_header_color' ) . ';';
		}
	}elseif( get_post_type() === 'post' ){
		if( get_custom_header_image( 'post_header_image' ) ){
			$banner_status = 'true';
			$banner_image = 'background-image: url(' . get_custom_header_image( 'post_header_image' ) . ');';
		}
		if( get_custom_header_color( 'post_header_color' ) ){
			$banner_status = 'true';
			$banner_color = 'background-color: ' . get_custom_header_color( 'post_header_color' ) . ';';
		}
		if( is_home() ){
			if( get_custom_header_image( 'home_header_image' ) ){
				$banner_status = 'true';
				$banner_image = 'background-image: url(' . get_custom_header_image( 'home_header_image' ) . ');';
			}
			if( get_custom_header_color( 'home_header_color' ) ){
				$banner_status = 'true';
				$banner_color = 'background-color: ' . get_custom_header_color( 'home_header_color' ) . ';';
			}
		}
	}elseif( get_post_type() ){
		if( get_custom_header_image( 'cpt_header_image' ) ){
			$banner_status = 'true';
			$banner_image = 'background-image: url(' . get_custom_header_image( 'cpt_header_image' ) . ');';
		}
		if( get_custom_header_color( 'cpt_header_color' ) ){
			$banner_status = 'true';
			$banner_color = 'background-color: ' . get_custom_header_color( 'cpt_header_color' ) . ';';
		}
		$post_types = get_post_types( ['public' => true, '_builtin' => false], 'names', 'and' );
		foreach( $post_types as $post_type_name ){
			if( get_post_type() === $post_type_name ){
				$header_image = $post_type_name . '_header_image';
				$header_color = $post_type_name . '_header_color';
				if( get_custom_header_image( $header_image ) ){
					$banner_status = 'true';
					$banner_image = 'background-image: url(' . get_custom_header_image( $header_image ) . ');';
				}
				if( get_custom_header_color( $header_color ) ){
					$banner_status = 'true';
					$banner_color = 'background-color: ' . get_custom_header_color( $header_color ) . ';';
				}
			}
		}
	}else{
		if( get_custom_header_image( 'other_header_image' ) ){
			$banner_status = 'true';
			$banner_image = 'background-image: url(' . get_custom_header_image( 'other_header_image' ) . ');';
		}
		if( get_custom_header_color( 'other_header_color' ) ){
			$banner_status = 'true';
			$banner_color = 'background-color: ' . get_custom_header_color( 'other_header_color' ) . ';';
		}
	}
}

優先順位とか考えると結構複雑に。

エンドユーザが変更することを考慮しないなら、ほんとCSSだけの方が楽です。