Użyj register_post_type (), aby zmodyfikować istniejący typ postu


29

Istnieje wiele sytuacji, w których motyw lub wtyczka rejestruje typ postu i chcesz go zmodyfikować. Jest oczywiście add_post_type_support()i remove_post_type_support(), ale nie dają one dostępu do pełnej listy argumentów, które trzeba wziąć register_post_type(). W szczególności może chcę wyłączyć archiwum typu posta, ukryć interfejs administratora, ukryć przed wyszukiwaniem itp., Pozostawiając resztę ustawień typu postu w spokoju.

Strona Kodeksu dlaregister_post_type() wiszących przede mną:

Opis

Utwórz lub zmodyfikuj typ postu.

Ale w przeszłości, kiedy próbowałem to zrobić, wydawało się, że to nie działa. Czy ta funkcja naprawdę służy do modyfikowania typów postów, a jeśli tak, to czy możesz po prostu zmienić kilka argumentów i zostawić resztę w spokoju?

Widząc, że nie ma nawet deregister_post_type()funkcji , nie rozumiem, jak można to zrobić.

Odpowiedzi:


18

Czy ta funkcja naprawdę służy do modyfikowania typów postów

Tak.

a jeśli tak, to czy możesz po prostu zmienić kilka argumentów i zostawić resztę w spokoju?

Nie. Jeśli chcesz zmodyfikować argumenty na typ postu, musisz użyć, get_post_type_objectaby uzyskać obiekt typu post, zmodyfikować, co chcesz w nim, a następnie ponownie zarejestrować, używając zmodyfikowanego typu jako nowego parametru $ args.


Czy register_post_typepoprawne byłoby wykonanie dwóch kolejnych wywołań ze zmodyfikowanymi argumentami ? Przyjmuję to przez twoje „tak”, i nie zrzuca żadnych błędów i ma pożądany efekt. Prawdziwy przypadek to druga opcja, którą przedstawiam w tej odpowiedzi: wordpress.stackexchange.com/a/74331/12615
brasofilo

Tak, to działa, ale wydaje się, że jeśli musisz to zrobić, musisz dodać jakieś filtry lub coś innego, aby uniknąć konieczności wielokrotnego rejestrowania tego samego typu postu w kółko. Zasadniczo najpierw posortuj argumenty, a następnie zarejestruj je.
Otto,

Właśnie o tym pomyślałem z powodu haka dostarczonego tuż przed wtyczką register_post_type. W rzeczywistości nie ma takiej potrzeby. To było pytanie „do akt”, dzięki za opinie.
brasofilo

34

Po kilku badaniach okazało się, że żadna z tych odpowiedzi nie jest aktualna.

Według stanu na 8 grudnia 2015 r. WordPress zawiera nowy filtr register_post_type_args, który pozwala zapoznać się z argumentami zarejestrowanego typu posta.

function wp1482371_custom_post_type_args( $args, $post_type ) {
    if ( $post_type == "animal-species" ) {
        $args['rewrite'] = array(
            'slug' => 'animal'
        );
    }

    return $args;
}
add_filter( 'register_post_type_args', 'wp1482371_custom_post_type_args', 20, 2 );

6
To jest właściwy sposób, aby to zrobić teraz.
Dave Romsey

6
To powinna być zaakceptowana odpowiedź
klewis

Co zrobić, jeśli musisz go zaktualizować po zarejestrowaniu w środowisku wykonawczym? Np .: poinit
Lucas Bustamante

@LucasBustamante To nie ma znaczenia. Wystarczy wywołać wiersz „add_filter” podczas wtyczki / motywu, a nie w akcji. Filtr będzie wywoływany podczas każdej register_post_typefunkcji. Jedynym scenariuszem, w którym mój kod nie będzie działał, jest sytuacja, gdy typ postu nie zostanie poprawnie zarejestrowany. Wszystkie typy postów powinny być rejestrowane podczas przechwytywania init. Z kodeksu: „register_post_type nie będzie działać, jeśli zostanie wywołany przed„ init ”, a aspekty nowo utworzonego lub zmodyfikowanego typu postu będą działać niepoprawnie, jeśli zostaną wywołane później.” Jeśli nadal potrzebujesz pomocy, sugeruję zamieścić więcej szczegółów w nowym pytaniu.
Radley Sustaire

