Пермалинки: пользовательский тип записи -> пользовательская таксономия -> запись
У меня возникли трудности с правилами перезаписи WordPress и мне нужна помощь.
У меня есть пользовательский тип записи под названием _shows_
.
Все шоу имеют одну пользовательскую таксономию категории _show-category_
. У _show_
никогда не будет более одной _show-category_
.
Я хотел бы, чтобы мои URL маршрутизировались следующим образом:
www.mysite.com/shows/ => archive-shows.php
www.mysite.com/shows/%category%/ => taxonomy-show-category.php
www.mysite.com/shows/%category%/%postname%/ => single-shows.php
Итак, в качестве реального примера, допустим, у нас есть _show-category_
"Foo" и запись _show_
с названием "Bar", которая имеет "Foo" в качестве своей _show-category_
. Я ожидаю, что мое приложение WordPress будет выглядеть так:
www.mysite.com/shows/foo/ => показывает все записи в категории foo
www.mysite.com/shows/foo/bar => показывает отдельную запись
Я стараюсь по возможности избегать плагинов, но открыт для любого решения.
Сначала зарегистрируйте свою таксономию и установите аргумент slug
в rewrite
как shows
:
register_taxonomy(
'show_category',
'show',
array(
'rewrite' => array( 'slug' => 'shows', 'with_front' => false ),
// другие ваши аргументы...
)
);
Затем зарегистрируйте свой тип записи и установите slug как shows/%show_category%
, а также установите аргумент has_archive
в shows
:
register_post_type(
'show',
array(
'rewrite' => array( 'slug' => 'shows/%show_category%', 'with_front' => false ),
'has_archive' => 'shows',
// другие ваши аргументы...
)
);
Наконец, добавьте фильтр к post_type_link
, чтобы подставлять категорию шоу в постоянных ссылках отдельных шоу:
function wpa_show_permalinks( $post_link, $post ){
if ( is_object( $post ) && $post->post_type == 'show' ){
$terms = wp_get_object_terms( $post->ID, 'show_category' );
if( $terms ){
return str_replace( '%show_category%' , $terms[0]->slug , $post_link );
}
}
return $post_link;
}
add_filter( 'post_type_link', 'wpa_show_permalinks', 1, 2 );
РЕДАКТИРОВАНИЕ
Забыл указать аргумент has_archive
в register_post_type
выше, он должен быть установлен в shows
.

Мило, спасибо! Фильтр post_type_link был тем недостающим элементом, который я искал. Всем, кто читает эту ветку с такой же проблемой: обратите внимание, что в функции wpa_show_permalinks есть небольшая ошибка - вместо $post->post_type == 'show' должно быть 'shows'. Еще раз спасибо, Мило!

Спасибо, Мило! Это решило мою проблему. Я пытался достичь похожего результата с помощью этого плагина, но переписанные URL выдавали 404 ошибку. Видимо, ручное решение было правильным путем.

@milo, переходя с http://wordpress.stackexchange.com/questions/199456/custom-taxonomy-post-slug-permalink, я постоянно получаю 404
с этим подходом. Моя структура постоянных ссылок: %category%/%postname%

Если вы вносите изменения в существующий экземпляр WordPress, обязательно перейдите в Настройки > Постоянные ссылки и нажмите "Сохранить". Изменения, которые вы внесли в functions.php, не вступят в силу, пока вы этого не сделаете.

Это почти сработало у меня: таксономия отображается на странице типа записи, страница /post_type/taxonomy/ работает (ранее выдавала 404), но моя страница /post_type/taxonomy/post возвращает 404. Я заметил, что при регистрации таксономии выше регистрировались и "show_category", и "show", хотя только show_category является таксономией. Я регистрирую только таксономию.

@Milo есть ли способ заставить это работать с подподтаксономией типа shows/tax/subtax/post ?

Мне тоже было бы интересно узнать, как заставить это работать с дочерними таксономиями, например /shows/tax/subtax/postname

