• Как добавить поддержку древовидной таксономии у пользовательских типов?

    @DarkFlame77 Автор вопроса
    в общем добавил древовидную структуру, немного переделав фильтр.
    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' );
    Ответ написан
    Комментировать