Настройка ЧПУ для многомерной вложенности категорий
Суть заключается в том, что бы построить ЧПУ вида:
site.com/catalog/{category}/{sub-category-1}/{sub-category-2}/.../{sub-category-N}
Если переходим в категорию, нам выводятся все товары и подкатегории, если заходим в подкатегорию, выводятся все его товары и его дочерние подкатегории и так далее.
В моём коде получилось вывести 3 вложенности, при переходе на товары
site.com/catalog/{category}/{sub-category-1}/{name-product}
всё хорошо,
открывает карточку, при переходе на товары
site.com/catalog/{category}/{sub-category-1}/{sub-category-2}/{name-product}
выбивает ошибку 404
Хочу сделать что бы работало в кастомной записи как и в родной wordpress-a, при настройке постоянных произвольных ссылок вида:
site.com/%category%/%postname%
Регистрирую кастомный пост для каталога
add_action('init', 'register_post_products');
function register_post_products(){
register_post_type('products', array(
'label' => null,
'labels' => array(
'name' => 'Каталог', // основное название для типа записи
'singular_name' => 'Каталог', // название для одной записи этого типа
'add_new' => 'Добавить товар', // для добавления новой записи
'add_new_item' => 'Добавление товара', // заголовка у вновь создаваемой записи в админ-панели.
'edit_item' => 'Редактирование товара', // для редактирования типа записи
'new_item' => 'Новый товар', // текст новой записи
'view_item' => 'Смотреть товар', // для просмотра записи этого типа.
'search_items' => 'Искать товар', // для поиска по этим типам записи
'not_found' => 'Не найдено', // если в результате поиска ничего не было найдено
'not_found_in_trash' => 'Не найдено в корзине', // если не было найдено в корзине
'parent_item_colon' => '', // для родителей (у древовидных типов)
'menu_name' => 'Каталог', // название меню
),
'description' => 'Здесь публикуются товары',
'public' => true,
'publicly_queryable' => null,
'exclude_from_search' => false,
'show_ui' => true,
'show_in_menu' => true, // показывать ли в меню админки
'show_in_admin_bar' => true, // по умолчанию значение show_in_menu
'show_in_nav_menus' => null,
'show_in_rest' => null, // добавить в REST API. C WP 4.7
'rest_base' => null, // $post_type. C WP 4.7
'menu_position' => 2,
'menu_icon' => 'dashicons-format-gallery',
'capability_type' => 'post',
'hierarchical' => false,
'supports' => array('title','editor', 'thumbnail'), // 'title','editor','author','thumbnail','excerpt','trackbacks','custom-fields','comments','revisions','page-attributes','post-formats'
'taxonomies' => array('product-category'),
'has_archive' => true,
'rewrite' => array('hierarchical' => false, 'slug' => 'catalog/%product-category%/', "with_front" => false),
'query_var' => true,
) );
}
затем регистрирую таксономию
add_action('init', 'create_taxonomy');
function create_taxonomy(){
// список параметров: http://wp-kama.ru/function/get_taxonomy_labels
register_taxonomy(
'product-category',
array('products'),
array(
'label' => '', // определяется параметром $labels->name
'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,
'publicly_queryable' => null, // равен аргументу public
'show_in_nav_menus' => true, // равен аргументу public
'show_ui' => true, // равен аргументу public
'show_tagcloud' => false, // равен аргументу show_ui
'show_in_rest' => null, // добавить в REST API
'rest_base' => null, // $taxonomy
'hierarchical' => true,
'update_count_callback' => '',
'query_var' => true,
'capabilities' => array(),
'meta_box_cb' => 'post_categories_meta_box', // callback функция. Отвечает за html код метабокса (с версии 3.8): post_categories_meta_box или post_tags_meta_box. Если указать false, то метабокс будет отключен вообще
'show_admin_column' => true, // Позволить или нет авто-создание колонки таксономии в таблице ассоциированного типа записи. (с версии 3.5)
'_builtin' => false,
'show_in_quick_edit' => null, // по умолчанию значение show_ui,
'rewrite' => array( 'hierarchical' => true, 'slug' => 'catalog', "with_front" => true),
) );
}
затем перезаписываю правила
function mmp_rewrite_rules($rules)
{
$newRules = array();
$newRules['catalog/(.+)/(.+)/(.+)/(.+)$'] = 'index.php?products=$matches[4]'; // my custom structure will always have the post name as the 5th uri segment
$newRules['catalog/(.+)/(.+)/(.+)$'] = 'index.php?products=$matches[3]'; // my custom structure will always have the post name as the 5th uri segment
$newRules['catalog/(.+?)$'] = 'index.php?product-category=$matches[1]';
// Cleaner::pre($rules);
return array_merge($newRules, $rules);
}
function filter_post_type_link($link, $post)
{
if ($post->post_type != 'products')
return $link;
if ($cats = get_the_terms($post->ID, 'product-category')) {
$link = str_replace('%product-category%', get_taxonomy_parents(array_pop($cats)->term_id, 'product-category', false, '/', true), $link); // see custom function defined below
}
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
// 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;
}
Помогите разобраться.