Использование register_post_type() для модификации существующего типа записей

13 сент. 2012 г., 19:12:15
Просмотры: 32.8K
Голосов: 39

Существует множество ситуаций, когда тема или плагин регистрирует тип записи, и вам нужно его изменить. Конечно, есть функции add_post_type_support() и remove_post_type_support(), но они не дают доступа ко всему списку аргументов, которые принимает register_post_type(). В частности, может потребоваться отключить архив типа записей, скрыть интерфейс администратора, скрыть из поиска и т.д., оставив при этом остальные настройки типа записей без изменений.

Страница Codex для register_post_type() дразнит нас следующим:

Описание

Создать или изменить тип записи.

Но когда я пытался сделать это раньше, казалось, что это не работает. Действительно ли эта функция предназначена для модификации типов записей, и если да, то можно ли просто переопределить несколько аргументов, оставив остальные без изменений?

Учитывая, что даже не существует функции deregister_post_type(), я не понимаю, как это можно сделать.

0
Все ответы на вопрос 6
7
57

После некоторых исследований я обнаружил, что ни один из этих ответов не актуален.

Начиная с 8 декабря 2015 года WordPress включает новый фильтр register_post_type_args, который позволяет вам изменять аргументы зарегистрированного типа записи.

function wp1482371_custom_post_type_args( $args, $post_type ) {
    if ( $post_type == "animal-species" ) {
        $args['rewrite'] = array(
            'slug' => 'animal' // ЧПУ для типа записи "animal-species"
        );
    }

    return $args;
}
add_filter( 'register_post_type_args', 'wp1482371_custom_post_type_args', 20, 2 );
21 июн. 2016 г. 01:32:19
Комментарии

Это правильный способ сделать это сейчас.

Dave Romsey Dave Romsey
16 сент. 2016 г. 02:47:46

Это должен быть принятый ответ

klewis klewis
18 нояб. 2016 г. 16:20:00

Что делать, если нужно обновить его после регистрации во время выполнения? Например: после init

Lucas Bustamante Lucas Bustamante
27 июн. 2019 г. 22:40:46

@LucasBustamante Это не имеет значения. Просто вызовите строку 'add_filter' в вашем плагине/теме, а не в экшене. Фильтр будет вызываться при каждой функции register_post_type. Единственный сценарий, когда мой код не сработает - это если тип записи регистрируется некорректно. Все типы записей должны регистрироваться во время хука init. Из кодекса: "register_post_type не будет работать, если вызван до 'init', и аспекты вновь созданного или изменённого типа записи будут работать некорректно, если вызваны позже." Если вам всё ещё нужна помощь, предлагаю опубликовать больше деталей в новом вопросе.

Radley Sustaire Radley Sustaire
28 июн. 2019 г. 05:57:14

то есть этот код изменит 'slug-of-post', как в 'sitename/projects/slug-of-post'??

Krys Krys
16 окт. 2020 г. 09:24:02

@Krys Не совсем понимаю вопрос, но для ясности: Если у вас есть "example.org/animal-species/slug-of-post", этот код позволяет изменить "animal-species" на просто "animal", так что URL станет "example.org/animal/slug-of-post", а архивная страница, если включена, будет "example.org/animal/". Без необходимости изменять название типа записи.

Radley Sustaire Radley Sustaire
16 окт. 2020 г. 20:51:58

Спасибо, что прояснили это

Krys Krys
18 окт. 2020 г. 10:54:44
Показать остальные 2 комментариев
3
21

Эта функция действительно предназначена для изменения типов записей?

Да.

И если да, можно ли просто переопределить несколько аргументов, оставив остальные без изменений?

Нет. Если вы хотите изменить аргументы типа записи, вам нужно использовать get_post_type_object для получения объекта типа записи, изменить нужные вам параметры в нем, а затем повторно зарегистрировать его, используя ваш измененный тип в качестве нового параметра $args.

13 сент. 2012 г. 21:59:55
Комментарии

Будет ли правильным делать два последовательных вызова с измененными аргументами для одной и той же функции register_post_type? Я предполагаю, что да, исходя из вашего "Да.", и это не вызывает ошибок, а дает желаемый эффект. Реальный случай - это второй вариант, который я привожу в этом ответе: http://wordpress.stackexchange.com/a/74331/12615

brasofilo brasofilo
29 нояб. 2012 г. 16:54:30

Да, это работает, но если вам приходится так делать, то, вероятно, нужно добавить какие-то фильтры или что-то еще, чтобы избежать необходимости повторно регистрировать один и тот же тип записи снова и снова. В идеале - сначала подготовить все аргументы, а затем зарегистрировать тип записи.

Otto Otto
29 нояб. 2012 г. 21:13:08