Это действительно ценный прием, спасибо. Однако есть небольшая проблема: при использовании 'post_type_link' кнопка изменения/редактирования в админке на странице редактирования записи исчезает. Это означает, что slug записи станет неизменяемым, и если вы позже измените post_title, вы не сможете отразить это изменение в slug.

Как (внутренне) 'shows/%show_category%' автоматически преобразуется в правильную таксономию/термин? Мне просто интересно. Официальная документация register_post_type не объясняет этого и не дает никакой информации, создавая впечатление, что мы можем передавать только обычные строки вместо полных структур постоянных ссылок. Также я не могу найти никакой документации о автоматическом создании тегов структуры постоянных ссылок при создании таксономии.

@Stratboy Мне нужно попробовать еще раз, я не помню, чтобы в этом случае slug записи нельзя было редактировать. Я знаю, что в более сложных структурах мне приходилось использовать add_permastruct
вместо этого. WP ничего не делает с %show_category%
в данном случае, это просто заполнитель, который вам нужно заменить самостоятельно в фильтре post_type_link
. На самом деле это может быть любой допустимый тег rewrite, например, если вы хотите использовать произвольное поле или что-то еще в URL.

На самом деле, если вы посмотрите на $wp_rewrite сразу после регистрации типов записей, но до фильтра post_type_link
, вы заметите, что тег %show_category% был сгенерирован, так же как и связанные с ним permastructures. Так что это странно, они существуют, поэтому распознаются, но, вероятно, WordPress не знает, как их обрабатывать.

@stratboy show_category должен быть допустимым тегом rewrite, что и есть, потому что он был добавлен как часть регистрации таксономии, но это также может быть просто тег, добавленный через add_rewrite_tag. За кулисами это делает то же самое.

Что делать, если вам нужен разный slug на разных языках? (например, WPML). И если у некоторых записей не задана категория, будет ли у них просто /shows/название-записи? Спасибо!

В случае с WPML это работает для языка по умолчанию, но, к сожалению, не для других

Мне так хотелось, чтобы это сработало и у меня, но каждая отдельная запись заканчивается ошибкой 404....

К сожалению, у меня тоже получаются только 404 ошибки... даже после обновления постоянных ссылок.

WordPress 5.2.4 и WordPress 5.3 также приводили к 404 ошибкам с этим решением. Я создал вопрос на форуме поддержки WP, спрашивая, может ли кто-то поделиться знаниями о том, что изменилось в механизме перезаписи за последние годы, что могло сломать эту возможность.
Сейчас я использую плагин для управления структурой постоянных ссылок, и похоже, что этот плагин выполняет некоторый парсинг wp_query, чтобы ссылки работали корректно.

У меня была такая же проблема с 404 ошибками на страницах отдельных постов шоу, как и у других пользователей, но мне удалось обойти её, добавив add_rewrite_rule( 'shows/([^/]+)/([^/]+)', 'index.php?show =$matches[2]', 'top' );
в functions.php. Это правило будет сопоставлять вторую часть слага после 'show' с именем поста шоу.

Решение Мило почти работает. К сожалению, тип записи теряется, и вместо пользовательского типа записи (CPT) используется шаблон по умолчанию.

Это почти сработало у меня – главная страница типа записи и страницы категорий работали нормально, но возникала проблема с отдельными записями! (WordPress считал запись подкатегорией и возвращал ошибку 404.) Недостающим шагом был фильтр rewrite_rules_array
, как описано здесь: https://stackoverflow.com/a/23702560/915762

Есть один минус – нельзя использовать одинаковые слаги для разных таксономий. Например, /post-type/taxonomy-1/seo-agency/
и /post-type/taxonomy-2/seo-agency/
не будут работать одновременно.

@Sarah О БОЖЕ, ты мой СПАСИТЕЛЬ! Теперь это работает, наконец-то, О МОЙ БОГ! Спасибо тебе огромное! У меня был очень похожий кейс: у меня был тип записи "resource" с таксономией "resource_category". Страницы таксономии работали, архив работал, но одиночные записи — нет. Сработало это: add_rewrite_rule( '^resources/([^/]+)/([^/]+)', 'index.php?resource=$matches[2]', 'top' );
