Подключение шаблонов для Типов записей и Таксономий при их регистрации

Click here to view original web page at wp-kama.ru

Идея: при регистрации Типа записи и Таксономии сразу указывать, какой шаблон будет использоваться для Архива, а какой для Записи, а также сколько выводить в этом шаблоне записей.

Реализация:

/**
 * При регистрации CTP "ловит" и применяет параметры "Шаблон" и "Количество выводимых постов".
 */
add_action( 'registered_post_type', function ( $post_type, $ctp_object ) {

	add_filter( 'template_include', function ( $templates ) use ( $ctp_object ) {
		// Задаём шаблон одиночной записи.
		if ( ! empty( $ctp_object->template_item ) && is_singular( $ctp_object->name ) ) {
			$templates = locate_template( $ctp_object->template_item );
		}

		// Задаём шаблон архиву записей.
		if ( ! empty( $ctp_object->template_archive ) && is_post_type_archive( $ctp_object->name ) ) {
			$templates = locate_template( $ctp_object->template_archive );
		}

		return $templates;
	} );

	// Устанавливаем количество выводимых записей в архивах.
	add_action( 'pre_get_posts', function ( $query ) use ( $ctp_object ) {
		if (
			! empty( $ctp_object->posts_per_page )
			&& ! is_admin()
			&& $query->is_main_query()
			&& $query->is_post_type_archive( $ctp_object->name )
		) {
			$query->set( 'posts_per_page', $ctp_object->posts_per_page );
		}
	} );

	// Устанавливаем плейсхолдер в поле Заголовок на странице редактирования записи
	add_filter( 'enter_title_here', function ( $text, $post ) use ( $ctp_object ) {
		if ( isset( $ctp_object->labels->title_placeholder ) && $post->post_type === $ctp_object->name ) {
			$text = $ctp_object->labels->title_placeholder;
		}

		return $text;
	}, 11, 2 );

}, 10, 2 );

/**
 * При регистрации Таксономии "ловит" и применяет параметры "Шаблон" и "Количество выводимых постов".
 */
add_action( 'registered_taxonomy', function ( $taxonomy, $object_type, $taxonomy_object ) {
	add_filter( 'template_include', function ( $templates ) use ( $taxonomy, $taxonomy_object ) {
		// Задаём шаблон термину.
		if ( ! empty( $taxonomy_object['template_item'] ) && is_tax( $taxonomy ) ) {
			$templates = locate_template( $taxonomy_object['template_item'] );
		}

		return $templates;
	} );

	// Устанавливаем количество выводимых записей в архивах.
	add_action( 'pre_get_posts', function ( $query ) use ( $taxonomy, $taxonomy_object ) {
		if (
			! empty( $taxonomy_object['posts_per_page'] )
			&& ! is_admin()
			&& $query->is_main_query()
			&& $query->is_tax( $taxonomy )
		) {
			$query->set( 'posts_per_page', $taxonomy_object['posts_per_page'] );
		}
	} );

}, 10, 3 );

Теперь можем указать шаблон и количество выводимых в нём записей сразу при регистрации сущностей:

// Для Типа записи
register_post_type( 'events', [
	'labels'           => [
		'name'               => 'События',
		'singular_name'      => 'События',
		'name_admin_bar'     => 'События',
		'menu_name'          => 'События',
		'add_new'            => 'Добавить новое событие',
		'add_new_item'       => 'Добавить новое событие',
		'edit_item'          => 'Редактировать событие',
		'new_item'           => 'Новое событие',
		'view_item'          => 'Посмотреть событие',
		'search_items'       => 'Найти событие',
		'not_found'          => 'Событие не найдено',
		'not_found_in_trash' => 'В корзине событие не найдено',
		'featured_image'     => 'Фото События',
		'set_featured_image' => 'Установите Фотографию события',
	],
	'public'           => true,
	'rewrite'          => [ 'slug' => 'events' ],
	'capability_type'  => 'post',
	'has_archive'      => 'events',
	'hierarchical'     => false,
	'menu_position'    => 7,
	'menu_icon'        => 'dashicons-megaphone',
	'supports'         => [ 'title', 'thumbnail', 'editor' ],

	'template_item'    => '/templates/event/single/event-single.php',
	'template_archive' => '/templates/event/archive/event-archive.php',
	'posts_per_page'   => 4,

	'show_in_rest'     => true,
	'show_ui'          => true,
	'show_in_menu'     => true,
] );

// Для Таксономии
register_taxonomy( 'section', [ 'news' ], [
	'hierarchical'      => false,
	'labels'            => [
		'name'               => 'Секция',
		'singular_name'      => 'Секция',
		'add_new'            => 'Добавить новую',
		'add_new_item'       => 'Добавить новую секцию',
		'edit_item'          => 'Редактировать секцию',
		'new_item'           => 'Новая секция',
		'view_item'          => 'Посмотреть секцию',
		'search_items'       => 'Найти секцию',
		'not_found'          => 'Секция не найдены',
		'not_found_in_trash' => 'В корзине секций не найдено',
		'menu_name'          => 'Секции',
	],

	'template_item'    => '/templates/event/archive/event-archive.php',
	'posts_per_page'   => 4,

	'show_admin_column' => true,
	'show_in_rest'      => false,
] );

Благодаря такому подходу, вы можете при регистрации указать любой свой параметр, а потом в фильтрах registered_post_type/registered_taxonomy его применить, что делает работу с WordPress ещё удобнее, но появляется минус - магия, о которой в будущем можно забыть и долго чесать затылок, как же это работает.