8

Oto przykład użycia 'registered_post_type'filtra do zmodyfikowania typu postu w innej wtyczce.

Wtyczka, której używałem, nie zawierała menu_icon w swojej definicji, więc chciałem dodać własny.

<?php
/**
 * Add a menu icon to the WP-VeriteCo Timeline CPT
 *
 * The timeline plugin doesn't have a menu icon, so we hook into 'registered_post_type'
 * and add our own.
 *
 * @param  string $post_type the name of the post type
 * @param  object $args the post type args
 */
function wpse_65075_modify_timeline_menu_icon( $post_type, $args ) {
    // Make sure we're only editing the post type we want
    if ( 'timeline' != $post_type )
        return;

    // Set menu icon
    $args->menu_icon = get_stylesheet_directory_uri() . '/img/admin/menu-timeline.png';

    // Modify post type object
    global $wp_post_types;
    $wp_post_types[$post_type] = $args;
}
add_action( 'registered_post_type', 'wpse_65075_modify_timeline_menu_icon', 10, 2 );

W większości przypadków jest to o wiele czystszy sposób; należy jednak zauważyć, że ten filtr jest zbyt późny, aby zostać podniesionym przez przepisywanie, dlatego w takich sytuacjach należy użyć zaakceptowanej odpowiedzi.
mrwweb,

4

Podłącz 'registered_post_type'po tym, jak inny kod go zarejestruje. Nazywa się na końcu register_post_type(). Dostajesz dwa argumenty: $post_typei $args.
Teraz możesz zmienić wszystko dla tego typu postów. Sprawdź $GLOBALS['wp_post_types']niektóre opcje.


Dzięki za skierowanie mnie w stronę tego haka. Odpowiada na (ważniejsze) pytanie dotyczące sposobu modyfikowania typu postu, ale co z opisem, register_post_type()który obejmuje „modyfikuj?” Czy to po prostu źle? Czy w tej chwili powinienem wskoczyć na mojego internetowego konia i zgubić go z Kodeksu?
mrwweb,

2
$wp_post_types[$post_type] = $args;… Sugeruje, że powinieneś być w stanie zmienić właściwości. Dodaj przykład błędnego kodu do swojego pytania.
fuxia

0

Tak samo było z wtyczką The Events Calendar .

Dodałem poniższy kod do function.php, aby zmodyfikować typ postu tribe_organizer

function tribe_modify_organizer() {
 //New arguments
    $tribe_organizer_args = get_post_type_object('tribe_organizer'); // get the post type to modify
    $tribe_organizer_args-> taxonomies = array('post_tag' , 'tribe_events_cat'); // add taxonomies support
    $tribe_organizer_args-> exclude_from_search = false; // show in search result
 //re-register the same post type includeing the new args
    register_post_type( 'tribe_organizer', $tribe_organizer_args );
}
add_action( 'init', 'tribe_modify_organizer', 100 );

0

Nie wiem, czy to brzydkie, ale można zmienić GLOBALsymbol zastępczy „w locie”, ilekroć trzeba manipulować jednym argumentem. W ten sposób używamy niepublicznego typu postu, contentsaby był akceptowalny w menu administratora. Zamykamy się przed i zamykamy po renderowaniu menu:

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);

W naszym przypadku chcemy, aby wtyczka listy administracyjnej listy postów akceptowała nasz typ postu, ponieważ wywołują return get_post_types(array('public' => true));wewnątrz haka z priorytetem 11 ...

Programiści - prosimy o komentarz, jeśli może to powodować jakiekolwiek problemy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.