Удаляем ярлык рубрик (category), меток (tag) и других произвольных таксономий из URL в WordPress

Долгожданный пост!

Когда-то у меня уже была запись о том, как удалить слово «category» из URL рубрик, вот она. Это кстати был мой первый пост на блоге и, как оказалось, тот метод немного сыроват, работает не у всех и не всегда.

Сейчас я уже поколдовал над кодом сам и у меня получился метод, работающий не только для рубрик, но также для меток и произвольных таксономий.

Весь код будет состоять из двух частей, в первой часте мы собственно меняем ссылки и запросы на странице, а во второй — проставляем 301 редиректы со старых страниц на новые.

Итак, часть 1. Весь код можете вставлять в functions.php вашей темы.

// смена запроса
add_filter('request', 'true_smenit_request', 1, 1 );
 
function true_smenit_request( $query ){
 
	$taxonomia_name = 'product_cat'; // укажите название таксономии здесь, это также могут быть рубрики category или метки post_tag
 
	// запросы для дочерних элементов будут отличаться, поэтому нам потребуется дополнительная проверка
	if( $query['attachment'] ) :
		$dochernia = true; // эту переменную задаём для себя, она нам потребуется дальше
		$urlyarlyk = $query['attachment']; // это ярлык данного термина/рубрики/метки
	else:
		$dochernia = false;
		$urlyarlyk = $query['name']; // как видите, здесь ярлык хранится в другой переменной запроса
	endif;
 
 
	$termin = get_term_by('slug', $urlyarlyk, $taxonomia_name); // получаем элемент таксономии по ярлыку
 
	if ( isset( $urlyarlyk ) && $termin && !is_wp_error( $termin )): // если такого элемента не существует, прекращаем выполнение кода
 
		// для страниц дочерних элементов код немного отличается
		if( $dochernia ) {
			unset( $query['attachment'] );
			$parent = $termin->parent;
			while( $parent ) {
				$parent_term = get_term( $parent, $taxonomia_name);
				$urlyarlyk = $parent_term->slug . '/' . $urlyarlyk; // нам нужно получить полный путь, состоящий из ярлыка текущего элемента и всех его родителей
				$parent = $parent_term->parent;
			}
		} else {
			unset($query['name']);
		}
 
		switch( $taxonomia_name ): // параметры запроса для рубрик и меток отличаются от других таксономий
			case 'category':{
				$query['category_name'] = $urlyarlyk;
				break;
			}
			case 'post_tag':{
				$query['tag'] = $urlyarlyk;
				break;
			}
			default:{
				$query[$taxonomia_name] = $urlyarlyk;
				break;
			}
		endswitch;
 
	endif;
 
	return $query;
 
}
 
// смена самой ссылки
add_filter( 'term_link', 'true_smena_permalink', 10, 3 );
 
function true_smena_permalink( $url, $term, $taxonomy ){
 
	$taxonomia_name = 'product_cat'; // название таксономии, тут всё понятно
	$taxonomia_slug = 'product_cat'; // ярлык таксономии - зависит от параметра rewrite, указанного при создании и может отличаться от названия,
	// как например таксономия меток это post_tag, а ярлык по умолчанию tag
 
	// выходим из функции, если указанного ярлыка таксономии нет в URL или если название таксономии не соответствует
	if ( strpos($url, $taxonomia_slug) === FALSE || $taxonomy != $taxonomia_name ) return $url;
 
	$url = str_replace('/' . $taxonomia_slug, '', $url); // если мы ещё тут, выполняем замену в URL
 
	return $url;
}

Если вы добрались до сюда и у вас всё работает — отлично, можете переходить к следующему коду статьи.

Если же не работает, то:

  1. Обратите внимание, что я тестировал код с таксономиями с иерархией и без, а также с рубриками и метками с настройками постоянных ссылок /%postname%/.
  2. Если вы меняете URL для рубрик или меток, убедитесь, что ярлыки в настройках постоянных ссылок совпадают с указанными вами в функциях. Это же самое касается произвольных таксономий.
  3. Если вы перепроверили весь ваш код и вроде бы всё ок, оставьте комментарий к этой записи и мы разберемся вместе.

Часть вторая, код 301 редиректа:

add_action('template_redirect', 'true_delaem_redirect');
 
function true_delaem_redirect() {
 
	// указываем здесь свои значения
	$taxonomia_name = 'product_cat';
	$taxonomia_slug = 'product_cat';
 
	// выходим из функции, если ярлыка таксономии нет в URL
	if( strpos( $_SERVER['REQUEST_URI'], $taxonomia_slug ) === FALSE)
		return;
 
	// делаем суперскую проверку, чтобы случайно не редиректнуть страницы, которые не следует
	if( ( is_category() && $taxonomia_name=='category' ) || ( is_tag() && $taxonomia_name=='post_tag' ) || is_tax( $taxonomia_name ) ) :
 
        	wp_redirect( site_url( str_replace($taxonomia_slug, '', $_SERVER['REQUEST_URI']) ), 301 ); // сам редирект
		exit();
 
	endif;
 
}
Подпишитесь, чтобы раз в неделю получать свежие статьи с блога по email.

По теме

Комментарии 10

  • Terry8 января 2016 в 22:01 #

    Добрый вечер, Михаил!
    Помогите пожалуйста! Массу времени потратил. Испробовал кучу примеров.

    Есть произвольный тип записей. Films.
    Есть произвольные таксономии (рубрики): боевики, комедии и тд.
    Требуется чтобы URL страниц публикации имел вид:
    site.ru/films/boevik/nazvanie-zapisi.html

    Различные примеры выдают ошибку 404 на разных уровнях вложенности!
    Корректно не работает ни один!
    Пытался использовать плагин Custom Post Type Permalinks. Проблемы те же самые. Задача по идее очень простая! Логичная вложенная структура.

    Огромная просьба: опубликуйте рабочий пример.

    • Миша9 января 2016 в 05:01 #

      Здравствуйте!
      Вся необходимая для решения вашей задачи информация есть тут.

      • Terry9 января 2016 в 20:01 #

        А до того мне как будто это было не понятно.
        Кэп, очевидно, что дело в пермалинках.

        • Миша10 января 2016 в 14:01 #

          Я лишь написал, что вся информация, которая тебе понадобится есть там. Ты к тому же говоришь, что задача очень простая.

        • Миша10 января 2016 в 14:01 #

          Если нужен готовый код, пиши на почту, разберёмся.

  • Александр9 января 2016 в 13:01 #

    А если у страницы и рубрики одинаковые слаги? Открывается рубрика?

    • Миша10 января 2016 в 14:01 #

      Конечно, после установки этого кода, не рекомендую использовать одинаковые слаги для разных элементов сайта. Что именно открывается - страница или рубрика, не проверял :) Но по идее рубрика должна открыться.

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
Получайте новости блога по email или следите за мной в социальных сетях.
  • Владимир: и на третьей строке не хватает скобки ) закрывающей if :)

  • Миша: Добрый вечер! Рекомендую получить ID пользователя через функцию get_current_user_id().

  • Дмитрий: Миша, подскажите пожалуйста, я использую такой редирект, но он не срабатывает: add_action( 'template_redirect', funct...

  • Миша: Ну как не определена - это аргумент функции. Или я просто вас не до конца понимаю.

  • Артем: Ага, понял. Вот только почему $args? Она же нигде не определена, по логике должна быть переменная $true_field_params или...