Как правильно настроить register_post_types и register_taxonomy?
Задача: настроить register_post_types и register_taxonomy
Ожидание: пост кастомного типа записи открывается по адресу "домен/страна/город/университет", где "страна" и "город" это кастомные таксономии присвоенные для поста кастомного типа записи
Вводные:
1. Код functions.php согласно источника: wp-kama.ru/function/register_post_type:
function register_post_types(){ register_post_type( 'universities', [ 'label' => null, 'labels' => [ 'name' => 'Universities', // основное название для типа записи 'singular_name' => 'universities', // название для одной записи этого типа 'add_new' => 'Добавить Uni', // для добавления новой записи 'add_new_item' => 'Добавление Uni', // заголовка у вновь создаваемой записи в админ-панели. 'edit_item' => 'Редактирование Uni', // для редактирования типа записи 'new_item' => 'Новое Uni', // текст новой записи 'view_item' => 'Смотреть Uni', // для просмотра записи этого типа. 'search_items' => 'Искать Uni', // для поиска по этим типам записи 'not_found' => 'Не найдено', // если в результате поиска ничего не было найдено 'not_found_in_trash' => 'Не найдено в корзине', // если не было найдено в корзине 'parent_item_colon' => '', // для родителей (у древовидных типов) 'menu_name' => '', // название меню ], 'description' => '', 'public' => true, // 'publicly_queryable' => null, // зависит от public // 'exclude_from_search' => null, // зависит от public // 'show_ui' => null, // зависит от public // 'show_in_nav_menus' => null, // зависит от public 'show_in_menu' => null, // показывать ли в меню админки // 'show_in_admin_bar' => null, // зависит от show_in_menu 'show_in_rest' => null, // добавить в REST API. C WP 4.7 'rest_base' => null, // $post_type. C WP 4.7 'menu_position' => null, 'menu_icon' => null, //'capability_type' => 'post', //'capabilities' => 'post', // массив дополнительных прав для этого типа записи //'map_meta_cap' => null, // Ставим true чтобы включить дефолтный обработчик специальных прав 'hierarchical' => false, 'supports' => [ 'title', 'editor' ], // 'title','editor','author','thumbnail','excerpt','trackbacks','custom-fields','comments','revisions','page-attributes','post-formats' 'taxonomies' => ['country'], 'has_archive' => false, 'rewrite' => array('slug' => 'universities/country/city'), 'query_var' => true, ] ); } add_action( 'init', 'register_post_types' ); function create_taxonomy(){ register_taxonomy( 'country', [ 'universities' ], [ 'label' => '', // определяется параметром $labels->name 'labels' => [ 'name' => 'Country', 'singular_name' => 'Country', 'search_items' => 'Search Country', 'all_items' => 'All Country', 'view_item ' => 'View Country', 'parent_item' => 'Parent Country', 'parent_item_colon' => 'Parent Country:', 'edit_item' => 'Edit Country', 'update_item' => 'Update Country', 'add_new_item' => 'Add New Country', 'new_item_name' => 'New Country Name', 'menu_name' => 'Country', 'back_to_items' => '← Back to Country', ], 'description' => '', // описание таксономии 'public' => true, // 'publicly_queryable' => null, // равен аргументу public // 'show_in_nav_menus' => true, // равен аргументу public // 'show_ui' => true, // равен аргументу public // 'show_in_menu' => true, // равен аргументу show_ui // 'show_tagcloud' => true, // равен аргументу show_ui // 'show_in_quick_edit' => null, // равен аргументу show_ui 'hierarchical' => true, 'rewrite' => array('slug' => 'universities'), //'query_var' => $taxonomy, // название параметра запроса 'capabilities' => array(), 'meta_box_cb' => null, // html метабокса. callback: `post_categories_meta_box` или `post_tags_meta_box`. false — метабокс отключен. 'show_admin_column' => false, // авто-создание колонки таксы в таблице ассоциированного типа записи. (с версии 3.5) 'show_in_rest' => null, // добавить в REST API 'rest_base' => null, // $taxonomy // '_builtin' => false, //'update_count_callback' => '_update_post_term_count', ] ); register_taxonomy( 'city', [ 'universities' ], [ 'label' => '', // определяется параметром $labels->name 'labels' => [ 'name' => 'city', 'singular_name' => 'city', 'search_items' => 'Search city', 'all_items' => 'All city', 'view_item ' => 'View city', 'parent_item' => 'Parent city', 'parent_item_colon' => 'Parent city:', 'edit_item' => 'Edit city', 'update_item' => 'Update city', 'add_new_item' => 'Add New city', 'new_item_name' => 'New city Name', 'menu_name' => 'city', 'back_to_items' => '← Back to city', ], 'description' => '', // описание таксономии 'public' => true, // 'publicly_queryable' => null, // равен аргументу public // 'show_in_nav_menus' => true, // равен аргументу public // 'show_ui' => true, // равен аргументу public // 'show_in_menu' => true, // равен аргументу show_ui // 'show_tagcloud' => true, // равен аргументу show_ui // 'show_in_quick_edit' => null, // равен аргументу show_ui 'hierarchical' => true, // Указываем, что таксономия иерархическая 'parent' => 'country', 'rewrite' => array('slug' => 'universities/country'), //'query_var' => $taxonomy, // название параметра запроса 'capabilities' => array(), 'meta_box_cb' => null, // html метабокса. callback: `post_categories_meta_box` или `post_tags_meta_box`. false — метабокс отключен. 'show_admin_column' => false, // авто-создание колонки таксы в таблице ассоциированного типа записи. (с версии 3.5) 'show_in_rest' => null, // добавить в REST API 'rest_base' => null, // $taxonomy // '_builtin' => false, //'update_count_callback' => '_update_post_term_count', ] ); } add_action( 'init', 'create_taxonomy' ); |
function register_post_types(){ register_post_type( 'universities', [ 'label' => null, 'labels' => [ 'name' => 'Universities', // основное название для типа записи 'singular_name' => 'universities', // название для одной записи этого типа 'add_new' => 'Добавить Uni', // для добавления новой записи 'add_new_item' => 'Добавление Uni', // заголовка у вновь создаваемой записи в админ-панели. 'edit_item' => 'Редактирование Uni', // для редактирования типа записи 'new_item' => 'Новое Uni', // текст новой записи 'view_item' => 'Смотреть Uni', // для просмотра записи этого типа. 'search_items' => 'Искать Uni', // для поиска по этим типам записи 'not_found' => 'Не найдено', // если в результате поиска ничего не было найдено 'not_found_in_trash' => 'Не найдено в корзине', // если не было найдено в корзине 'parent_item_colon' => '', // для родителей (у древовидных типов) 'menu_name' => '', // название меню ], 'description' => '', 'public' => true, // 'publicly_queryable' => null, // зависит от public // 'exclude_from_search' => null, // зависит от public // 'show_ui' => null, // зависит от public // 'show_in_nav_menus' => null, // зависит от public 'show_in_menu' => null, // показывать ли в меню админки // 'show_in_admin_bar' => null, // зависит от show_in_menu 'show_in_rest' => null, // добавить в REST API. C WP 4.7 'rest_base' => null, // $post_type. C WP 4.7 'menu_position' => null, 'menu_icon' => null, //'capability_type' => 'post', //'capabilities' => 'post', // массив дополнительных прав для этого типа записи //'map_meta_cap' => null, // Ставим true чтобы включить дефолтный обработчик специальных прав 'hierarchical' => false, 'supports' => [ 'title', 'editor' ], // 'title','editor','author','thumbnail','excerpt','trackbacks','custom-fields','comments','revisions','page-attributes','post-formats' 'taxonomies' => ['country'], 'has_archive' => false, 'rewrite' => array('slug' => 'universities/country/city'), 'query_var' => true, ] ); } add_action( 'init', 'register_post_types' ); function create_taxonomy(){ register_taxonomy( 'country', [ 'universities' ], [ 'label' => '', // определяется параметром $labels->name 'labels' => [ 'name' => 'Country', 'singular_name' => 'Country', 'search_items' => 'Search Country', 'all_items' => 'All Country', 'view_item ' => 'View Country', 'parent_item' => 'Parent Country', 'parent_item_colon' => 'Parent Country:', 'edit_item' => 'Edit Country', 'update_item' => 'Update Country', 'add_new_item' => 'Add New Country', 'new_item_name' => 'New Country Name', 'menu_name' => 'Country', 'back_to_items' => '← Back to Country', ], 'description' => '', // описание таксономии 'public' => true, // 'publicly_queryable' => null, // равен аргументу public // 'show_in_nav_menus' => true, // равен аргументу public // 'show_ui' => true, // равен аргументу public // 'show_in_menu' => true, // равен аргументу show_ui // 'show_tagcloud' => true, // равен аргументу show_ui // 'show_in_quick_edit' => null, // равен аргументу show_ui 'hierarchical' => true, 'rewrite' => array('slug' => 'universities'), //'query_var' => $taxonomy, // название параметра запроса 'capabilities' => array(), 'meta_box_cb' => null, // html метабокса. callback: `post_categories_meta_box` или `post_tags_meta_box`. false — метабокс отключен. 'show_admin_column' => false, // авто-создание колонки таксы в таблице ассоциированного типа записи. (с версии 3.5) 'show_in_rest' => null, // добавить в REST API 'rest_base' => null, // $taxonomy // '_builtin' => false, //'update_count_callback' => '_update_post_term_count', ] ); register_taxonomy( 'city', [ 'universities' ], [ 'label' => '', // определяется параметром $labels->name 'labels' => [ 'name' => 'city', 'singular_name' => 'city', 'search_items' => 'Search city', 'all_items' => 'All city', 'view_item ' => 'View city', 'parent_item' => 'Parent city', 'parent_item_colon' => 'Parent city:', 'edit_item' => 'Edit city', 'update_item' => 'Update city', 'add_new_item' => 'Add New city', 'new_item_name' => 'New city Name', 'menu_name' => 'city', 'back_to_items' => '← Back to city', ], 'description' => '', // описание таксономии 'public' => true, // 'publicly_queryable' => null, // равен аргументу public // 'show_in_nav_menus' => true, // равен аргументу public // 'show_ui' => true, // равен аргументу public // 'show_in_menu' => true, // равен аргументу show_ui // 'show_tagcloud' => true, // равен аргументу show_ui // 'show_in_quick_edit' => null, // равен аргументу show_ui 'hierarchical' => true, // Указываем, что таксономия иерархическая 'parent' => 'country', 'rewrite' => array('slug' => 'universities/country'), //'query_var' => $taxonomy, // название параметра запроса 'capabilities' => array(), 'meta_box_cb' => null, // html метабокса. callback: `post_categories_meta_box` или `post_tags_meta_box`. false — метабокс отключен. 'show_admin_column' => false, // авто-создание колонки таксы в таблице ассоциированного типа записи. (с версии 3.5) 'show_in_rest' => null, // добавить в REST API 'rest_base' => null, // $taxonomy // '_builtin' => false, //'update_count_callback' => '_update_post_term_count', ] ); } add_action( 'init', 'create_taxonomy' );
2. Cозданы страницы для отображения информации согласно источника wp-kama.ru/handbook/theme/theme-files-hierarchy: taxonomy-country.php, taxonomy-city.php и single-universities.php.
Контекст: помимо университетов будут так же кастомные записи для других типов записи.
Что я делал: пытался добавить ярлык к урлу.
function custom_term_link($termlink, $term, $taxonomy) { // Проверяем, что мы работаем с таксономией city if ($taxonomy === 'city') { // Получаем родительскую таксономию country $country = get_term($term->parent, 'country'); // Если у термина есть родительская таксономия country, добавляем ее ярлык к урлу if ($country && !is_wp_error($country)) { $termlink = str_replace('country', $country->slug, $termlink); } } return $termlink; } add_filter('term_link', 'custom_term_link', 10, 3); |
function custom_term_link($termlink, $term, $taxonomy) { // Проверяем, что мы работаем с таксономией city if ($taxonomy === 'city') { // Получаем родительскую таксономию country $country = get_term($term->parent, 'country'); // Если у термина есть родительская таксономия country, добавляем ее ярлык к урлу if ($country && !is_wp_error($country)) { $termlink = str_replace('country', $country->slug, $termlink); } } return $termlink; } add_filter('term_link', 'custom_term_link', 10, 3);
Что я получил: нулевой результат.
Вопрос: как правильно настроить register_post_types и register_taxonomy чтобы получить для поста кастомного типа записи урлы вида "домен/страна/город/университет", где "страна" и "город" это кастомные таксономии присвоенные для поста кастомного типа записи?
Дополнительные вопросы
Не совсем ответ на вопрос, может пища для раздумий
Штатно урл вида "домен/страна/город/университет", наверное, проще задать так (на примере рубрик у записей):
-Страна1
--Город1.1
---Универ1.1.1
---Универ1.1.2
--Город1.2
---Универ1.2.3
-Страна2
--Город2.1
---Универ2.1.1
Т.е. страна -это рубрика, город - подрубрика, университет - запись
Ответы на вопрос 0
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос

Одних
register_post_type()иregister_taxonomy()недостаточно, чтобы запись открывалась по адресу/страна/город/университет/. Таксономии присваиваются записи, но WordPress сам не подставляет их slug в permalink кастомного типа. Нужны три части: регистрация CPT с rewrite-шаблоном, замена плейсхолдеров в ссылке и правило разбора входящего URL.Пример регистрации:
register_post_type('university', [ 'public' => true, 'rewrite' => [ 'slug' => '%country%/%city%', 'with_front' => false, ], 'has_archive' => false, ]);
Дальше заменяем плейсхолдеры на термины конкретной записи:
add_filter('post_type_link', function ($link, $post) { if ($post->post_type !== 'university') { return $link; } $country = wp_get_post_terms($post->ID, 'country', ['fields' => 'slugs']); $city = wp_get_post_terms($post->ID, 'city', ['fields' => 'slugs']); return str_replace( ['%country%', '%city%'], [$country[0] ?? 'no-country', $city[0] ?? 'no-city'], $link ); }, 10, 2);
И добавляем rewrite rule:
add_action('init', function () { add_rewrite_rule( '^([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?university=$matches[3]', 'top' ); });
После изменения нужно один раз сбросить постоянные ссылки: открыть
Настройки → Постоянные ссылкии сохранить. Не вызывайтеflush_rewrite_rules()на каждом хите.^([^/]+)/([^/]+)/([^/]+)/?$может конфликтовать со страницами и другими разделами./universities/страна/город/университет/.Поэтому рабочий вариант возможен, но для продакшена лучше делать его с префиксом и проверкой соответствия терминов, а не глобальным правилом на весь сайт.