WordPress как на ладони
rgbcode is looking for WordPress developers.

Одинаковые ярлыки (слаги) в ЧПУ для нового (произвольного) типа записи и его произвольной таксономии

Приветствую.

  1. Создал произвольный тип записей: "Портфолио" (portfolio)
  2. Создал произвольную таксономию для этого типа записей: "Категории работ" (manufactured).

Для портфолио использую has_archive, в результате ссылка получается такая: example.com/portfolio, но у категорий работ выходят такие ссылки: example.com/manufactured/название категории, а нужно сделать example.com/portfolio/название категории.

Как такое можно реализовать? Уже 3 суток в интернете пересмотрел сотни сайтов, никакого решения не нашел.

Решение

if (!function_exists('create_a_portfolio')) {
	function create_a_portfolio() {
		$labels = array(
			'name'                => 'Портфолио',
			'singular_name'       => 'Работа',
			'menu_name'           => 'Портфолио',
			'parent_item_colon'   => 'Родительский:',
			'all_items'           => 'Все работы',
			'view_item'           => 'Просмотреть',
			'add_new_item'        => 'Добавить новую работу в портфолио',
			'add_new'             => 'Добавить работу',
			'edit_item'           => 'Редактировать работу',
			'update_item'         => 'Обновить работу',
			'search_items'        => 'Найти работу',
			'not_found'           => 'Не найдено',
			'not_found_in_trash'  => 'Не найдено в корзине',
		);
		$args = array(
			'labels'              => $labels,
			'supports'            => array('title', 'editor', 'excerpt', 'thumbnail'),
			'public'              => true,
			'menu_position'       => 5,
			'taxonomies'          => array('manufactured'),
			'menu_icon'           => 'dashicons-welcome-add-page',
			'has_archive'         => true,
			'query_var'           => true
		);
		register_post_type('portfolio', $args);
	}
	add_action('init', 'create_a_portfolio', 0);
}

if (!function_exists('create_a_portfolio_category')) {
	function create_a_portfolio_category() {
		$labels = array(
			'name'                       => 'Категории портфолио',
			'singular_name'              => 'Категориия',
			'menu_name'                  => 'Категории портфолио',
			'all_items'                  => 'Категории',
			'new_item_name'              => 'Новая категория',
			'add_new_item'               => 'Добавить новую категорию',
			'edit_item'                  => 'Редактировать категорию',
			'update_item'                => 'Обновить категорию',
			'search_items'               => 'Найти',
			'add_or_remove_items'        => 'Добавить или удалить категорию',
			'choose_from_most_used'      => 'Поиск среди популярных',
			'not_found'                  => 'Не найдено',
		);
		$args = array(
			'labels'                     => $labels,
			'hierarchical'               => true,
			'public'                     => true,
			'query_var'                  => true,
			'rewrite'                    => array('slug' => 'portfolio', 'with_front' => true)
		);
		register_taxonomy('manufactured', array('portfolio'), $args);
	}
	add_action('init', 'create_a_portfolio_category', 0);
}

/*
 * Replace Taxonomy slug with Post Type slug in url
 * Version: 1.1
 */

function taxonomy_slug_rewrite($wp_rewrite) {
	$rules = array();
	// get all custom taxonomies
	$taxonomies = get_taxonomies(array('_builtin' => false), 'objects');
	// get all custom post types
	$post_types = get_post_types(array('public' => true, '_builtin' => false), 'objects');
	foreach ($post_types as $post_type) {
		foreach ($taxonomies as $taxonomy) {
			// go through all post types which this taxonomy is assigned to
			foreach ($taxonomy->object_type as $object_type) {
				// check if taxonomy is registered for this custom type
				if ($object_type == $post_type->rewrite['slug']) {
					// get category objects
					$terms = get_categories(array('type' => $object_type, 'taxonomy' => $taxonomy->name, 'hide_empty' => 0));
					// make rules
					foreach ($terms as $term) {
						$rules[$object_type . '/' . $term->slug . '/?$'] = 'index.php?' . $term->taxonomy . '=' . $term->slug;
					}
				}
			}
		}
	}
	// merge with global rules
	$wp_rewrite->rules = $rules + $wp_rewrite->rules;
}
add_filter('generate_rewrite_rules', 'taxonomy_slug_rewrite');

/* Убираем ярлык типа записи */

