Удаляем slug для произвольного типа записей из URL

Рассмотрим удаление slug для произвольного типа записей. Предположим, нам необходимо создать произвольный тип записей «Products» (товары) для нашего сайта. Публикуемые материалы этого типа будут доступны по адресу site.ru/products/product_name (Где «products» — slug произвольного типа, а «product_name» — slug отдельной записи данного типа).

При этом, в настройках постоянных ссылок (Permalinks) указан параметр /%postname%/

Возникает необходимость избавиться от параметра произвольного типа в адресе (URL) таким образом, чтобы все товары были доступны по адресу site.ru/product_name

Для создания произвольного типа записей (Custom Post Type) в WordPress используем следующий код (пишем его в файле functions.php нашей текущей темы):

[sourcecode language=»php»]$args = array(
‘description’ => ‘Товары нашего магазина’,
‘label’ => ‘Товары’,
‘public’ => true,
‘rewrite’ => array( ‘slug’ => ‘products’),
);
register_post_type( ‘products’ , $args );
[/sourcecode]

Мы создали произвольный тип данных «Товары» с параметром slug = ‘products’.

Опубликуем запись данного типа, если все сделано верно — пост будет доступен по адресу site.ru/products/product_name

Теперь добавим фильтр, который удалит slug типа записи из адреса URL:

Читайте также:  Удаляем ненужные теги из блока head

[sourcecode language=»php»]function remove_slug( $post_link, $post, $leavename ) {
if ( ‘products’ != $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’, ‘remove_slug’, 10, 3 );
[/sourcecode]

Как видите, мы просто заменили slug на пустое значение при помощи функции str_replace()

Однако, сейчас, при попытке обращения к адресу site.ru/product_name мы получим код 404, т.к. WordPress не рассматривает product_name как запись типа «products«.

Осталось прописать несколько строк кода…

[sourcecode language=»php»]function parse_request( $query ) {
if ( ! $query->is_main_query() )
return;

if ( 2 != count( $query->query ) || ! isset( $query->query[‘page’] ) ) {
return;
}

if ( ! empty( $query->query[‘name’] ) ) {
$query->set( ‘post_type’, array( ‘post’, ‘products’, ‘page’ ) );
}
}
add_action( ‘pre_get_posts’, ‘parse_request’ );[/sourcecode]

Теперь наши записи произвольного типа «Products» (товары) доступны по адресу site.ru/product_name (т.е. без указания типа в URL)

Вам может быть интересно:

  • Satico

    Артур, я месяц искала решение этой проблемы, но по другим поисковым фразам и даже решила отказаться от проивзольных типов записей, а тут набрала в Гугле «slug адрес» совершенно по другому вопросу и увидела заголовок вашей записи. Огромное спасибо за решение этой проблемы!

  • Денис

    Как сделать для нескольких произвольных записей?

  • SemyonAstakhov

    И тут же появляется баг — при условии, что не проверяется уникальность слага для разных типов записей у нас появляется ситуация, что будут в наличии 2 страницы доступные по 1 адресу. Что в итоге будет не понятно…

  • Стас

    Здравствуйте, ссылки поменялись.. Но выдает 404 ошибку. А страницы доступны по старому url

  • Виталий Каракушан

    Cпасибо. Всё отлично работает! Нужно только поменять название типа записи на собственный в двух функциях! Ещё бы подсказали как убрать слаг таксономии из ссылки было б бесподобно.