Переопределение/Изменение ЧПУ (slug) Пользовательского Типа Записи Плагина

11 февр. 2012 г., 18:03:50
Просмотры: 69.5K
Голосов: 32

Возможно ли переопределить/изменить ЧПУ (slug) существующего пользовательского типа записи плагина (без прямого редактирования плагина)?

То есть, если Плагин X создает пользовательский тип записи с ЧПУ /uncookedtoast/, возможно ли добавить фильтр в functions.php (или что-то подобное), чтобы изменить ЧПУ на /bread/?

1
Комментарии

Я только что решил эту же проблему, добавив хук на init с приоритетом 20 и повторно вызвав register_post_type для того же типа записи. Кто-нибудь знает, может ли это вызвать проблемы в будущем?

Dustin Dustin
12 апр. 2013 г. 05:48:23
Все ответы на вопрос 4
4
32

Да, это возможно, но если плагин создает пользовательский тип записи с использованием параметра rewrite => array('slug' => 'post_type'), то маловероятно, что вы сможете заменить слаг.

При создании пользовательских типов записей правила перезаписи URL сохраняются в базе данных. В зависимости от действия, которое инициирует создание типа записи (например, действие init), WordPress сбросит правила перезаписи и восстановит слаги пользовательских типов записей, независимо от внесенных изменений.

Тем не менее, вы можете задать собственные слаги для пользовательских типов записей. В следующем примере предполагается, что у вас есть пользовательский тип записи movies, и вы пытаетесь изменить слаг /movies/ на /films/.

Для полноты картины, вот базовая функция для определения пользовательского типа записи movies. Плагин, на который вы ссылаетесь, должен делать что-то подобное:

function movies_register_post_type() {

    register_post_type(
        'movies',
        array(
            'labels' => array(
                'name' => __('Фильмы'),
                'singular_name' => __('Фильм')
            ),
            'public' => true,
            'has_archive' => true,
            'rewrite' => array(
                'slug' => 'movies'
            )
        )
    );

} // end example_register_post_type
add_action('init', 'movies_register_post_type');

Вы можете изменить таблицу опций, добавив собственные правила на основе существующего типа записи.

Вкратце, мы сделаем следующее:

  • Возьмем существующие правила и создадим новые с собственными слагами
  • Присвоим новому правилу более высокий приоритет, чем слагу пользовательского типа записи

Вот как это можно реализовать:

function add_custom_rewrite_rule() {

    // Сначала попытаемся загрузить правила перезаписи на случай,
    // если используется структура постоянных ссылок по умолчанию.
    if( ($current_rules = get_option('rewrite_rules')) ) {

        // Затем пройдемся по каждому пользовательскому правилу, добавляя новое правило,
        // которое заменяет 'movies' на 'films' с более высоким приоритетом,
        // чем у существующего правила.
        foreach($current_rules as $key => $val) {
            if(strpos($key, 'movies') !== false) {
                add_rewrite_rule(str_ireplace('movies', 'films', $key), $val, 'top');   
            } // end if
        } // end foreach

    } // end if/else

    // ...и сбрасываем правила
    flush_rewrite_rules();

} // end add_custom_rewrite_rule
add_action('init', 'add_custom_rewrite_rule');

Теперь у вас будет два способа доступа к фильмам:

  • /movies/Назад-в-будущее
  • /films/Назад-в-будущее

Обратите внимание, что я не рекомендую подключать функцию add_custom_rewrite_rule к действию init, так как оно срабатывает слишком часто. Это лишь пример. Лучше использовать активацию темы, активацию плагина, действие save_post и т.д. В зависимости от задачи, функцию может потребоваться вызвать один раз или несколько.

На этом этапе вы можете обновить постоянные ссылки для пользовательского типа записи, чтобы использовать слаг /movies/. Например, если перейти по адресу /films/, вы увидите список всех фильмов, но при наведении на заголовок станет видно, что по-прежнему используется слаг /movies/.

Для дальнейшей доработки можно реализовать 301 редирект, чтобы все ссылки на /movies/ перенаправлялись на соответствующие /films/, но это зависит от ваших целей.

13 февр. 2012 г. 16:40:49
Комментарии

Отлично сработало! Не могли бы вы также подсказать, как правильно обновить постоянные ссылки?

Edbury Edbury
13 февр. 2012 г. 22:23:38

В зависимости от вашей темы, это можно сделать на уровне шаблона. Когда вы видите вызов 'the_title()', вы можете заменить его на $title = get_the_title(), а затем заменить '/movies/' в $title на '/films/'.

Tom Tom
14 февр. 2012 г. 15:16:06

