Создал произвольный тип записи service и таксономию к нему service_category.
По заданию нужно было сделать ссылку sitename.ru/название категории/название записи.
И теперь тип записи доступен по 2 ссылкам: sitename.ru/категория_1/услуга_1 и sitename.ru/service/услуга_1
С таксономией так же sitename.ru/категория_1/ и sitename.ru/service_category/категория_1
Как убрать вот эти дубли с ярлыками ? Сеошник говорит, что это очень плохо
Вот код, который использовал, чтобы изменить ссылки
// смена запроса
add_filter('request', 'true_smenit_request_3', 1, 1);
function true_smenit_request_3($query)
{
$taxonomia_name = 'service_category'; // укажите название таксономии здесь, это также могут быть рубрики 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_3', 10, 3);
function true_smena_permalink_3($url, $term, $taxonomy)
{
$taxonomia_name = 'service_category'; // название таксономии, тут всё понятно
$taxonomia_slug = 'service_category'; // ярлык таксономии - зависит от параметра 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;
}
add_filter('post_link', 'true_post_type_permalink2', 20, 3);
add_filter('post_type_link', 'true_post_type_permalink2', 20, 3);
function true_post_type_permalink2($permalink, $post_id, $leavename)
{
$post_type_name = 'service'; // название типа записи, вы можете найти его в админке или в функции register_post_type()
$post_type_slug = 'service'; // часть URL товаров, не всегда совпадает с названием типа записи!
$tax_name = 'service_category'; // ну это понятно, название таксономии - категории товаров
$post = get_post($post_id); // получаем объект поста по его ID
if (strpos($permalink, $post_type_slug) === FALSE || $post->post_type != $post_type_name) // не делаем никаких изменений, если тип записи не соответствует или если URL не содержит ярлык tovar
return $permalink;
$termini = wp_get_object_terms($post->ID, $tax_name); // получаем все категории, к которым принадлежит данный товар
if (!is_wp_error($termini) && !empty($termini) && is_object($termini[0])) // и делаем перезапись ссылки, только, если товар находится хотя бы в одной категории, иначе возвращаем ссылку по умолчанию
$permalink = str_replace($post_type_slug, $termini[0]->slug, $permalink);
return $permalink;
}
add_filter('request', 'true_post_type_request2', 1, 1);
function true_post_type_request2($query)
{
global $wpdb; // нам немного придётся поработать с БД
$post_type_name = 'service'; // указываем тут название типа записей товара
$tax_name = 'service_category'; // а также название таксономии - категории товаров
$yarlik = $query['attachment']; // после того, как мы изменили ссылки товаров в предыдущей функции, WordPress начал принимать их за страницы вложений
// а теперь давайте получим ID товара, ярлык которого соответствует запросу на странице
$post_id = $wpdb->get_var(
"
SELECT ID
FROM $wpdb->posts
WHERE post_name = '$yarlik'
AND post_type = '$post_type_name'
"
);
$termini = wp_get_object_terms($post_id, $tax_name); // товар должен находиться в категории (одной или нескольких)
if (isset($yarlik) && $post_id && !is_wp_error($termini) && !empty($termini)) : // изменяем запрос, если всё ок
unset($query['attachment']);
$query[$post_type_name] = $yarlik;
$query['post_type'] = $post_type_name;
$query['name'] = $yarlik;
endif;
return $query; // возвращаем результат
}