Как добавить префикс к URL пользовательского типа записи с термином таксономии пользовательской записи?

Вопрос или проблема

Для одного из моих 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 были такими:

(где, в идеале, в случае “одинаковых 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.

Оцените материал
Добавить комментарий

Капча загружается...