Я просто задумался об этом из-за хука, который выполняется прямо перед register_post_type в плагине. На самом деле, в этом нет необходимости. Это был вопрос "для протокола", спасибо за обратную связь.

brasofilo brasofilo
29 нояб. 2012 г. 21:22:44
1

Вот пример использования фильтра 'registered_post_type' для изменения типа записи в другом плагине.

Плагин, который я использовал, не включал menu_icon в своём определении, поэтому я решил добавить свою иконку.

<?php
/**
 * Добавляем иконку меню для пользовательского типа записи WP-VeriteCo Timeline
 *
 * Плагин таймлайна не имеет иконки меню, поэтому мы подключаемся к 'registered_post_type'
 * и добавляем свою.
 *
 * @param  string $post_type название типа записи
 * @param  object $args аргументы типа записи
 */
function wpse_65075_modify_timeline_menu_icon( $post_type, $args ) {
    // Убедимся, что редактируем только нужный тип записи
    if ( 'timeline' != $post_type )
        return;

    // Устанавливаем иконку меню
    $args->menu_icon = get_stylesheet_directory_uri() . '/img/admin/menu-timeline.png';

    // Модифицируем объект типа записи
    global $wp_post_types;
    $wp_post_types[$post_type] = $args;
}
add_action( 'registered_post_type', 'wpse_65075_modify_timeline_menu_icon', 10, 2 );
24 авг. 2013 г. 02:49:20
Комментарии

Это гораздо более чистый способ в большинстве случаев; однако следует отметить, что этот фильтр срабатывает слишком поздно для обработки перезаписями, поэтому в таких ситуациях необходимо использовать принятый ответ.

mrwweb mrwweb
18 мар. 2015 г. 00:44:16
2

Подключитесь к хуку 'registered_post_type' после того, как другой код зарегистрирует его. Этот хук вызывается в конце функции register_post_type(). Вы получаете два аргумента: $post_type и $args.
Теперь вы можете изменить любые параметры для этого типа записи. Проверьте $GLOBALS['wp_post_types'] для просмотра доступных опций.

13 сент. 2012 г. 19:19:08
Комментарии

Спасибо, что направили меня к этому хуку. Это отвечает на (более важный) вопрос о том, как изменить тип записи, но что насчёт описания register_post_type(), где упоминается "модификация"? Это просто ошибка? Мне стоит оседлать своего интернет-коня и немедленно изгнать это из Кодекса?

mrwweb mrwweb
13 сент. 2012 г. 19:32:41

$wp_post_types[$post_type] = $args; … говорит о том, что вы должны иметь возможность изменять свойства. Добавьте пример проблемного кода к вашему вопросу.

fuxia fuxia
13 сент. 2012 г. 19:36:45
1

Я столкнулся с такой же проблемой в плагине The Events Calendar.

Я добавил следующий код в function.php, чтобы изменить тип записи tribe_organizer:

function tribe_modify_organizer() {
 //Новые аргументы
    $tribe_organizer_args = get_post_type_object('tribe_organizer'); // получаем тип записи для изменения
    $tribe_organizer_args-> taxonomies = array('post_tag' , 'tribe_events_cat'); // добавляем поддержку таксономий
    $tribe_organizer_args-> exclude_from_search = false; // показывать в результатах поиска
 //перерегистрируем тот же тип записи с новыми аргументами
    register_post_type( 'tribe_organizer', $tribe_organizer_args );
}
add_action( 'init', 'tribe_modify_organizer', 100 );
12 февр. 2017 г. 22:26:01
Комментарии

Отличный пример, спасибо!

Philipp Philipp
25 авг. 2020 г. 14:25:59
0

Не знаю, насколько это коряво, но вы можете изменять глобальный плейсхолдер GLOBAL "на лету", когда вам нужно манипулировать одним аргументом. Вот как мы используем непубличный тип записи contents, чтобы он был доступен в админ-меню. Мы добавляем хуки непосредственно перед и после отрисовки меню:

function entex_theme_make_contents_public(){
    $GLOBALS['wp_post_types']['contents']->public = true;
}
add_action('admin_menu', 'entex_theme_make_contents_public', 10);

function entex_theme_make_contents_private_again(){
    $GLOBALS['wp_post_types']['contents']->public = '';
}
add_action('admin_menu', 'entex_theme_make_contents_private_again', 12);

В нашем случае мы хотим, чтобы плагин Admin Menu Post List принимал наш тип записи, так как он вызывает return get_post_types(array('public' => true)); внутри своего хука с приоритетом 11...

Разработчики - пожалуйста, оставьте комментарий, если это может вызвать какие-либо проблемы.

19 сент. 2018 г. 01:42:00