в общем добавил древовидную структуру, немного переделав фильтр.
function filter_post_type_link($link, $post) {
if ($post->post_type != 'products')
return $link;
if ($cats = get_the_terms($post->ID, 'catalogs'))
$parent_slug = get_term_parents_list($cats[0]->term_id, 'catalogs', array(
'separator' => '/',
'format' => 'slug',
'link' => false,
'inclusive' => true,
) );
$parent_slug = mb_substr($parent_slug, 0, -1);
$link = str_replace('%catalogs%', $parent_slug, $link);
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
осталось решить проблему с общей базой.
Нужна база - catalog и для такс и для постов. т.е. вот этот пример
site.ru/catalog/term/subterm/ - выводятся продукты привязанные к subterm.
site.ru/catalog/term/subterm/product/ - страничка продукта(кастомный тип поста).
Сейчас если rewrite делать не с общей базой catalog, то все работает как надо и открываются и разделы/подразделы и сам товар, но разная база портит цельность структуры. И в хлебных крошках тоже выглядит это не очень хорошо.
UP.
В общем вроде бы получил
конечное решение. Может кому-то пригодится. Так же
прошу людей хорошо разбирающихся в теме указать на ошибки, подводные камни такого решения или возможно предложить более правильное. Мое такое получилось:
////////////////////////////////////////////////
add_action( 'init', 'register_faq_post_type' );
function register_faq_post_type() {
register_taxonomy('catalogs', array('products'), array(
'label' => 'Раздел каталога',
'labels' => array(
'name' => 'Разделы каталога',
'singular_name' => 'Раздел каталога',
'search_items' => 'Найти раздел каталога',
'all_items' => 'Все разделы каталога',
'view_item ' => 'Показать раздел каталога',
'parent_item' => 'Родительский раздел каталога',
'parent_item_colon' => 'Родительский раздел каталога:',
'edit_item' => 'Редактировать раздел каталога',
'update_item' => 'Обновить раздел',
'add_new_item' => 'Добавить новый раздел',
'new_item_name' => 'Новое имя раздела',
'menu_name' => 'Разделы каталога',
),
'description' => 'Разделы каталога',
'public' => true,
'show_in_nav_menus' => false,
'show_ui' => true,
'show_tagcloud' => false,
'hierarchical' => true,
'rewrite' => array('slug'=>'catalog', 'hierarchical'=>true, 'with_front'=>false, 'feed'=>false ),
'show_admin_column' => true,
) );
register_post_type('products', array(
'label' => 'Продукция',
'labels' => array(
'name' => 'Продукция',
'singular_name' => 'Продукт',
'add_new' => 'Новый продукт',
'add_new_item' => 'Добавить новый продукт',
'edit_item' => 'Редактировать продукт',
'new_item' => 'Новый продукт',
'view_item' => 'Просмотреть продукт',
'search_items' => 'Найти продукт',
'not_found' => 'Продукты не найдены',
'not_found_in_trash' => 'В корзине продуктов нет'
),
'description' => '',
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_rest' => false,
'rest_base' => '',
'show_in_menu' => true,
'exclude_from_search' => false,
'capability_type' => 'post',
'map_meta_cap' => true,
'hierarchical' => false,
'rewrite' => array('slug'=>'products/%catalogs%'),
'has_archive' => 'catalog',
'query_var' => true,
'supports' => array( 'title', 'editor' ),
'taxonomies' => array( 'catalogs' ),
) );
}
function filter_post_type_link($link, $post) {
if ($post->post_type != 'products')
return $link;
if ($cats = get_the_terms($post->ID, 'catalogs'))
$parent_slug = get_term_parents_list($cats[0]->term_id, 'catalogs', array(
'separator' => '/',
'format' => 'slug',
'link' => false,
'inclusive' => true,
) );
$parent_slug = mb_substr($parent_slug, 0, -1);
$link = str_replace('%catalogs%', 'catalog/'.$parent_slug, $link);
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
function default_taxonomy_term( $post_id, $post ) {
if ( 'publish' === $post->post_status ) {
$defaults = array(
'catalogs' => array('non-cat'),
);
$taxonomies = get_object_taxonomies( $post->post_type );
foreach ( (array) $taxonomies as $taxonomy ) {
$terms = wp_get_post_terms( $post_id, $taxonomy );
if ( empty( $terms ) && array_key_exists( $taxonomy, $defaults ) ) {
wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy );
}
}
}
}
add_action( 'save_post', 'default_taxonomy_term', 100, 2 );
function na_remove_slug( $post_link, $post, $leavename ) {
if ( 'products' != $post->post_type || 'publish' != $post->post_status ) {
return $post_link;
}
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'na_remove_slug', 10, 3 );
function na_parse_request( $query ) {
if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'post', 'products', 'page' ) );
}
}
add_action( 'pre_get_posts', 'na_parse_request' );