function custom_remove_cpt_slug($post_link, $post, $leavename) {
	if ('portfolio' != $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', 'custom_remove_cpt_slug', 10, 3);

function custom_parse_request_tricksy($query) {
	// Only noop the main query
	if (!$query->is_main_query())
		return;
	// Only noop our very specific rewrite rule match
	if (2 != count( $query->query ) || ! isset( $query->query['page'])) {
		return;
	}
	// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
	if (!empty( $query->query['name'])) {
		$query->set('post_type', array('post', 'portfolio', 'page'));
	}
}
add_action('pre_get_posts', 'custom_parse_request_tricksy');
1
Clearman
8 лет назад 5
  • 0
    Kama9752

    Эти ярлыки это зацепки для правил перезаписи. Такое сделать не просто. Код не подскажу, там тестировать надо, готового нет.

    Принцип такой: для такс указываешь в параметре rewrite slug=portfolio и потом добавляешь в правила перезаписи (наверх) все рубрики портфолио, чтобы они проверялись первыми и при совпадении, чтобы ВП не считал ссылку таксономии как страницу типа записей portfolio. Аналогичная фитча делается в плагине удаления category из URL. Посмотри код плагина no category base или ему подобного...

    Ссылки по теме:

    Clearman 8 лет назад

    Я использовал этот код - http://someweblog.com/wordpress-custom-taxonomy-with-same-slug-as-custom-post-type/

    Полностью работает, проблем с пагинацией (в моем случаи подключен плагин WP-PageNavi) нет.

    Единственный минус - в моих хлебных крошках на странице записи (single.php) не выводится категория к которой относится данная запись. Хлебные крошки использую ваши - http://wp-kama.ru/id_541/samyie-hlebnyie-kroshki-breabcrumbs-dlya-wordpress.html

    Думаю если по колдовать - можно решить эту проблему...

    Kama 8 лет назад

    Надо смоделировать и поправить крошки... Скинь сюда весь код свой плз...

    Clearman 8 лет назад

    Кода "немного" smile

    if (!function_exists('create_a_portfolio')) {
    	function create_a_portfolio() {
    		$labels = array(
    			'name'                => 'Портфолио',
    			'singular_name'       => 'Работа',
    			'menu_name'           => 'Портфолио',
    			'parent_item_colon'   => 'Родительский:',
    			'all_items'           => 'Все работы',
    			'view_item'           => 'Просмотреть',
    			'add_new_item'        => 'Добавить новую работу в портфолио',
    			'add_new'             => 'Добавить работу',
    			'edit_item'           => 'Редактировать работу',
    			'update_item'         => 'Обновить работу',
    			'search_items'        => 'Найти работу',
    			'not_found'           => 'Не найдено',
    			'not_found_in_trash'  => 'Не найдено в корзине',
    		);
    		$args = array(
    			'labels'              => $labels,
    			'supports'            => array('title', 'editor', 'excerpt', 'thumbnail'),
    			'public'              => true,
    			'menu_position'       => 5,
    			'taxonomies'          => array('manufactured'),
    			'menu_icon'           => 'dashicons-welcome-add-page',
    			'has_archive'         => true,
    			'query_var'           => true
    		);
    		register_post_type('portfolio', $args);
    	}
    	add_action('init', 'create_a_portfolio', 0);
    }
    
    if (!function_exists('create_a_portfolio_category')) {
    	function create_a_portfolio_category() {
    		$labels = array(
    			'name'                       => 'Категории портфолио',
    			'singular_name'              => 'Категориия',
    			'menu_name'                  => 'Категории портфолио',
    			'all_items'                  => 'Категории',
    			'new_item_name'              => 'Новая категория',
    			'add_new_item'               => 'Добавить новую категорию',
    			'edit_item'                  => 'Редактировать категорию',
    			'update_item'                => 'Обновить категорию',
    			'search_items'               => 'Найти',
    			'add_or_remove_items'        => 'Добавить или удалить категорию',
    			'choose_from_most_used'      => 'Поиск среди популярных',
    			'not_found'                  => 'Не найдено',
    		);
    		$args = array(
    			'labels'                     => $labels,
    			'hierarchical'               => false,
    			'public'                     => true,
    			'query_var'                  => true,
    			'rewrite'                    => array('slug' => 'portfolio', 'with_front' => true)
    		);
    		register_taxonomy('manufactured', array('portfolio'), $args);
    	}
    	add_action('init', 'create_a_portfolio_category', 0);
    }
    
    /*
     * Replace Taxonomy slug with Post Type slug in url
     * Version: 1.1
     */
    
    function taxonomy_slug_rewrite($wp_rewrite) {
    	$rules = array();
    	// get all custom taxonomies
    	$taxonomies = get_taxonomies(array('_builtin' => false), 'objects');
    	// get all custom post types
    	$post_types = get_post_types(array('public' => true, '_builtin' => false), 'objects');
    	foreach ($post_types as $post_type) {
    		foreach ($taxonomies as $taxonomy) {
    			// go through all post types which this taxonomy is assigned to
    			foreach ($taxonomy->object_type as $object_type) {
    				// check if taxonomy is registered for this custom type
    				if ($object_type == $post_type->rewrite['slug']) {
    					// get category objects
    					$terms = get_categories(array('type' => $object_type, 'taxonomy' => $taxonomy->name, 'hide_empty' => 0));
    					// make rules
    					foreach ($terms as $term) {
    						$rules[$object_type . '/' . $term->slug . '/?$'] = 'index.php?' . $term->taxonomy . '=' . $term->slug;
    					}
    				}
    			}
    		}
    	}
    	// merge with global rules
    	$wp_rewrite->rules = $rules + $wp_rewrite->rules;
    }
    add_filter('generate_rewrite_rules', 'taxonomy_slug_rewrite');
    
    /* Убираем ярлык типа записи */
    
    function custom_remove_cpt_slug($post_link, $post, $leavename) {
    	if ('portfolio' != $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', 'custom_remove_cpt_slug', 10, 3);
    
    function custom_parse_request_tricksy($query) {
    	// Only noop the main query
    	if (!$query->is_main_query())
    		return;
    	// Only noop our very specific rewrite rule match
    	if (2 != count( $query->query ) || ! isset( $query->query['page'])) {
    		return;
    	}
    	// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
    	if (!empty( $query->query['name'])) {
    		$query->set('post_type', array('post', 'portfolio', 'page'));
    	}
    }
    add_action('pre_get_posts', 'custom_parse_request_tricksy');
    
    Kama 8 лет назад

    Глянул, крошки не работают потому что таксономия не древовидная, а они только для древовидных. Т.е. тебе просто нужно изменить параметр при реге таксы на 'hierarchical' => true,

    Ivan 2.8 лет назад

    А моголо что-то поменятся за эти 5 лет? Просто у меня некорректно работает. Я скопировал код но url получается такой:
    myexample.com/portfolio/ --- архив, тут норм
    myexample.com/portfolio/kategorija-2/ --- категория, тоже норм
    myexample.com/rabota4/ --- а вот для работы почему-то от корня url, а ведь должно быть myexample.com/portfolio/rabota4/
    Подскажите, плиз, куда копать

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