Вопрос или проблема
Для одного из моих CPT, когда стандартная постоянная ссылка выглядит так:
example.com/CPT_slug/%postname%
вместо этого я хотел бы, чтобы постоянная ссылка выглядела так:
example.com/%custom_taxonomy_term%/CPT_slug/%postname%
С обычными категориями и записями это легко сделать, мне просто нужно использовать %category%/%postname% для постоянных ссылок.
Но я не могу понять, как добиться этого для CPT и пользовательских таксономий. Где я ошибаюсь?
Мой slug CPT – “activity”, со записями типа: “Food tour”, “Dinner cruise”, …
Мой slug пользовательской таксономии – “agence”, с терминами типа “New York”, “Miami”, …
Так что я хотел бы, чтобы мои URL были такими:
- https://www.example.com/new-york/activity/food-tour
- https://www.example.com/new-york/activity/dinner-cruise
- https://www.example.com/miami/activity/food-tour (другая запись, отличная от первой)
(где, в идеале, в случае “одинаковых slug” ситуации, было бы произведено различение)
Я пробовал такой подход:
"rewrite" => array( "slug" => "%agence%/activity", "with_front" => false ),
в register_post_type
и
function add_agence_prefix_in_activity_url( $post_link, $id = 0 ) {
$post = get_post( $id );
if ( is_object( $post ) && get_post_type($post) == 'activity' )
{
$terms = wp_get_object_terms( $post->ID, 'agence' );
if ( $terms ) {
return str_replace( '%agence%', $terms[0]->slug, $post_link );
}
}
return $post_link;
}
add_filter( 'post_type_link', 'add_agence_prefix_in_activity_url', 1, 3 );
Это работает: это позволяет мне отображать содержимое моей записи “activity”.
Но я получаю ошибки 404, когда пытаюсь отобразить записи и страницы с их обычными /%postname% постоянными ссылками; и я не знаю, что делать, чтобы это исправить.
Поэтому вместо этого я попробовал использовать плагин “Custom Post Type Permalinks”:
он почти работает: страницы и записи больше не сломаны, и он дает мне URL такие как:
https://www.example.com/activity/**new-york**/food-tour
… в то время как я хотел бы:
https://www.example.com/**new-york**/activity/food-tour
Так что я почти у цели, но не совсем.
Как мне поступить? То, что я пытаюсь сделать, вообще возможно?
Хорошо, я нашел (одно?) решение.
"rewrite" => array( "slug" => "activity", "with_front" => false ),
и
function my_injecter_agence_in_activite_url( $post_link, $id = 0 ) {
$post = get_post( $id );
if ( $post->post_type == 'activity' || 'publish' == $post->post_status )
{
$terms = wp_get_object_terms( $post->ID, 'agence' );
if ( $terms )
{
$post_link = str_replace("activity", $terms[0]->slug.'/activite', $post_link);
return $post_link;
}
}
return $post_link;
}
add_filter( 'post_type_link', 'my_injecter_agence_in_activite_url', 1, 3 );
function my_rewrite_rules()
{
add_rewrite_rule(
'(.*)\/activity\/(.*)?$',
'index.php?post_type=activity&name=$matches[2]',
'top'
);
}
add_action( 'init', 'my_rewrite_rules' );
Я был довольно близок. Я думаю, что была проблема с моим первоначальным str_replace.
Теперь ни записи, ни страницы, ни активности не сломаны, все кажется в порядке.
Пользовательский термин таксономии, используемый в качестве префикса в URL, является чисто косметическим, и у меня нет различения, если две активности имеют одинаковый slug, но я думаю, что это не должно происходить, так как WP не позволит мне иметь две записи с двумя идентичными slug.
Теперь мне просто нужно найти способ убедиться, что я получаю ошибку 404, если ищу активность в неправильном термине (например, если пытаюсь достичь example.com/new-york/activity/bike-tour-in-miami)
Если кто-то знает лучший способ сделать это, пожалуйста, дайте мне знать.
Ответ или решение
Чтобы создать префикс для пользовательского типа записей (CPT) с учётом термина пользовательской таксономии в URL, необходимо следовать определённой последовательности шагов. Рассмотрим их более подробно:
1. Регистрация пользовательского типа записей и таксономии
Сначала убедитесь, что ваш пользовательский тип записей (activity
) и таксономия (agence
) зарегистрированы с помощью функций register_post_type
и register_taxonomy
. При регистрации нужно указать параметры rewrite
.
Примерный код для регистрации пользовательского типа записей:
function create_activity_post_type() {
register_post_type('activity',
array(
'labels' => array(
'name' => __('Activities'),
'singular_name' => __('Activity'),
),
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'activity', 'with_front' => false),
// Другие параметры
)
);
}
add_action('init', 'create_activity_post_type');
function create_agence_taxonomy() {
register_taxonomy('agence', 'activity', array(
'labels' => array(
'name' => __('Agences'),
'singular_name' => __('Agence'),
),
'public' => true,
'rewrite' => array('slug' => 'agence', 'with_front' => false),
));
}
add_action('init', 'create_agence_taxonomy');
2. Изменение структуры URL
Для изменения структуры URL используйте фильтр post_type_link
. Этот фильтр позволяет модифицировать ссылки на единицы вашего пользовательского типа записей.
Пример функции для обновления ссылок:
function add_agence_prefix_in_activity_url($post_link, $id = 0) {
$post = get_post($id);
if (is_object($post) && get_post_type($post) == 'activity') {
$terms = wp_get_object_terms($post->ID, 'agence');
if ($terms) {
return str_replace('activity', $terms[0]->slug.'/activity', $post_link);
}
}
return $post_link;
}
add_filter('post_type_link', 'add_agence_prefix_in_activity_url', 1, 3);
3. Добавление правил перезаписи
После того как вы изменили ссылки, нужно добавить новое правило перезаписи, чтобы WordPress знал, как обрабатывать новые URL. Это достигается с помощью функции add_rewrite_rule
.
Пример добавления правила перезаписи:
function my_rewrite_rules() {
add_rewrite_rule(
'(.*)/activity/(.+)$',
'index.php?post_type=activity&name=$matches[2]',
'top'
);
}
add_action('init', 'my_rewrite_rules');
4. Обновление постоянных ссылок
Не забудьте после внесения изменений обновить постоянные ссылки. Это можно сделать в админке WordPress: перейдите в Настройки → Постоянные ссылки и просто нажмите «Сохранить изменения». Это заставит WordPress пересоздать правила перезаписи.
5. Обработка ошибок 404 и дублирования
Чтобы убедиться, что ссылки не приводят к ошибкам 404, вы можете использовать дополнительные проверки в вашей функции. Например, проверьте, существует ли активность с данной комбинацией термина таксономии и slug’ом.
Примерный код:
function custom_404_check($query) {
if ($query->is_post_type_archive('activity')) {
// Логика проверки существования активности и соответствия терминам
}
}
add_action('pre_get_posts', 'custom_404_check');
Эти шаги помогут вам создать URL вашего пользовательского типа записей с префиксом термина таксономии без ошибок 404, а также предотвратят дублирование.
Заключение
Следуя приведённым шагам, вы сможете настроить URL для вашего пользовательского типа записей, используя термин таксономии в качестве префикса. Надеюсь, эта информация была полезной для вас, и поможет реализовать необходимые свойства URL в вашем проекте WordPress.