Как создать структуру постоянных ссылок для произвольных типов записей и таксономий (вложенные термы)?
Я больше не могу. Перерыл весь интернет и перепробывал разные фрагменты кода, но так и не нашёл того что мне нужно. Надеюсь на помощь сообщества: https://qna.habr.com/q/826639
Что я сделал:
Создал произвольный тип записи и зарегистрировал
px_product - тип записи - товары.
px_product_cat - таксономия - категории товаров (термы таксономии имеют иерархическую структуру, вложенность).
Мне нужно, чтобы ссылки имели следующий вид:
mysite.com/products/category1/child-category-1/grandchild-category-1/product-name mysite.com/Товары/Мебель/Мягкая мебель/Диваны/Диван mysite.com/products/category-1/category-1.1/category-1.1.1/product-name
Вот часть моего functions.php файла
/** * CPT - Создание произвольного типа записи. */ add_action( 'init', 'cpt_product', 0 ); function cpt_product() { // Тип записи register_post_type( 'px_product', array( 'labels' => array( 'name' => __( 'Товары' ) ), 'public' => true, 'show_ui' => true, 'capability_type' => 'post', 'publicly_queryable' => true, 'exclude_from_search' => false, 'hierarchical' => true, '_builtin' => false, 'query_var' => true, 'rewrite' => array( 'slug' => 'products/%px_product_cat%', 'with_front' => true ), 'supports' => array( 'title', 'editor', 'author', 'excerpt', 'trackbacks', 'custom-fields' ) ) ); // Таксономия register_taxonomy( 'px_product_cat', array( 'px_product' ), array( 'labels' => array( 'name' => __( 'Категории' ) ), 'hierarchical' => true, 'show_ui' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'products', 'with_front' => true ) ) ); } /** * PermaLink - Внедрение терма таксономии в структуру постоянных ссылок для произвольного типа записи. */ add_filter( 'post_type_link', 'permalink_cpt_product', 10, 2 ); function permalink_cpt_product( $link, $post ) { if ( $post->post_type === 'px_product' ) { if ( $terms = get_the_terms( $post->ID, 'px_product_cat' ) ) $link = str_replace( '%px_product_cat%', current( $terms )->slug, $link ); } return $link; }
Далее, я создаю в админ панели WordPress три терма (категории), которые имею вложенность:
- Мебель
- Мягкая
- Диваны
Далее создаю новый товар - Диван, и присваиваю ему категорию Диваны.
В теме Astra путь хлебных крошек такой:
Главная/Мебель/Мягкая/Диваны/Диван
Ссылка выглядит так:
http://a.ru/products/диваны/диван/
Помогите, что мне сделать, чтобы моя ссылка выводила полный путь, как в крошках
http://a.ru/products/мебель/мягкая/диваны/диван
В поиске решения:
Нашёл похожий вопрос тут
Код работает, но есть 2 проблемы:
- В ссылке появляется двойной слешь
http://b.ru/products/Мебель/Мягкая/Диваны//Диван - Если перейти по пути выше, Диваны или Мягкая, то структура рушиться:
http://b.ru/products/Диваны/
http://b.ru/products/Мягкая/
// 1 add_filter( 'rewrite_rules_array', 'mmp_rewrite_rules' ); function mmp_rewrite_rules( $rules ) { $newRules = array(); $newRules['products/(.+)/(.+)/(.+)/(.+)/?$'] = 'index.php?px_product=$matches[4]'; // my custom structure will always have the post name as the 5th uri segment $newRules['products/(.+)/?$'] = 'index.php?px_product_cat=$matches[1]'; return array_merge( $newRules, $rules ); } // 2 add_filter( 'post_type_link', 'filter_post_type_link', 10, 2 ); function filter_post_type_link( $link, $post ) { if ($post->post_type != 'px_product') return $link; if ( $cats = get_the_terms( $post->ID, 'px_product_cat' ) ) { $link = str_replace( '%px_product_cat%', get_taxonomy_parents( array_pop( $cats )->term_id, 'px_product_cat', false, '/', true ), $link ); // see 3 custom function defined below } return $link; } // 3 - my own function to do what get_category_parents does for other taxonomies function get_taxonomy_parents( $id, $taxonomy, $link = false, $separator = '/', $nicename = false, $visited = array() ) { $chain = ''; $parent = &get_term( $id, $taxonomy ); if ( is_wp_error( $parent ) ) { return $parent; } if ( $nicename ) $name = $parent -> slug; else $name = $parent -> name; if ( $parent -> parent && ( $parent -> parent != $parent -> term_id ) && !in_array( $parent -> parent, $visited ) ) { $visited[] = $parent -> parent; $chain .= get_taxonomy_parents( $parent -> parent, $taxonomy, $link, $separator, $nicename, $visited ); } if ( $link ) { // nothing, can't get this working :( } else $chain .= $name . $separator; return $chain; }
В сети есть готовое решение.
В functions:
В админке нужно будет зайти в Настройки -> Постоянные ссылки -> Общие настройки, выставить на "Произвольно"и в поле после домена указать /%postname%/.
т.е http://домен.com
/%postname%/