Подключение шаблонов для Типов записей и Таксономий при их регистрации
Идея: при регистрации Типа записи и Таксономии сразу указывать, какой шаблон будет использоваться для Архива, а какой для Записи, а также сколько выводить в этом шаблоне записей.
Реализация:
<?php /** * При регистрации 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; } ); // Устанавливаем количество выводимых записей в архивах. // Поддерживается свойсва 'posts_per_page_front' (приоритет) и 'posts_per_page' (fallback). add_action( 'pre_get_posts', function ( $query ) use ( $ctp_object ) { $ppp_front = $ctp_object->posts_per_page_front ?? null; $ppp_front = $ppp_front ?: ( $ctp_object->posts_per_page ?? null ); if ( ! empty( $ppp_front ) && ! is_admin() && $query->is_main_query() && $query->is_post_type_archive( $ctp_object->name ) ) { $query->set( 'posts_per_page', $ppp_front ); } } ); // Скрываем выбор количества постов в админке для типа записи, если он указывается программно. add_action( 'admin_head-edit.php', static function () use ( $ctp_object ) { global $typenow; if ( $typenow === $ctp_object->name && isset( $ctp_object->posts_per_page_admin ) ) { ?> <style> #screen-meta .screen-options { display: none; } </style> <?php } } ); // Устанавливаем количество постов в таблице в админке. add_filter( "edit_{$ctp_object->name}_per_page", static function ( $posts_per_page ) use ( $ctp_object ) { $ppp_admin = $ctp_object->posts_per_page_admin ?? $posts_per_page; return $ppp_admin === - 1 ? 1000 : $ppp_admin; } ); // Устанавливаем плейсхолдер в поле Заголовок на странице редактирования записи 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' => 'Установите Фотографию события', 'title_placeholder' => 'Введите название события', 'first_menu_name' => 'Список событий', ], '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 ещё удобнее, но появляется минус - магия, о которой в будущем можно забыть и долго чесать затылок, как же это работает.