Jak stworzyć niestandardowy typ posta

Niestandardowy typ posta może Ci się przydać, gdy te dostępne w WordpPressie są niewystarczające. W WordPressie na jego czystej instalacji mamy co najmniej dwa oczywiste typy treści: posty i strony. Tak naprawdę większość encji w WordPressie to posty, tylko różnego typu. Na dowód możesz zajrzeć do tabeli posts (z odpowiednim prefiksem) w Twojej bazie. Znajdziesz w niej np. posty typu page jeżeli masz jakieś strony na swoim WordPressie. Jeżeli natomiast masz na swojej stronie zainstalowany np. WooCommerce, pojawią się tam także posty typu product czy shop_order.

A co jeżeli np. tak jak ja chcesz tworzyć kursy i stworzyć osobny typ posta, który nazwiesz np. kurs? Albo jeżeli chcesz tworzyć ogłoszenia? Albo jakieś inne rodzaje treści, które są odrębne logicznie np. od strony czy od postów? W tym celu pokażę Ci jak stworzyć niestandardowy typ posta.

Po co mi niestandardowy typ posta

Bo będziesz mieć większą elastyczność w rozwijaniu swojego rozwiązania i uchronisz się przed częścią potencjalnych problemów jakie mogą się pojawić po drodze. Pokażę Ci to na przykładzie strony z kursami.

Załóżmy, że mamy 3 kursy: kurs z podstaw Pythona, kurs z podstaw Javy i zawansowany kurs Javy. Dodatkowo mamy bloga, na którym od czasu do czasu publikujemy treści.

Posty i kursy mają się zachowywać trochę inaczej, np. chcemy wyłączyć możliwość komentowania lekcji ale chcemy pozostawić taką możliwość w postach. Jak to zatem zrobić globalnie, a nie pojedynczo w każdej lekcji? Skąd nasz kod ma wiedzieć, że coś jest kursem lub nie?

Może zaraz odpowiesz, że można to rozwiązać kategoriami. Niby można ale szybko zrobi Ci się śmietnik w miarę jak będzie przybywać Ci kursów i będziesz chcieć to jakoś pogrupować. Twoje lekcje prędzej czy później pewnie też dostaną swoje kategorie, np. w kursie Pythona część lekcji będzie należała do kategorii „pętle”. Równolegle możesz mieć post o pętlach jako materiał darmowy i jemu też przypiszesz kategorię „pętle”. Czyli będzie to wspólna kategoria zarówno dla lekcji jak i postów. Czy chcesz zatem, żeby Twoi użytkownicy wchodząc na stronę kategorii zobaczyli darmowe i płatne treści wymieszane razem? Pewnie nie, zwłaszcza, że to jest inny rodzaj materiału.

Kursy mogą też potrzebować specyficznych pól np. numeru lekcji, długości trwania lekcji, jakiegoś pola mówiącego o tym czy dana lekcja to nowy materiał czy zadanie itp. Wtedy najprościej i najrozsądniej jest użyć właśnie innego typu posta do takich lekcji i na tym typie posta dodać dodatkowe pole. Prawdę mówiąc bez osobnego typu posta przychodzą mi jakieś ciężkie i skomplikowane rozwiązania tego problemu, a lepiej sobie życie ułatwiać niż utrudniać.

Najważniejsze do zapamiętania jest chyba to, że jeżeli te kursy, ogłoszenia czy poszczególne firmy w katalogu firm mają służyć czemuś innemu niż posty czy strony, to powinny być obsłużone customowym typem posta. Tak samo jak jest to zrobione w WooCommerce np. z produktem.

Jak stworzyć niestandardowy typ posta

Skoro już ustaliśmy, że życie jest prostsze (zwłaszcza z upływem czasu), gdy wydzielimy sobie logicznie encje, które służą do czegoś innego niż standardowe typy posta, to pokażę Ci teraz jak to zrobić. Stworzymy sobie nowy typ posta specjalnie na kursy ale jeżeli chcesz tego użyć np. do ogłoszeń czy czegoś innego to można, należy jedynie zmienić nazwy i ikonkę (zobaczysz zaraz którą).

Nowy typ posta tworzy się poprzez funkcję register_post_type. Musisz zatem stworzyć funkcję, która wywoła register_post_type z odpowiednimi parametrami i zaczepisz ją w odpowiednim hooku. Chodzi o to, że samo stworzenie sobie nowej funkcji nie oznacza, że się ona wykona. Żeby się wykonała i nasz niestandardowy typ posta został stworzony, musimy naszą funkcję zaczepić w hooku „init”. Na tym etapie większość WordPressa jest już załadowana ale na hooku „init” wciąż wiele rzeczy się jeszcze doładowuje, np. niektóre pluginy, które potrzebują jakiejś podstawowej funkcjonalności WordPressa na etapie ładowania.

