TECHBLOG

WordPress > サイト毎の設定

WordPressカスタムタクソノミーの設定

Create:

Update:

Category:WordPressサイト毎の設定

Series:WordPressサイト毎の設定

[ Version.19 ]

概要

カスタムタクソノミーの設定。プラグインは使用しません。

functions.php には設定値のみ記載して functions_setup.php に記述しinclude。

functions.php

設定定数「CUSTOM_TAXONOMY」をfunctions.phpに記載します。

const CUSTOM_TAXONOMY = [
	'cat_xxx' => [
		'name' => 'カテゴリー(XXX)',
		'post_type' => 'xxx',
		'style' => 'radio',
		'tax_type' => 'taxonomy',
		'posts_per_page' => 10,
		'editor' => 'classic',
	],
];
include_once 'xxx/functions_setup.php';

先ず cat_xxxにカスタムタクソノミー taxonomy を記載します。

name

カスタムタクソノミー名

post_type

関連付ける投稿タイプを指定します。

style

下記から選択します。parent_no_ が接頭にあるものは、第1カテゴリを選択せず、第2カテゴリだけが選択できます。

※ gutenberg(ブロックエディター)では動作しません。*開発中

  • checkbox
  • radio
  • parent_no_child_checkbox
  • parent_no_child_radio

tax_type

下記から選択します。

  • taxonomy
  • tag
posts_per_page

wp_query で取得される標準のアーカイブ投稿数

editor

classic || gutenberg から選択。
ブロックエディターの時はカテゴリを表示するために必要です。

functions_setup.php

上記の設定定数を元にカスタムタクソノミーを追加します。

このファイルはバージョン管理され、各サイト共通で設置しています。

カスタムタクソノミー追加

add_action('init', function () {
	foreach (CUSTOM_TAXONOMY_FIXED as $taxonomy => $v) {
		$args = [
			'label' => $v['name'],
			'rewrite' => ['slug' => $taxonomy],
			'hierarchical' => $v['tax_type'] !== 'tag',
			'show_in_rest' => $v['editor'] === 'gutenberg',
		];
		if (isset($v['labels'])) {
			$args['labels'] = $v['labels'];
		}
		register_taxonomy($taxonomy, $v['post_type'], $args);
	}
});

アーカイブのリンク

プラグインを使用せず、ルーティングも管理しています。

add_filter('term_link', function ($termlink, $term, $taxonomy) {
	if (isset(CUSTOM_TAXONOMY[$taxonomy]['post_type'])) {
		$termlink = '/' . CUSTOM_TAXONOMY[$taxonomy]['post_type'] . '/' . $taxonomy . '/' . $term->slug . '/';
	}
	return $termlink;
}, 10, 3);
	foreach (CUSTOM_TAXONOMY_FIXED as $taxonomy => $v) {
		add_rewrite_rule('^' . $v['post_type'] . '/' . $taxonomy . '/(.+?)/date/([0-9]{4})/?$', 'index.php?' . $taxonomy . '=$matches[1]&year=$matches[2]&post_type=' . $v['post_type'] . '', 'top');
		add_rewrite_rule('^' . $v['post_type'] . '/' . $taxonomy . '/(.+?)/date/([0-9]{4})/page/?([0-9]{1,})/?$', 'index.php?' . $taxonomy . '=$matches[1]&year=$matches[2]&paged=$matches[3]&post_type=' . $v['post_type'] . '', 'top');
		add_rewrite_rule('^' . $v['post_type'] . '/' . $taxonomy . '/(.+?)/date/([0-9]{4})/([0-9]{1,2})/?$', 'index.php?' . $taxonomy . '=$matches[1]&year=$matches[2]&monthnum=$matches[3]&post_type=' . $v['post_type'] . '', 'top');
		add_rewrite_rule('^' . $v['post_type'] . '/' . $taxonomy . '/(.+?)/date/([0-9]{4})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?' . $taxonomy . '=$matches[1]&year=$matches[2]&monthnum=$matches[3]&paged=$matches[4]&post_type=' . $v['post_type'] . '', 'top');
		add_rewrite_rule('^' . $v['post_type'] . '/' . $taxonomy . '/(.+?)/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$', 'index.php?' . $taxonomy . '=$matches[1]&year=$matches[2]&monthnum=$matches[3]&day=$matches[4]&post_type=' . $v['post_type'] . '', 'top');
		add_rewrite_rule('^' . $v['post_type'] . '/' . $taxonomy . '/(.+?)/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/?([0-9]{1,})/?$', 'index.php?' . $taxonomy . '=$matches[1]&year=$matches[2]&monthnum=$matches[3]&day=$matches[4]&paged=$matches[5]&post_type=' . $v['post_type'] . '', 'top');
		add_rewrite_rule('^' . $v['post_type'] . '/' . $taxonomy . '/(.+?)/page/?([0-9]{1,})/?$', 'index.php?' . $taxonomy . '=$matches[1]&paged=$matches[2]&post_type=' . $v['post_type'] . '', 'top');
		add_rewrite_rule('^' . $v['post_type'] . '/' . $taxonomy . '/(.+?)/?$', 'index.php?' . $taxonomy . '=$matches[1]&post_type=' . $v['post_type'] . '', 'top');
	}

foreach せずに(array_keys(CUSTOM_TAXONOMY))して、「|」でjoinした正規表現を使う方がスマートかもしれませんが、空の場合もあるためこれでよしとしています。

