WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Настройка ЧПУ для многомерной вложенности категорий

Суть заключается в том, что бы построить ЧПУ вида:

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

Помогите разобраться.

0
Павел
20 дней назад

Нет ответов на этот вопрос.

    На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация