Dawno na blogu nic nie było, ale teraz nadrobimy to w dwójnasób. Będzie to krótka (acz treściwa) seria artykułów o najbardziej rewolucyjnej funkcji wordpressa wprowadzonej od wersji 3.0. Wiem, że nie jest to nowość, ale inspiracja przyszła nagle i nieoczekiwanie. Przebudowywałem mechanizm mojej strony brydżowej, przeniosłem ją ze starej Joomli na WordPressa. Potrzebowałem do tego jakiś system do katalogowania wyników imprez, które sędziowałem.
Optymalnym rozwiązaniem były właśnie własne typy postów. Jednak na moje, zdawałoby się dość typowe potrzeby (na dobrą sprawę jest to baza otagowanych linków z nazwami i datami), nie znalazłem żadnego gotowego i spójnego rozwiązania. Aby oszczędzić wszystkim poszukującym czasu i nerwów, będzie ono tutaj umieszczane w odcinkach:
- Własne typy postów (właśnie to czytasz)
- Przedefiniowanie typu postu – nie będzie to już coś w rodzaju wpisu, a rekord bazy danych
- Własne taksonomie – tagi i kategorie dla własnych typów postów
- Jak to praktycznie wykorzystać we własnym szablonie
Co to są własne typy postów
Jak zapewne wiesz, w WordPressie mamy dwa podstawowe typy danych – posty i strony. Podstawowa różnica – strony są hierarchiczne – strona może mieć podstrony (co znajdzie swoje odzwierciedlenie np. w automatycznym menu), a posty mają taksonomie – domyślnie kategorie i tagi (kategorie są hierarchczne , tagi nie).
Własne typy postów umożliwiają wprowadzenie trzeciego (i następnych – nie ma tu ograniczeń) modelu danych na stronę. Ma to sens zasadniczo wtedy, gdy chcemy umieszczać na stronie coś nietypowego np. wskazana powyżej baza wyników. Na Wordcampie w Poznaniu padł (dość szeroko omówiony) przykład stworzonego systemu CRM na bazie WordPressa i własnych typów postów.
Kiedy nie będzie to potrzebne
Nie ma sensu używać własnych typów postów, jeżeli chcemy tylko zmienić sposób w jaki są one wyświetlane. Do tego może posłużyć format postu, a często nawet osobny szablon dla konkretnej kategorii czy tagu. Owszem, będzie to działać, ale to tak jak zwalczać muchy profesjonalną klapką z ultragiętką rączką i profilowaną rękojeścią wykładaną korkiem (za jedyne X XXX w telemarkecie). Będzie to działać, ale zwinięta gazeta sprawdzi się równie dobrze.
Gdzie zadeklarować własny typ postu
Szkoły są dwie. Pierwsza z nich proponuje plik [cci]functions.php[/cci] w katalogu szablonu. Ma to pewien minus – jeśli zmienimy szablon, musimy ręcznie przenosić odpowiednie wpisy. Prawda jednak jest taka, że najczęściej nowy szablon będzie wymagał kilku plików do specyficznego wyświetlania własnych typów postów, więc nie będzie to duża różnica.
W drugim, technicznie bardziej poprawnym przypadku, umieszczamy nasz kod we własnym pluginie.
Jak wygląda deklaracja
[php]
add_action( 'init’, 'moj_cpt’ );
function moj_cpt() {
$labels = array(
'name’ => __( 'Książki’, 'post type general name’ ),
'singular_name’ => __( 'Książka’, 'post type singular name’ ),
'add_new’ => __( 'Dodaj nową’ ),
'add_new_item’ => __( 'Dodaj nową książkę’ ),
'edit_item’ => __( 'Edytuj książkę’ ),
'new_item’ => __( 'Nowa książka’ ),
'view_item’ => __( 'Zobacz książkę’ ),
'search_items’ => __( Szukaj książki’ ),
'not_found’ => __( 'Nie znaleziono książki’ ),
'not_found_in_trash’ => __( 'Brak książek w koszu’ ),
'parent_item_colon’ => ”
);
// Create an array for the $args
$args = array(
'labels’ => $labels,
'public’ => true,
'publicly_queryable’ => true,
'show_ui’ => true,
'query_var’ => true,
'rewrite’ => true,
'capability_type’ => 'post’,
'has_archive’ => false,
'hierarchical’ => false,
'show_in_menu’ => true,
'menu_position’ =>5,
'supports’ => array( 'title’, 'editor’, 'author’, 'thumbnail’, 'excerpt’, 'comments’ )
);
register_post_type( 'ksiazka’, $args );
}
[/php]
W przypadku gdy powyższe piszemy w pliku [cci]functions.php[/cci], nie musimy się bawić w funkcje i akcje, wszystko działa wpisane bez tego. Omówienia może wymagać opcja [cci]rewrite[/cci], jako ta najczęściej zmieniana, reszta jest dość oczywista.
Co więc jest z tym rewrite?
Wartość [cci]false[/cci] oznacza, że nie stosujemy żadnych permalinków w przypadku tych wpisów. Jeżeli chcemy stosować permalinki, to parametrem będzie tablica z definicją permalinków. Najczęściej:
[php]
'rewrite’ => array(’slug’ => 'ksiazki’)
[/php]
Do tej tablicy można także dodać [cci]’feeds’ => true[/cci] aby włączyć RSS dla tego typu postów oraz [cci]’with_front’ => 'false'[/cci] aby usunąć z permalinka przedrostek do adresu wpisów (np. „/blog/”)
A pozostałe pozycje
One są dobrze objaśnione w dokumentacji. Wspomnę tu jeszcze tylko, że[cci]’has_archive'[/cci] z premedytacją ustawiłem na [cci]false[/cci]. Dlaczego? O tym w odcinku czwartym – już wkrótce.
Masz pytania, uważasz, że którąś część opisałem zbyt skrótowo lub, nie daj Boże, błędnie? Daj znać w komentarzach.
SpeX napisał
Co z pozostałymi częściami?
Łukasz Jasiński napisał
Będą
Dariusz napisał
http://example.pl/artykuly/ (wyświetla listę artykułów)
http://example.pl/artykuly/test (wyświetla artykuł na single page)
breadcrumb pokazuje
example.pl » Artykuły » Biznes » test
Biznes jest kategorią należącą do artykułów (Rodzic Artykuły)
kiedy kliknę w kategorie Biznes niestety WordPress wywala mi błąd 404
co jest nie tak?
Łukasz Jasiński napisał
A czy pozostałe kategorie działają? Problemem może być obsługa mod_rewrite przez serwer. Czasami także błąd powstaje po stronie WordPressa, wówczas odwiedzenie w kokpicie ustawienia->bezpośrednie odnośniki i kliknięcie ok rozwiązuje problem.
Dariusz napisał
rozwiązałem problem deklarując raz jeszcze w functions.php custom post type i użyć musiałem flush_rewrite_rules();
add_action(’init’, 'artykuly_register_post_type’);
function artykuly_register_post_type() {
register_post_type(’artykuly’, array(
'labels’ => array(
'name’ => 'Artykuły’,
'singular_name’ => 'Artykuły’,
'add_new’ => 'Dodaj artykuł’,
'edit_item’ => 'Edit artykuł’,
'new_item’ => 'Nowe artykuły’,
'view_item’ => 'View artykuł’,
'search_items’ => 'Szukaj artykułu’,
'not_found’ => 'Nie znaleziono artykułu’,
'not_found_in_trash’ => 'No info found in Trash’
),
'public’ => true,
'supports’ => array(
'title’,
'editor’,
'thumbnail’,
'excerpt’
),
'taxonomies’ => array(’category’, 'post_tag’) // this is IMPORTANT
));
flush_rewrite_rules();
}
Kolejny problem to, że sporo funkcji NIE chodzi w custom post type. Przykładowo
żeby wyświetlić kategorie jej id w normalnych typach wpisów wykonuje zapytanie:
$current_cat=get_the_category();
$current_category = $current_cat[0]->cat_ID;
zwraca np „720”
Natomiast ta wartość w custom post type daje zawsze wartość ostatniej kategorii z normal post type zwracajac 720
a w panelu edytując kategorie widzę wyraźnie ze ma ID 766
Musiałem użyć tricka innego zdeklarowałem coś takiego co przypadkiem znalazłem
$categoryID = $cat; (to już dawało prawidłowe ID 766)
potem przebiłem się czyś takim zupełnie bez sensu pusta pętla
$loop = new WP_Query( array( 'post_type’ => 'artykuly’, 'cat’=>$categoryID,’posts_per_page’ => $per_page, 'paged’ => $cur_page ) );
while ( $loop->have_posts() ) : $loop->the_post(); ?>
i poniżej już działa to prawidłowo
$current_cat_ad=get_the_category();
$current_category_ad = $current_cat_ad[0]->cat_ID;
nie rozumiem dlaczego funkcje które podaje codex (odnośnie custom_post_type) nie zawsze chodzą. Myślę, że wina tu stoi po stronie złej deklaracji w functions.php albo jest jeszcze coś innego na rzeczy, że muszę stosować dziwaczne obejścia. Jeżeli znasz ten problem dlaczego tak jest to czekam na informacje. Forum Polskiego WordPressa na 90% moich postów nie jest w stanie pomóc 🙂
Łukasz Jasiński napisał
Flush_rewrite_rules bardzo źle wpływa na wydajność strony. Jednokrotne wywołanie tej funkcji powinno wystarczyć (jest ona również wywoływana po odwiedzeniu ustawienia->bezpośrednie odnośniki). Polecam zakomentowanie tej funkcji w kodzie nie powinno nic zepsuć, a przyspieszy działanie strony.
Dariusz napisał
ok teraz już rozumiem działanie flusha, dzięki. Drugie moje pytanie pewnie się zlało z kodem. Poniżej wspomniałem co powtórzę raz jeszcze:
Kolejny problem to, że sporo funkcji NIE chodzi w custom post type. Przykładowo
żeby wyświetlić kategorie jej id w normalnych typach wpisów wykonuje zapytanie:
$current_cat=get_the_category();
$current_category = $current_cat[0]->cat_ID;
zwraca np „720″
Natomiast ta wartość w custom post type daje zawsze wartość ostatniej kategorii z normal post type zwracajac 720
a w panelu edytując kategorie widzę wyraźnie ze ma ID 766
Musiałem użyć tricka innego zdeklarowałem coś takiego co przypadkiem znalazłem
$categoryID = $cat; (to już dawało prawidłowe ID 766)
potem przebiłem się czyś takim zupełnie bez sensu pusta pętla
$loop = new WP_Query( array( ‚post_type’ => ‚artykuly’, ‚cat’=>$categoryID,’posts_per_page’ => $per_page, ‚paged’ => $cur_page ) );
while ( $loop->have_posts() ) : $loop->the_post(); ?>
i poniżej już działa to prawidłowo
$current_cat_ad=get_the_category();
$current_category_ad = $current_cat_ad[0]->cat_ID;
nie rozumiem dlaczego funkcje które podaje codex (odnośnie custom_post_type) nie zawsze chodzą. Myślę, że wina tu stoi po stronie złej deklaracji w functions.php albo jest jeszcze coś innego na rzeczy, że muszę stosować dziwaczne obejścia. Jeżeli znasz ten problem dlaczego tak jest to czekam na informacje. Forum Polskiego WordPressa na 90% moich postów nie jest w stanie pomóc 🙂
Dev napisał
Jak znaleźć kolejne części?