カテゴリ選択欄(ウィジェット)の設定と並べ替え禁止

参考にさせていただいたサイトがありましたが、記憶しておらず引用元を記載しておりません。
最初に記載された方には、敬意を表するとともにご査収いただければと思います。

※ Gutenberg(ブロックエディター)では動作しません。

if (is_admin()) {
	// class : Walker_Category_Checklist を上書き
	include_once ABSPATH . '/wp-admin/includes/template.php';
	class admin_category_adjust_checklist extends Walker_Category_Checklist
	{
		public function start_el(&$output, $category, $depth = 0, $args = [], $id = 0)
		{
			// 親カテゴリの時はチェックボックス非表示
			$target_taxonomy_parent_checkbox_hide = [];
			// チェックボックスをラジオボタンに変更
			$target_taxonomy_change_radio = [];
			foreach (CUSTOM_TAXONOMY_FIXED as $k => $v) {
				if ($v['style'] === 'parent_no_child_checkbox' || $v['style'] === 'parent_no_child_radio') {
					$target_taxonomy_parent_checkbox_hide[] = $k;
				}
				if ($v['style'] === 'radio' || $v['style'] === 'parent_no_child_radio') {
					$target_taxonomy_change_radio[] = $k;
				}
			}
			extract($args);
			$taxonomy = empty($taxonomy) ? 'category' : $taxonomy;
			$name = $taxonomy === 'category' ? 'post_category' : 'tax_input[' . $taxonomy . ']';
			$class = in_array($category->term_id, $popular_cats) ? ['popular-category'] : [];
			$class = $class ? ' class="' . join(' ', $class) . '"' : ''; // 該当タクソノミーで親カテゴリの時はチェックボックス表示しない
			if (in_array($taxonomy, $target_taxonomy_parent_checkbox_hide) && get_term_children($category->term_id, $taxonomy)) {
				$style = $category->parent === 0 ? 'style="font-weight:bold;"' : '';
				$output .= "\n" . '<li id=' . $taxonomy . '-' . $category->term_id . $class . '><label class="selectit"' . $style . '>' . esc_html(apply_filters('the_category', $category->name)) . '</label>';
			// 該当タクソノミーでラジオボタンに変更
			} elseif (in_array($taxonomy, $target_taxonomy_change_radio)) {
				$output .= "\n" . '<li id="' . $taxonomy . '-' . $category->term_id . '"' . $class . '><label class="selectit"><input value="' . $category->term_id . '" type="radio" name="' . $name . '[]" id="in-' . $taxonomy . '-' . $category->term_id . '"' . checked(in_array($category->term_id, $selected_cats), true, false) . disabled(empty($args['disabled']), false, false) . '> ' . esc_html(apply_filters('the_category', $category->name)) . '</label>';
			} else {
				$output .= "\n" . '<li id="' . $taxonomy . '-' . $category->term_id . '"' . $class . '><label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $name . '[]" id="in-' . $taxonomy . '-' . $category->term_id . '"' . checked(in_array($category->term_id, $selected_cats), true, false) . disabled(empty($args['disabled']), false, false) . '> ' . esc_html(apply_filters('the_category', $category->name)) . '</label>';
			}
		}
	}
	/* カテゴリの並べ替え停止 */
	add_action('wp_terms_checklist_args', function ($args, $post_id = null) {
		$args['checked_ontop'] = false;
		// 入力欄調整親カテゴリ非表示/ラジオボタンに変更
		$args['walker'] = new admin_category_adjust_checklist();
		return $args;
	});
}

投稿一覧でのタクソノミー絞り込み表

add_action('restrict_manage_posts', function () {
	global $post_type;
	$tag = '';
	$tb = '';
	foreach (CUSTOM_TAXONOMY_FIXED as $taxonomy => $taxonomy_prop) {
		$terms = OoGetWp::termsTree($taxonomy);
		if ($post_type === $taxonomy_prop['post_type']) {
			$selected = get_query_var($taxonomy);
			$tag .= $tb . '' . '<select name="' . $taxonomy . '">' . "\n";
			$tag .= $tb . "\t" . '<option value="">' . $taxonomy_prop['name'] . '</option>' . "\n";
			foreach ($terms as $term) {
				$tag_selected = $selected === $term->slug ? ' selected="selected"' : '';
				if (in_array($taxonomy_prop['style'], ['parent_no_child_checkbox', 'parent_no_child_radio'])) {
					$tag .= $tb . "\t" . '<optgroup label="' . $term->name . '">' . "\n";
				} else {
					$tag .= $tb . "\t" . '<option' . $tag_selected . ' value="' . $term->slug . '">' . $term->name . '</option>' . "\n";
				}
				if (isset($term->children) && $term->children) {
					foreach ($term->children as $child_term) {
						$tag .= $tb . "\t" . '<option' . $tag_selected . ' value="' . $child_term->slug . '"> - ' . $child_term->name . '</option>' . "\n";
					}
				}
				if (in_array($taxonomy_prop['style'], ['parent_no_child_checkbox', 'parent_no_child_radio'])) {
					$tag .= $tb . "\t" . '</optgroup>' . "\n";
				}
			}
			$tag .= $tb . '' . '</select>' . "\n";
		}
	}
	echo $tag;
});
loading