Wyglądałoby to mniej więcej tak jak poniżej, ale to nie wszystko co musimy zrobić.

function automatela_create_cpt_classes() {
	register_post_type( 'class');
}
add_action( 'init', 'automatela_create_cpt_classes', 0 );

W powyższym przykładzie nasz post będzie typu „class”.

Parametry

Ten kawałek kodu to jednak nie wszystko, żeby móc korzystać z nowego typu posta. Funkcja register_post_type( 'automatela_classes') w tym przykładzie przyjmuje tylko jeden parametr, czyli typ posta (’automatela_classes') ale możemy, a nawet powinniśmy, w drugim parametrze przekazać tablicę argumentów, która pozwoli na ustawienie min.:

  • jak ma się wyświetlać ten typ posta w panelu administracyjnym (czyli np. etykieta i ikona),
  • czy ma mieć edytor i możliwość ustawienia kategorii i tagów,
  • czy ma być hierarchiczny (czyli np. czy lekcja może mieć lekcję nadrzędną),
  • czy wyłączyć nowy typ posta z „szukajki”.

Poniżej znajdziesz pełny kod który należy umieścić w functions.php motywu potomnego (inaczej zmiany zostaną nadpisane przy aktualizacji motywu), by zarejestrować nowy typ posta. Plik functions.php znajduje się w Wygląd>Edytor motywu i tam „Funkcje motywu”. Przetestuj lepiej wcześniej ten kawałek kodu np. lokalnie na jakiejś testowej stronie, którą możesz zepsuć, bo grzebanie w functions.php może się skończyć małym dramatem, zwłaszcza jeżeli stawiasz pierwsze kroki w WordPressie i nie wiesz jak się dostać do plików np. przez ftp.

// Niestandardowy typ posta
function automatela_create_cpt_classes() {
    //Etykiety widoczne w interfejsie
    $labels = array(
        'name'                  => _x( 'lekcje', 'Post Type General Name', 'automatela_create_cpt_classes' ),
        'singular_name'         => _x( 'lekcja', 'Post Type Singular Name', 'automatela_create_cpt_classes' ),
        'menu_name'             => __( 'Lekcje', 'automatela_create_cpt_classes' ),
        'name_admin_bar'        => __( 'Lekcje', 'automatela_create_cpt_classes' ),
        'archives'              => __( 'Archiwum lekcji', 'automatela_create_cpt_classes' ),
        //Strona kursu
        'parent_item_colon'     => __( 'Lekcja nadrzędna:', 'automatela_create_cpt_classes' ),
        'all_items'             => __( 'Wszystkie lekcje', 'automatela_create_cpt_classes' ),
        'add_new_item'          => __( 'Dodaj nową lekcję', 'tautomatela_create_cpt_classes' ),
        'add_new'               => __( 'Dodaj nową', 'automatela_create_cpt_classes' ),
        'new_item'              => __( 'Nowa lekcja', 'automatela_create_cpt_classes' ),
        'edit_item'             => __( 'Edytuj lekcję', 'automatela_create_cpt_classes' ),
        'update_item'           => __( 'Aktualizuj lekcję', 'automatela_create_cpt_classes' ),
        'view_item'             => __( 'Zobacz lekcję', 'automatela_create_cpt_classes' ),
        'search_items'          => __( 'Znajdź lekcję', 'automatela_create_cpt_classes' ),
        'not_found'             => __( 'Nie znaleziono', 'automatela_create_cpt_classes' ),
        'not_found_in_trash'    => __( 'Nie znaleziono w koszu', 'automatela_create_cpt_classes' ),
        'featured_image'        => __( 'Obrazek lekcji', 'automatela_create_cpt_classes' ),
        'set_featured_image'    => __( 'Wybierz obrazek lekcji', 'automatela_create_cpt_classes' ),
        'remove_featured_image' => __( 'Usuń obrazek lekcji', 'automatela_create_cpt_classes' ),
        'use_featured_image'    => __( 'Użyj obrazka', 'automatela_create_cpt_classes' ),
        'insert_into_item'      => __( 'Wstaw do lekcji', 'automatela_create_cpt_classes' ),
        'uploaded_to_this_item' => __( 'Dodany do lekcji', 'automatela_create_cpt_classes' ),
        'items_list'            => __( 'Lista lekcji', 'automatela_create_cpt_classes' ),
        'items_list_navigation' => __( 'Nawigacja listy lekcji', 'automatela_create_cpt_classes' ),
        'filter_items_list'     => __( 'Filtruj listę lekcji', 'automatela_create_cpt_classes' )
    );
    $rewrite = array(
        //To będzie miało sens, jeżeli lekcje zawsze będą pod jakimś kursem. W innym przypadku prawdopodobnie lepiej będzie ustawić tutaj "lekcja"
        'slug'                  => 'kurs',
        'with_front'            => true,
        'pages'                 => true,
        'feeds'                 => true,
    );
    $args = array(
        'label'                 => __( 'Lekcje', 'automatela_create_cpt_classes' ),
        'description'           => __( 'Kursy i lekcje', 'automatela_create_cpt_classes' ),
        'labels'                => $labels,
        'show_in_rest'          => true,
        //Tutaj dodajemy na przykład, że chcemy, żeby lekcje wzorem np. postów miały autora, dostępny edytor, komentarze itp.
        'supports' 				=> array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'trackbacks', 'revisions', 'custom-fields', 'page-attributes', 'post-formats'),
        //Jeżeli chcesz, żeby twoje lekcje mogły mieć jakieś tagi i kategorie:
        'taxonomies'            => array('post_tag','category'),
        //Oznacza, że nasze lekcje są hierarchiczne. Szczególnie przydatne, gdy chcemy tworzyć lekcję nadrzędną (kurs) i do niej podpinać lekcje.
        'hierarchical'          => true,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 5,
        /*Ikonka, która będzie używana w panelu admina do tego typu posta.
        Jeżeli chcesz użyć innej ikonki sprawdź dostępne tutaj: https://developer.wordpress.org/resource/dashicons.
        Wystarczy, że podmienisz nazwę na nową.*/
        'menu_icon'             => 'dashicons-welcome-learn-more',
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => 'lekcja',
        //Ta opcja opdpowiada za ustawienie, czy ten typ posta ma być możliwy do wyszukania przez szukajkę w WordPressie
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'rewrite'               => $rewrite
    );
    register_post_type( 'class', $args );
}
add_action( 'init', 'automatela_create_cpt_classes', 0 );