Что делать, если новый ярлык (slug) должен динамически создаваться из мета-значения текущей записи? Мне нужно использовать $post в функции add_custom_rewrite_rule(), но в админке WordPress выдается ошибка 'Trying to get property of non-object'. Как правильно получить доступ к $post, чтобы получить мета-значение?

Lee Lee
17 янв. 2018 г. 18:15:37

Это сработало отлично. Спасибо за публикацию!!

Student22 Student22
22 февр. 2024 г. 10:22:14
3
15

Этот код отлично сработал для моей дочерней темы. Нужно было изменить слаг "program" на "place".

/*
ИЗМЕНЕНИЕ СЛАГОВ ПРОИЗВОЛЬНЫХ ТИПОВ ЗАПИСЕЙ
*/

function change_post_types_slug( $args, $post_type ) {

   /*слаг типа записи item*/   
   if ( 'program' === $post_type ) {
      $args['rewrite']['slug'] = 'place';
   }

   return $args;
}
add_filter( 'register_post_type_args', 'change_post_types_slug', 10, 2 );

/*
ИЗМЕНЕНИЕ СЛАГОВ ТАКСОНОМИЙ, слаги используются для архивных страниц
*/

function change_taxonomies_slug( $args, $taxonomy ) {

   /*категория item*/
   if ( 'program-category' === $taxonomy ) {
      $args['rewrite']['slug'] = 'locations';
   }

   return $args;
}
add_filter( 'register_taxonomy_args', 'change_taxonomies_slug', 10, 2 );
23 дек. 2017 г. 22:29:38
Комментарии

Работает идеально, я также использовал это для тегов, добавив соответствующее правило. Необходимо обновить постоянные ссылки, выполнив сохранение на странице настроек > постоянные ссылки. Спасибо!

Lorenzo Magon Lorenzo Magon
19 окт. 2018 г. 21:17:46

Отлично работает для изменения других аргументов. Мне нужно было установить $args['has_archive'] = false, и это сработало.

Mere Development Mere Development
8 февр. 2019 г. 18:35:48

Что если я хочу изменить постоянную ссылку записи, а не ярлык типа записи, например: themename/projects/ярлык-записи ??

Krys Krys
15 окт. 2020 г. 12:05:18
0

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

Что я сделал — перерегистрировал (своего рода перезапись функции регистрации плагина) произвольный тип записи, добавив следующий код в файл functions.php дочерней темы:

function my-theme-name_post_type_my-custom-post-type-name()
{
   $labels = array(
      ...
   );

   $args = array(
      ...

      'rewrite' => array(
         'slug' => __('the-slug-of-your-choise', 'the-textdomain-of-your-choise-for-translation-if-needed'),
      ),
   );
   register_post_type('the-custom-post-type-name-registered-by-the-plugin', $args);
}
add_action('init', 'my-theme-name_post_type_my-custom-post-type-name');

Как видите, вы можете изменить ярлык (slug), просто добавив следующее в массив $args:

'rewrite' => array(
    'slug' => __('the-slug-of-your-choise', 'the-textdomain-of-your-choise-for-translation-if-needed'),
)

Подробнее об этом можно узнать здесь: https://developer.wordpress.org/reference/functions/register_post_type/

ОЧЕНЬ ВАЖНО

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

14 февр. 2021 г. 17:28:23
0
function change_portfolio_slug() {
    $args = get_post_type_object( 'portfolio' );
    if ( ! empty( $args ) ) {
        $args->rewrite['slug'] = 'project';
        register_post_type( 'portfolio', $args );
    }
}
add_action( 'init', 'change_portfolio_slug', 20 );

В моём случае плагин объявляет пользовательский тип записи "portfolio" с параметром 'rewrite' => array( 'slug' => 'portfolio'), используя хук для действия 'init': add_action( 'init', 'some_plugin_custom_posts_init' );.

Приведённый выше фрагмент кода, размещённый в файле functions.php темы, определяет новую функцию change_portfolio_slug(), которая изменяет параметр rewrite для типа записи portfolio, меняя его ярлык (slug) на "project". Затем мы используем функцию register_post_type() для регистрации типа записи с изменёнными параметрами.

Функция add_action() подключает функцию change_portfolio_slug() к действию init, чтобы она выполнялась при инициализации WordPress.

В последней строке фрагмента add_action( 'init', 'change_portfolio_slug', 10 ); число 10 обозначает приоритет хука. Если вам нужно изменить приоритет, вы можете заменить 10 на другое число. В моём случае рабочим приоритетом оказалось 20.

Обратите внимание, что после внесения этих изменений вам может потребоваться обновить постоянные ссылки, чтобы новая структура URL применилась корректно. Это можно сделать в разделе Настройки → Постоянные ссылки в админ-панели WordPress, нажав кнопку "Сохранить изменения".

10 мар. 2023 г. 17:04:18