Как правильно настроить register_post_types и register_taxonomy?

Ссылка скопирована
1 ответ

Задача: настроить 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

Т.е. страна -это рубрика, город - подрубрика, университет - запись

Как правильно настроить register_post_types и register_taxonomy?

Ответы на вопрос 0

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Стас DB Ответ

Одних 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,
]);

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);

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'
    );
});

add_action('init', function () { add_rewrite_rule( '^([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?university=$matches[3]', 'top' ); });

После изменения нужно один раз сбросить постоянные ссылки: открыть Настройки → Постоянные ссылки и сохранить. Не вызывайте flush_rewrite_rules() на каждом хите.

  • Широкое правило ^([^/]+)/([^/]+)/([^/]+)/?$ может конфликтовать со страницами и другими разделами.
  • Безопаснее использовать префикс: /universities/страна/город/университет/.
  • Нужно проверять, что страна и город в URL действительно принадлежат записи, иначе появятся дубли.
  • Если у университета может быть несколько стран/городов, заранее выберите основную таксономию.

Поэтому рабочий вариант возможен, но для продакшена лучше делать его с префиксом и проверкой соответствия терминов, а не глобальным правилом на весь сайт.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно