Redeclare / Change Slug пользовательского типа поста плагина

28

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

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

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

Ответы:

24

Да, это возможно, но если плагин создает пользовательский тип записи, используя 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' => __('Movies'),
                'singular_name' => __('Movie')
            ),
            '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() {

    // First, try to load up the rewrite rules. We do this just in case
    // the default permalink structure is being used.
    if( ($current_rules = get_option('rewrite_rules')) ) {

        // Next, iterate through each custom rule adding a new rule
        // that replaces 'movies' with 'films' and give it a higher
        // priority than the existing rule.
        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

    // ...and we flush the rules
    flush_rewrite_rules();

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

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

  • /movies/Back-To-The-Future
  • /films/Back-To-The-Future

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

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

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

Том
источник
Работал красиво! Не могли бы вы также указать мне правильное направление для обновления постоянных ссылок?
Эдбери
1
В зависимости от вашей темы, вы можете сделать это на уровне шаблона. Когда вы видите вызов «the_title ()», вы можете заменить его на $ title = get_the_title (), а затем заменить строку «/ movies /» в $ title на «/ films /».
Том
Что если слаг, на которого вы хотите изменить, динамически создается мета-значением текущего поста? Мне нужно иметь возможность использовать $postэту add_custom_rewrite_rule()функцию, но она выдает ошибки в WP Admin, говорящие «Попытка получить свойство не-объекта». Как я могу получить $ post, чтобы получить мета-значение?
Ли
6

Этот код хорошо работал для моей детской темы. Нужно поменять «программный» слаг на «место».

/*
CHANGE SLUGS OF CUSTOM POST TYPES
*/

function change_post_types_slug( $args, $post_type ) {

   /*item post type slug*/   
   if ( 'program' === $post_type ) {
      $args['rewrite']['slug'] = 'place';
   }

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

/*
CHANGE SLUGS OF TAXONOMIES, slugs used for archive pages
*/

function change_taxonomies_slug( $args, $taxonomy ) {

   /*item category*/
   if ( 'program-category' === $taxonomy ) {
      $args['rewrite']['slug'] = 'locations';
   }

   return $args;
}
add_filter( 'register_taxonomy_args', 'change_taxonomies_slug', 10, 2 );
Iggy
источник
Он работает отлично, я также использовал его для тегов, добавляющих относительное правило, необходимо обновить постоянные ссылки, выполнив сохранение на странице настроек> постоянная ссылка. Спасибо!
Лоренцо Магон
Прекрасно работает, чтобы изменить другие аргументы, мне нужно было установить, $args['has_archive'] = falseи это сработало.
Простое развитие