Po wrzuceniu powyższego kodu do functions.php musisz jeszcze wejść w Ustawienia>Bezpośrednie odnośniki i zasymulować jakąś zmianę, żeby odnośniki się przeregenerowały. Zmień np. w „Popularnych ustawieniach” format linków i bez zapisywania zmian wróć do tego, co miałeś lub miałaś ustawione domyślne. Po tej akcji zapisz „zmiany”.

Format odnośnika

W podanym przeze mnie przykładzie slugiem nie będzie „lekcja” ale „kurs”. Wspomniałam o tym w komentarzu do kodu ale wyjaśnię jeszcze tutaj. W moim przypadku każda lekcja zawsze jest pod jakimś kursem, tzn. nie mam żadnych lekcji rozrzuconych luzem. Dlatego też nasz nowy typ posta jest hierarchiczny: bo chcę mieć możliwość stworzenia lekcji nadrzędnej (czyli kursu) oraz lekcji potomnych (czyli właściwych lekcji).

Wtedy przykładowy odnośnik do lekcji wygląda następująco:

https://twojastrona.pl/kurs/odnośnik_do_kursu/odnośnik_do_lekcji

W powyższym przykładzie „odnośnik_do_kursu” to po prostu odnośnik do lekcji nadrzędnej, a „odnośnik_do_lekcji” to odnośnik do lekcji potomnej, czyli właściwej lekcji.

Jeżeli u Ciebie lekcje mają być luzem (czyli bez rodzica) wtedy lepiej przestawić slug w kodzie z „kurs” na „lekcja” i dodatkowo się zabezpieczyć wyłączając hierachiczność. Wtedy link do Twojej lekcji będzie wyglądał tak:

https://twojastrona.pl/lekcja/odnośnik_do_lekcji

Jak tworzyć poszczególne niestandardowe posty

Na naszym przykładzie lekcji i kursów należy w przypadku tworzenia nowego kursu po prostu stworzyć nową lekcję. Jeżeli natomiast chcemy stworzyć lekcję pod tym kursem musisz pamiętać, żeby w edycji lekcji w prawej kolumnie w zakładce „Dokument” odnaleźć „Atrybuty strony” i ustawić lekcję nadrzędną oraz jeżeli chcesz numerować swoje lekcje, podać jaki numer powinna ona mieć. Może Ci się to przydać w przyszłości, gdy będziesz chcieć wyświetlać np. listę lekcji w danym kursie w odpowiedniej kolejności.

Dodaj komentarz