WordPress jako CMS – własne typy wpisów Twoim kołem ratunkowym

WordPress jako CMS - własne typy wpisów
Jeśli używasz WordPressa jako CMS, ta wiadomość jest będzie dla Ciebie jak wiatr w żagle: własne typy wpisów (ang. custom post types) pomogą Ci w bardziej elastyczny sposób dostosować witrynę do potrzeb Twoich lub Twojego klienta.

Każdy, kto wykorzystywał WordPressa jako systemu o szerszej funkcjonalności niż tradycyjny blog, prędzej czy później doszedł do wniosku, że prosty mechanizm wpisów i kategorii to za mało. Począwszy od WordPressa w wersji 3.0 można tworzyć własne typy wpisów.Co to oznacza? Zobaczmy jak to działa w praktyce. Tutorial ten będzie miał formę studium przypadku, czyli analizy problemu wykonanej na rzeczywistym przykładzie.

Custom post types - przykład zastosowania
Przykład zastosowania

Opis problemu

Być może już wcześniej zauważyłaś/-eś, że na tym blogu w pasku bocznym po lewej stronie mamy sekcję pt. „Czy wiesz, że…” wyświetlającą krótką notatkę zachęcającą do przeczytania jakiegoś artykułu z tego bloga. Zwróćmy uwagę, że treść notatki wyświetla się losowo. Każda z takich notatek jest w jakiś sposób w WordPressie zapamiętana. Jak? Moglibyśmy wprowadzić ją jako zwykły wpis i przyporządkować do jakiejś kategorii, jednak wówczas teksty notatek byłyby automatycznie wyświetlane:

  • na stronie głównej
  • w kanałach nowości RSS
  • w archiwum
  • w wynikach wyszukiwania
  • jako wpisy danego autora
  • itd.

a tego wszystkiego chcemy uniknąć, ponieważ notatki te nie stanowią istoty naszego bloga, są czymś w rodzaju „wzmianki na marginesie”. Ręczne pomijanie ich z wyświetlania z uwzględnieniem wszystkich tych przypadków, to zbyt dużo pracy. Poza tym nie chcemy przechowywać ich z „tradycyjnymi” wpisami, żeby uniknąć misz-maszu wśród naszych artykułów.

Własne typy wpisów jako rozwiązanie

Własne typy wpisów w WordPressie - jak są przechowywane
Własne typy wpisów – jak są przechowywane (powiększ)

Co innego gdybyśmy mogli pamiętać własne wpisy gdzieś jakby „na boku”. Na pomoc przychodzą własne typy danych (custom post types). Zobaczmy na obrazku obok, w jaki sposób pamiętam teksty tych notatek w WordPressie tego bloga:

Każda notatka składa się z:

  • tytułu (nie jest wyświetlany na ustronie, ale nam przyda się do identyfikacji notatki)
  • opisu, czyli treści notatki (description)
  • wpisu do którego się odwołuje (reference post)
  • daty utworzenia notatki (note date)
Własne typy wpisów - edycja
Własne typy wpisów – edycja (powiększ)

Edycja notatki wygląda niemal identycznie jak edycja tradycyjnego wpisu w WordPressie. Zobacz obrazek obok. Typ nazwałam note (angielski odpowiednik słowa „notatka”), ale równie dobrze moglibyśmy go nazwać „ciekawostka” czy zupełnie inaczej.

Jak założyć i wyświetlić w WordPressie wpisy oparte o własny typ wpisu

Realizacja przedstawionej wyżej funkcjonalności sprowadza się do wykonania 3 kroków:

Krok 1. Założenie własnego typu danych o wybranej nazwie

Wszystkie zmiany wykonywane w tym kroku należy wpisywać do pliku functions.php.

Krok 1.1. Rejestracja własnego typu wpisu

Własny typ wpisu tworzymy i rejestrujemy za pomocą funkcji register_post_type. W naszym przykładzie typ ten będzie nosił nazwę note (notatka).

add_action('init', 'note_register');

function note_register() {
	$args = array(
    	'label' => __('My notes'),
    	'singular_label' => __('My note'),
    	'public' => true,
    	'show_ui' => true,
    	'capability_type' => 'post',
    	'hierarchical' => false,
    	'rewrite' => true,
    	'supports' => array('title')
    );
	register_post_type( 'note' , $args );
}

Własne typy wpisów - rezultat kroku 1.1a
Rezultat kroku 1.1 (powiększ)

Na rysunku obok widać efekt wykonania tego kroku: w menu bocznym w naszym panelu administracyjnym powinna pojawić się nowa sekcja „My notes” z dwoma pozycjami do wyboru „My notes” oraz „Dodaj nowy”.

Własne typy wpisów - rezultat kroku 1.1b - dodanie nowego wpisu (notatki)
Rezultat kroku 1.1 – dodanie nowego wpisu (notatki)

Po kliknięciu w „Dodaj nowy” zobaczymy ekran jak pokazano obok. Widzimy, że ekran przypomina nieco tradycyjny ekran edycji wpisu: ma tytuł (title), lecz jednak nie ma posiada ekranu edycji treści (editor). Ekranu edycji nie włączamy celowo, gdyż do wprowadzania pozostałych wartości wykorzystamy własne pola (ang. custom post fields), o czym później. Włączenie obsługi tytułu umożliwił nam parametr: 'supports’ => array(’title’).

Wykaz innych parametrów akceptowanych przez funkcję register_post_type znajdziemy w Kodeksie WordPressa.

Krok 1.2. Dodanie własnego ekranu do edycji treści wpisu

Oprócz tytułu wpisu (naszej notatki) chcielibyśmy mieć możliwość przechowywania, wyświetlania i edycji następujących pól:

  • opisu, czyli treści notatki (description)
  • tematu wpisu do którego się odwołuje nasza notatka (reference post)
  • daty utworzenia notatki (note date)

Za pomocą funkcji add_meta_box utworzymy własną sekcję edycji dla naszych wpisów (notatek):

add_action("admin_init", "add_note_info");

function add_note_info() {
	add_meta_box("noteInfo-meta",  __( 'Note information') , "meta_options", "note", "normal", "low");
}

Opis najważniejszych parametrów:

  • noteInfo-meta – HTML-owy identyfikator sekcji
  • Note information – tytuł sekcji wyświetlany na ekranie (widoczny na obrazku niżej)
  • meta_options – funkcja, która wyświetli na ekranie, w postaci HTML-a daną sekcję (kod funkcji niżej)
  • note – typ ekranu na którym będzie wyświetlona sekcja edycji, tutaj będzie to nazwa utworzonego przez nas typu wpisu

Znaczenie pozostałych parametrów funkcji add_meta_box możemy doczytać w Kodeksie

Poniżej kod funkcji meta_options, który pozwala na wyświetlenie pól edycji. U nas będą to pola note_content (etykieta „Enter note content”) oraz post_ref (etykieta Enter reference post title).


function meta_options() {
	global $post;
	
	$custom = get_post_custom($post->ID);
	
	$note_content = $custom["note_content"][0];?>	
	<label style="display: block; margin-bottom: 5px"> <?php _e( 'Enter note content:') ?> </label><textarea cols="20" rows="5" name="note_content" style="width:99%"><?php echo esc_attr( $note_content ); ?> </textarea>'
	
	<?php $ref_post = $custom["ref_post"][0]; ?>
	<label><?php _e( 'Enter reference post title:') ?></label><input type="text" name="ref_post" value="<?php echo esc_attr( $ref_post ); ?>" size="80" style="width:97% />
	
<?php }
Własne typy wpisów - rezultat kroku 1.2
Rezultat kroku 1.2 (powiększ)

Na obrazku obok pokazano efekt uzyskany po wykonaniu tego kroku. Wyświetlamy własny meta-box, inaczej sekcję edycji (z etykietą „Note information”) czyli obszar, w którym pokazujemy własne pola skojarzone z danym wpisem:

  • note_content – pole typu textarea (textarea cols=”20″ rows=”5″ name=”note_content”)
  • ref_post – pole tekstowe (input type=”text” name=”ref_post”)

Za pomocą funkcji get_post_custom wyciągamy z bazy zawartość wszystkich własnych pól skojarzonych z danym wpisem. Jest to (czyli sięgnięcie poprzez tę funkcję do bazy) niezbędne, kiedy otwieramy istniejący już wpis do ponownej edycji.

Krok 1.3. Zapisanie w bazie wartości wprowadzonych przez użytkownika

Gdybyśmy w tym momencie kliknęli w „Dodaj nowy” i wprowadzili jakieś wartości dla własnych pól note_content i/lub ref_post, okaże się, że nasze dane wylecą w przysłowiowy kosmos. Aby trafiły do bazy potrzebny będzie jeszcze mechanizm, za pomocą którego WordPress odczyta z ekranu wartości wprowadzone/zmodyfikowane przez użytkownika i zapamięta je w bazie.

W tym celu napiszemy funkcję save_note_data, która zostanie wywołana przez WordPress w momencie dodania/modyfikacji wpisu. Aby tak się stało wbijamy się z jej wywołaniem do akcji save_post. W celu podpięcia się w core’owy cykl przetwarzania WordPressa wykorzystamy funkcję add_action, gdzie jako pierwszy parametr podajemy właśnie save_post:

add_action('save_post', 'save_note_data');

function save_note_data() {
	global $post;
	
	update_post_meta($post->ID, "note_content", $_POST["note_content"]);
	update_post_meta($post->ID, "ref_post", $_POST["ref_post"]);
}

Za pomocą funkcji update_post_meta zapisujemy lub aktualizujemy w bazie wartości dla własnych pól (custom post fields): note_content oraz ref_post przypisanych do danego wpisu (właśnie aktualizowanej notatki).

Własne typy wpisów - widok w układzie kolumnowym
Widok w układzie kolumnowym (powiększ)

Krok 1.4. Wyświetlenie pól wpisu w kolumnach

Gdy teraz będziemy dodawać nowe wpisy-notatki, a następnie wejdziemy w ponowną edycję dowolnego z nich, wartości w polach note_content oraz ref_post będą pamiętane jak należy. Jednak gdy w panelu admin. spróbujemy wyświetlić wykaz wszystkich naszych notatek (czyli klikniemy w „My notes”) czeka nas małe rozczarowanie. Zobaczymy wprawdzie tytuł i datę każdej z nich, ale nic poza tym – patrz rysunek obok.

W tym kroku dodamy dwie kolumny do tego widoku. Naszym celem jest pokazanie w układzie kolumnowym również pól note_content oraz ref_post.

Krok 1.4.1. Wyświetlenie nagłówków kolumn

W celu wyświetlenia nagłówków kolumn z własnymi etykietami do pliku function.php wpisujemy poniższy kod:

add_filter("manage_edit-note_columns", "note_edit_columns");

function note_edit_columns($columns) {
	$columns = array(
		"cb" => "<input type="checkbox" />",
		"title" => __('Note title'),						
		"note_content" => __('Description'),
		"ref_post" => __('Reference post'),
		'date' => __('Note date'),
	);
	return $columns;
}

Uwaga! Niezmiernie ważna jest nazwa pierwszego parametru funkcji add_filter: manage_edit-note_columns. Po przedrostku manage_edit- musi się znaleźć nazwa typu wpisu, zgodna z tą, którą podaliśmy w kroku 1.1 (w funkcji register_post_type), u nas będzie to note, zakończona postfiksem _columns.

Własne typy wpisów - rezultat kroku 1.4.1
Rezultat kroku 1.4.1 (powiększ)

Na obrazku obok przedstawiono efekt wykonania tego kroku. Pojawiły się tytuły nowych kolumn Description title oraz Reference post a dotychczasowe (tytuł i data wpisu) zmieniły swoje etykiety.

W powyższym fragmencie kodu jest jeszcze jeden tejamniczy zapis:

"cb" => "<input type="check.ox" />"

To przypisanie musimy pozostawić, żeby nie zniknęła nam pierwsza z domyślnych kolumn, jaką jest okienko typu checkbox umożliwiające wykonywanie akcji zbiorowych na naszych wpisach.

Krok 1.4.2 Wyświetlenie wartości w kolumnach
Zaraz, zaraz… Mamy już eleganckie nagłówki wszystkich kolumn, ale dlaczego wartości widoczne są tylko w dwóch z nich?
Musimy jeszcze powiedzieć WordPressowi, do jakich pól w bazie ma sięgnąć, żeby uzupełnić zawartość kolumn wyświetlających dane z naszych własnych pól (custom post fields): note_content oraz ref_post.

add_action("manage_posts_custom_column",  "note_custom_columns");

function note_custom_columns($column) {
	global $post;
	switch ($column) {
		case "note_content":
			$custom = get_post_custom();
			echo $custom["note_content"][0];
			break;
		case "ref_post":
			$custom = get_post_custom();
			echo $custom["ref_post"][0];
			break;
	}		
}

Z naszą funkcją note_custom_columns wpinamy się w przetwarzanie WordPressa w punkcie manage posts custom column” target=blank”

Dla kolumny note_content wyświetlamy wartość z pola note_content, dla kolumny ref_post postępujemy analogicznie. Zauważmy, że do odczytu wartości z własnych pól (ang. custom fields) posłużyliśmy ponownie (jak w kroku 1.2) funkcją get_post_custom.

Własne typy wpisów - rezultat kroku 1.4.2
Rezultat kroku 1.4.2 (powiększ)

Odświeżamy ekran z naszymi notatkami i powinniśmy zobaczyć wykaz podobny jak na obrazku obok.

Od tego momentu możemy dodawać, modyfikować i usuwać wpisy własnego typu (notatka).

Własne typy wpisów - widok po wprowadzeniu wpisów
Widok po wprowadzeniu wpisów (powiększ)

Krok 2. Dodanie kilku wpisów utworzonego typu

Mamy już pełny interfejs do zarządzania naszymi notatkami. Teraz dodajmy kilka wpisów wykorzystując opcję My notes->Dodaj nowy.
Po wykonaniu tego kroku powinniśmy uzyskać efekt pokazany na rysunku obok.

Krok 3. Wyświetlenie losowo wybranego wpisu na pasku bocznym

Jak dotąd nasze notatki siedzą tylko w bazie i są widoczne w panelu administracyjnym. Czas pokazać je światu, czyli wyświetlić na stronie. Jako że są to w dalszym ciągu wpisy WordPressowe do ich wyświetlania należy zbudować query. Naszym celem jest wyświetlenie tylko jednego, losowego wpisu, który ma sie pojawić na pasku bocznym, w sekcji widgetowej. Owieramy plik sidebar.php i dopisujemy:

<div class="side-widget">
	<h2><?php _e('Did you know...') ?></h2>
	<?php global $post;	

	$r = new WP_Query(array('posts_per_page' => 1, 'no_found_rows' => true,
                                                       'post_type' => 'note', 'orderby' => 'rand'));
	if ($r->have_posts()) : 	
		while ($r->have_posts()) : $r->the_post(); 
			$custom = get_post_custom($post->ID); 
			echo '<p>' . $custom["note_content"][0] . '</p>';
		endwhile;
		wp_reset_postdata();
	endif;?>
</div>	

Komentarz do najistotniejszych fragmentów kodu:

  • ’posts_per_page’ => 1 – wybieramy tylko jeden wpis
  • ’post_type’ => 'note’ – wybieramy tylko spośród wpisów typu notatka (note)
  • ’orderby’ => 'rand’ – wybieramy wpis losowy
  • ’no_found_rows’ => true – wyłączamy automatyczne zliczanie wszystkich wpisów w wyniku w celu przyspieszenia zapytania

Do wyświetlenia głównej treści notatki (note_content) wykorzystujemy funkcję get_post_custom i odwołujemy się do pola note_content, podobnie jak to robiliśmy już wcześniej.

Informacje dodatkowe

Pokazane wyżej kroki w pełni pozwalają na realizację naszego zadania – po ich wykonaniu możemy już cieszyć się efektem. Będzie podobny do tego jak na tym blogu w lewej, bocznej kolumnie.

Ale przydałby się coś jeszcze: możliwość wykonania podglądu lub wyświetlenia strony z treścią pojedynczego wpisu.

Robimy szablon podglądu własnego wpisu
Robimy szablon podglądu własnego wpisu (powiększ)

Na rysunku obok widzimy, że po najechaniu myszą na tytuł wpisu oraz opcję Zobacz w dolnym pasku przeglądarki (Firefox) widzimy URL strony, na której wpis będzie widoczny. Naszym celem jest pokazanie na niej tytułu i treści wpisu.

W katalogu z naszym motywem zakładamy plik o nazwie single-note.php. Nazwa ta nie jest przypadkowa. Pierwszy jej człon (single) jest odpowiednikiem nazwy znanego nam szablonu single.php, służącego do wyświetlania pojedynczego wpisu, a drugi (note) odpowiada typowi wpisu jaki nadaliśmy w kroku 1.1. Oba człony muszą być połączone myślnikiem.

Do pliku single-note.php wklejamy kod wyróżniony poniżej. Kontekst (to co jest przed i za wyróżnieniem) będzie się oczywiście różnić, w zależności od budowy struktury danego motywu.

<?php get_header(); 
			
	if ( have_posts() ) while ( have_posts() ) : the_post(); 
		$custom = get_post_custom($post->ID); ?>
		<h2><?php echo $post->post_title ?></h2>
		<p><?php echo $custom["note_content"][0] ?></p>
	endwhile; 

get_footer(); ?>

Co się stanie jeśli nie utworzymy dedykowanego pliku single-note.php?
Zgodnie z hierarchią szablonów, WordPress sięgnie do pliku index.php. Nasz wpis-notatka jest wpisem jak każdym inny, więc wykorzystanie standardowej pętli WordPressa pokaże jakiś wynik, ale w naszym przypadku tylko częściowo. Na ekranie poglądu wpisu zobaczymy jedynie sam tytuł wpisu-notatki. Jej treść przechowujemy we własnym polu (note_content), a wyświetlania tego pola nie znajdziemy ma w ogólnym pliku index.php. Dlatego najlepiej napisać własny szablon dla wyświetlania pojedynczego wpisu.

To już wszystko. Pamiętaj, że ten tutorial jest utworzony z myślą o Tobie. Jeśli któryś z przedstawionych tu punktów jest dla Ciebie niejasny, śmiało zapytaj o to w komentarzach. Możesz również ekspresowo sprawdzić, jak działa mechanizm własnych typów wpisów, korzystając z kompletu prezentowanych tu kodów – do pobrania niżej.

Pliki do pobrania

Niżej znajdują paczka plików do pobrania, zawierająca wszystkie kody źródłowe wykorzystane w tym tutorialu.

Inne wpisy o podobnej tematyce:

77 komentarzy do “WordPress jako CMS – własne typy wpisów Twoim kołem ratunkowym”

  1. Sprawdzam, czy dobrze zrozumiałam: jeśli wprowadzę te instrukcje w życie, zgodnie z w/w punktami, to na moim blogu we wpisach czytelnikom wyświetli się to, co w tym wpisie nazywa się „czy wiesz, że..”, tak?

  2. Mam wrażenie, że piszecie (nie wiem, która z Was) artykuły pod moje potrzeby.

    Przy okazji, chcę zauważyć, że poza merytorycznie dobrą treścią Waszego wpisu, jego struktura (pod względem SEO) na 6+

    Profesjonalizm połączony z perfekcjonizmem (w dobrym tego słowa znaczeniu).

    A teraz, dla tych, którzy tu trafili (tak jak ja), od strony bloga i nie zorientowali się jeszcze, że zajmujecie się tworzeniem fajnych i dobrze wykonanych stron internetowych polecam zapoznanie się z Waszą stroną główną: http://www.webfaces.pl/

    1. MarioC, nie ukrywam, że tym razem lepiej się postarałam o dobrą strukturę pod SEO, właśnie po lekturze Twojego artykułu z tą a’la tabelka porównawczą do struktury książki, o, właśnie ten, który Ci się podpiął pod komentarzem. To znaczy bardziej starałam się zapanować nad hierarchiczną struktura nagłówków, bo przyznam, że wcześniej nagłówki bardziej dobierałam na zasadzie: „stawiam na h2 bo jest najlepiej widoczny” 🙂

  3. Wpis dołączam do mojej kolekcji perełek 🙂 Mam tylko jeden pomysł racjonalizatorski 🙂 Podczas wprowadzania nowej notatki jest pole reference post, gdzie należy wprowadzić tytuł posta. Trudno jednak zapamiętać dokładnie tytuły wszystkich wpisów na blogu 🙂 W takim wypadku nawet zamiana tego pola tekstowego na listę wyboru znacznie ułatwiłaby dodawnie notatek. Co o tym myślisz?

    1. Ciekawe co tam jeszcze jest w Twojej kolekcji perełek 🙂

      Z tą listą to rzeczywiście dobry pomysł. Już nawet zakasałam rękawy, żeby od razu wdrożyć go w życie, ale w praniu okazało się, że ja potrzebuję i tak jeszcze link do tego wpisu (wykorzystuję go w treści notatki), więc chyba zostanę przy mojej obecnej metodzie na piechotę:
      1. Wchodzę do archiwum na moim blogu
      2. Wciskam na tytule artykułu prawy klawisz myszy i wybieram „Kopiuj adres odnośnika” po czym wstawiam go do treści notatki
      3. Wracam do archiwum, zaznaczam tytuł posta i przeklejam (copy-paste) w treści notatki jako opis odnośnika i drugi raz w polu referencyjnym.

      1. Jedna z tych rzeczy, które warto by mieć rozpracowane na przyszłość. Na własne potrzeby można się zadowolić prowizorką, ale np. dla klienta już niezbyt 🙂

        W takich sytuacjach tęsknię troszkę za Drupalem, gdzie po prostu definijesz pole jako 'node-refernce’ i możesz sobie wybierać między 'select list’ i 'autocomplete text field’ 🙂

        1. Tak, zgadzam się, im mniej tego rodzaju wytycznych dla klienta, tym lepiej świadczy o jakości naszego „produktu”. Tego rodzaju wskazówki dla klienta opisałam nawet jako jeden z najczęściej popełnianych błędów deweloperów używających WordPressa jako CMS.

          Nie mam doświadczenia w Drupalu, ale skoro takie rzeczy są dostępne od ręki, to faktycznie duży plus. Ola, piszesz, że tęsknisz trochę za Drupalem, to dlaczego przeniosłaś się na WP?

          1. Żeby była jasność – jest też mnóstwo rzeczy związanych z Drupalem, za którymi nie tęsknię 🙂

            A na WP się nie przeniosłam. Po prostu trafiają projekty, dla których bardziej odpowiedni jest Drupal albo Joomla niż WP i właśnie nie tak dawno nad jednym pracowałam 🙂

  4. Witam 🙂 ponownie sobie przeczytałam artykuł i postanowiłam zrealizować pomysł. Ale jestem laikiem, i potrzebuję dodatkowej wskazówki: w którym dokładnie miejscu w pliku functions.php mam wstawić ten kod?
    A drugie pytanie: czy jak ściągnę te pliki to mam dokładnie wszystko skopiować i wkleić? Po otwarciu bowiem są jeszcze tagi /body i /html, one tez muszą być skopiowane do pliku, który już istnieje w motywie?
    I mała uwaga: chyba commentluv trochę nie działa 😉
    Pozdrawiam

    1. Ania, najlepiej, żebyś zrobiła te zmiany gdzieś na wersji roboczej swojej witryny, a jeśli takiej nie posiadasz, to zarób sobie kopie plików functions.php i sidebar.php przed wprowadzeniem zmian i jak się coś posypie, to będziesz mogła przywrócić stare wersje.

      1. Wchodzisz do pliku functions.php z paczki, zaznaczasz całość i przeklejasz do swojego pliku functions.php na końcu (za aktualną zawartością).

      Po wykonaniu tego kroku już powinnaś zobaczyć w panelu admina to, co na obrazku w kroku 1.1
      Możesz dodać treści jednej notatki na próbę i zapisać. Teraz, żeby ona się pojawiła w sidebarze (na pasku bocznym), musisz zmodyfikować plik sidebar, czyli wykonać punkt 2:

      2. Widzę, że używasz motywu graphene. Wchodzisz do pliku sidebar.php i za linią:

       &lt;?php do_action('graphene_after_sidebar1'); ?&gt;
      

      oraz przed linią:

      &lt;/div&gt;&lt;!-- #sidebar1 --&gt;
      

      wklejasz taki kod:

        &lt;div class=&quot;sidebar-wrap clearfix&quot;&gt;
         &lt;h3&gt;&lt;?php _e('Did you know...') ?&gt;&lt;/h3&gt;
          &lt;?php global $post;  
       
          $r = new WP_Query(array('posts_per_page' =&gt; 1, 'no_found_rows' =&gt; true,
                                                             'post_type' =&gt; 'note', 'orderby' =&gt; 'rand'));
          if ($r-&gt;have_posts()) :
              while ($r-&gt;have_posts()) : $r-&gt;the_post();
                  $custom = get_post_custom($post-&gt;ID);
                  echo '&lt;p&gt;' . $custom[&quot;note_content&quot;][0] . '&lt;/p&gt;';
              endwhile;
              wp_reset_postdata();
          endif;?&gt;
          &lt;/div&gt;
      

      Po zapisaniu zmian (wysłaniu pliku na serwer) i odświeżeniu dowolnej strony powinnaś zobaczyć nową pozycję w sidebarze, na samym dole z napisem „Did you know…”

      I mała uwaga: chyba commentluv trochę nie działa

      Comment luv nie działa tylko dla Twojej strony. Wpisz sobie testowo (bez wysyłania komentarza 😉 w polu „www” adres innego bloga i będzie ok.

  5. hm…z tym commentluv to dziwna sprawa…masz rację, że nie działa na mojej podstawowej stronie; ale taka sytuacja jest tylko tutaj :/
    dziękuję za porady, wieczorem potestuję 🙂

    1. Tak, można. Najlepiej wcześnie przygotować ten fragment kodu w postaci tzw. shortcode’u, który umieszcza się w functions.php i nadaje mu jakaś przyjazną nazwę. Wówczas będzie można wstawić ten kod w dowolnym miejscu podczas edycji postu lub strony używając wskazanej nazwy shortcode’u w nawiasach klamrowych. Wiesz jak się pisze shortcode’y?

    1. Najprościej to będzie dodać możliwość wstawiania featured images (ikony wpisów).
      Podczas rejestracji custom post type w parametrze supports dodajesz wsparcie dla thumbnail:

      'supports' =&gt; array('title','thumbnail')
      

      Dla przypomnienia, żeby ikony wpisów działały, trzeba w pliku functions.php mieć również linię add_theme_support( 'post-thumbnails’ );

  6. A jak ma się sytuacja, gdy chcę zastosować standardowy edytor TinyMCE zamiast zdefiniowanego? Tzn. jak zapisać dane do bazy podane przez edytor? Mówię o tym fragmencie kodu: 'supports’ => array(’title’, 'editor’) . Z góry dziękuję za odpowiedź!

  7. Cofam pytanie, już wszystko wiem, wydawało mi się, że posty się nie zapisują do bazy, a to nie w tym leżał problem. Można śmiało usunąć oba posty.

  8. Niestety u mnie nie działa tak jak trzeba. Nie wiem gdzie popełniam błąd aby wszystko wyświetlało się poprawnie.

    1. Po wpisaniu do pliku functions.php
    // 3. Poniżej kod funkcji meta_options, który pozwala na wyświetlenie pól edycji.
    function meta_options() {
    global $post;

    $custom = get_post_custom($post->ID);

    $note_content = $custom[„note_content”][0]; ?>

    <input type="text" name="ref_post" value="” size=”80″ style=”width:97%” />

    oraz

    Notice: Undefined index: ref_post in /home/nazwa/ftp/blog/wp-content/themes/Oribiz/functions.php on line 145

    chodzi o linijkę:

    2. A po wpisaniu kodu do pliku funcions.php

    add_action(’save_post’, 'save_note_data’);

    function save_note_data() {
    global $post;

    update_post_meta($post->ID, „note_content”, $_POST[„note_content”]);
    update_post_meta($post->ID, „ref_post”, $_POST[„ref_post”]);
    }

    Wyskoczyły błędy:
    Notice: Trying to get property of non-object in /home/nazwa/ftp/blog/wp-content/themes/OriflameBiznes/functions.php on line 156

    Notice: Undefined index: note_content in /home/nazwa/ftp/blog/wp-content/themes/Oribiz/functions.php on line 156

    Notice: Trying to get property of non-object in /home/nazwa/ftp/blog/wp-content/themes/Oribiz/functions.php on line 157

    Notice: Undefined index: ref_post in /home/nazwa/ftp/blog/wp-content/themes/Oribiz/functions.php on line 157

    Chodzi o linijki:
    (linijka 156) update_post_meta($post->ID, „note_content”, $_POST[„note_content”]);
    )linijka 157) update_post_meta($post->ID, „ref_post”, $_POST[„ref_post”]);

    Nie wiem co z tym począć. Czy może jakieś sugestie do tego?

    1. Komunikat „Trying to get property of non-object…” oznacza, że następuje odwołanie jak do obiektu, do czegoś co w istocie obiektem nie jest. Taki błąd pojawia się zwykle wówczas, gdy używamy operatora ->

      Dobrze jest spróbować użyć funkcji var_dump($nazwa_zmiennej), która wypisze zawartość danej zmiennej. Wówczas upewnimy się, czy nie ma tam śmieci.

      np:

      var_dump($post)
      
      1. Witam

        Działa wszystko tak jak należy. Super i dziękuję za pomoc.
        Jeszcze jedno. Szukam już 3 dzień rozwiązania tego typu. Jestem przekonany, że mogę liczyć na Twoją pomoc. Może to być także kolejny artykuł na Twojego bloga.

        W czym rzecz. Chciałbym aby przy wyświetlaniu archiwum w/g kategorii wyświetlał się dodatkowy opis kategorii, a po nim dopiero zbiór artykułów w archiwum danego działu. Chciałbym także aby można było wpisać dodatkowy tytuł w h1 niezależny od nazwy kategorii.
        Wiem, że opis można wstawić za pomocą funkcji

        Ale nie o to chodzi. Czy mogę otrzymać jakieś wskazówki jak można to zrobić.
        dziękuję za pomoc

    1. Podczas rejestracji typu w parametrze supports (krok 1.1. w linii 11) trzeba dodać editor (jako kolejny argument po 'title’).

  9. Witam. Na początek dziękuje za podpowiedź, jak fajnie zrobić dział czy wiesz, że. Do tego potrzebowałbym jeszcze możliwość formatowania wyświetlanego tekstu. Niestety w cssach nie czuje się mocny i potrzebowałbym Twojej pomocy w tym temacie. Znalazłem też fajną wtyczkę, którą chciałbym wykorzystać razem z Twoją poradą. Razem miałoby to działać w ten sposób, że w miejscu jednego wyświetlanego postu pojawiają się inne (automatycznie przesuwane przez inną wtyczkę – Scroll post excerpt) chciałbym te dwie rzeczy połączyć.
    Ps. poprosiłbym również o przesłanie całego kodu, który pozwala na wyświetlanie ikon wpisów.
    Będziesz w stanie mi pomóc w tej kwestii?

    1. Witam. Co konkretnie oczekujesz ode mnie w związku z kwestią pierwszą?

      O jakie wyświetlanie ikon chodzi?

  10. Brawo za napisany jasno artykuł. Brawo zresztą za cały blog! Ja na swoim od jakiegoś czasu myślę o czymś w rodzaju minibloga na sidebarze. Poszukuję różnych rozwiązań; jednym z nich jest Alkivia SidePosts, tyle że tutaj jest ten minus, że wpisy na ten miniblog będę mi się pojawiać we „Wpisach”, czyli zrobi mi się mały bałagan. Chciałbym zatem te wpisy na miniblog potraktować jako custom post types… Inaczej mówiąc, wiem, co chcę, ale: 1) nie wiem, jak to zrobić; 2) miewam problemy z wytłumaczeniem tego, co chcę;) Mimo pkt. 2, jednak spróbuję:

    1. Jak z tego zrobić widget, tzn. żeby nie implementować tego poprzez wklejanie kodu do sidebar.php, ale aby było to funkcjonalnym widgetem i żebym np. mógł określać, w którym miejscu na siedabarze ma się to (ta notatka Czy wiesz, że, posługując się Waszym przykładem) pojawiać.
    2. Jak zrobić, aby nie wyświetlała się cała notka, lecz tylko fragment (excerpt/content, uhm)… całość natomiast byłaby wyświetlana, jak rozumiem, wg single-note.php (przy czym obecnie, gdy z poziomu admina kliknę „zobacz” wyświetla mi się 404, a nie ten pojedynczy wpis typu note… pewnie coś ja źle robię, ale na razie nie będę tego zgłębiał…).
    3. Dalsze pytania może pominę (bo nie do końca potrafię opisać, czego chcę)… generalnie chodzi mi o to, czy można jakoś połączyć to, co daje Alkivia Sideposts z jednej strony (fajny plugin na miniblog… pytanie, czy to samo można osiągnąć bez wtyczki…?) i custom post types z drugiej (aby wpisy na to, co nazywam miniblogiem, nie plątały się wśród „normalnych” wpisów).

    Pozdrawiam i dziękuję za to, co robicie!

    1. Dzięki za miłe słowa. Na Twoje pytania nie mogę odpowiedzieć tak z marszu, ale w wolnej chwili wrócę do temu, bo jesteś już którąś z rzędu osobą, która o to pyta. Zapoznam się też międzycasie z pluginem Alkivia Sideposts bo go nie znam.

  11. W stopce strony znalazłem zapis „Wszelkie prawa zastrzeżone.”. Rozumiem i respektują prawa autorskie.

    Ale co z wykorzystaniem we własnym projekcie tych zaprezentowanych kodów, które przypuszczam że opierają się zapewne na dokumentacji codex’a)? Czy ich obejmuję też ta klauzula?

    1. Kody można wykorzystywać. Dziękuję za sugestię, we stopce przygotuję link do strony, w której będzie to jasno napisane, żeby nie było wątpliwości. Dziękuję za pytania i jestem pod niesamowitym wrażeniem, że trafiają się ludzie, którzy przywiązują taką wagę do praw autorskich. Pozdrawiam! Aga

  12. Jeżeli mam kilka typów postów jak wtedy wygląda sytuacja z wywołaniem funkcji add_action(’save_post’, 'POST_TYPE’)? Można wywołać ją tyle razy ile typów?

    1. Damian, jeśli korzystamy z własnych typów wpisów (custom post types) save jest niepotrzebny. Save jest potrzebny tylko w przypadku custom meta boxes. Teraz tak myślę, że w tym artykule może nie potrzebnie wprowadziłam 2 pojęcia na raz i jest zamieszanie.

      1. Ale każdy z tych typów na swoje własne custom meta boxes. Załóżmy, że typ ALKOHOL ma pola ZAWARTOŚĆ ALKOHOLU i RODZAJ a typ postu SOK ma pola SMAK i LITRY. I teraz podpinam pod jednego save_posta wszystkie cztery pola, a edytuję tylko ALKOHOL. Czy w takim przypadku taki wpis (typu ALKOHOL) otrzyma pola SMAK i LITRY mimo, że są one charakterystyczne dla wpisu typu SOK?

        Podejrzewam, że chyba pola te nie zostaną wzięte pod uwagę, bo ID będzie odwoływał się do wpisu ALKOHOL, który nie ma takich cech, ale nie jestem pewien.

  13. Ciekawy artykuł.
    Mam pytanie jak zrobic by można bylo dodac tagi jak wprzypadku normalnego postu oraz dodac media typu grafika itp.

    Przerobilem ten tutorial i dodalem sobie analogicznie dodatkowe custom fields , rozwijane listy itp.

    Chcialbym by mialo to funkcjonalnosc jak w przypadku postu ale z dodatkowymi polami.

    Czy lepiej jakis plugin?
    Wolabym sam napisac.

    Pozdrawiam

    1. Jest to kwestia dobrania odpowiednich parametrów podczas inicjalizacji zmiennej $args, podczas rejestracji custom post type.

      Żeby pojawiła się ikonka dodawania zdjęć, trzeba dołączyć wsparcie dla edytora (w przykładzie był niepotrzebny więc go nie dawałam, byłoo tylko wsparcie dla title):

      'supports' =&gt; array( 'title', 'editor')
      

      Żeby była możliwość dodawania kategorii i tagów za parametrem supports należy dołączyć parametr:

       'taxonomies' =&gt; array('category', 'post_tag')
      

      pamiętając, żeby oddzielać parametry przecinkami.

  14. dziękuję za szybką odpowiedz.

    Teraz kolejna porcja pytań.

    Jak wyświetlić to na stronie?
    Trzeba w widgecie umieścić? czy skonstruować pętle?

    dodałem taki wpis do kategorii.

    Gdy chce wyswitlic wpisy z danej kategori dodane jako zwykly post i metoda wyzej opisana to się nie wyswietla na stronie.

    Pozdrawiam

    1. Również witam 🙂
      Spróbuj coś takiego wstawić do functions.php (na końcu):

      add_filter( 'pre_get_posts', 'advanced_search' );
      function advanced_search( $query ) {
          if ( $query-&gt;is_search )
              $query-&gt;set( 'post_type', array( 'post', 'notes', 'books' ) );
          return $query;
      };
      

      W miejsce notes, books wstawiasz swoje wpisy. Jak chcesz dodać strony to w array’u dopisz też pages.

      1. Jak działa ta linijka:
        $query->set( 'post_type’, array( 'post’, 'notes’, 'books’ ) );

        Ona nadpisze to co jest aktualnie pod set czy dopisze te pozycje wpisane?
        Wydaje mi się że w tym stanie jak jest tu napisane może wystąpić konflikt w przypadku użycia jakichś wtyczek ingerujących w szukanie lub we własne typy wpisów.

        Czy nie lepiej najpierw pobrać to co jest aktualnie pod tą zmienną, i tylko dopisać te nowe rzeczy zamiast nadpisywać?

  15. Kolejny raz świetny pomysł, który zaraz wprowadzam w życie 😀
    Pozwoliłem sobie dodać Twój blog do listy TOP odnośników. Z czystym sercem Was polecam 😀

  16. Hej, przepraszam, pytanie, może nie do końca na temat, ale widzę, że w dyskusji padło pytanie, jak do własnych typów wpisów dodać edytor tinymce… a może pomożesz i powiesz jak dodac go we Własnych polach? Cały dzień siedzę na tym i nic 🙁 Pozdrawiam i gratuluję tak dużej wiedzy i tak konkretnie podanej 🙂

    1. Dzięki za info. Przyda się wiedza o tej wtyczce. Ja edytor dodaję sama, ale nie jestem tego w stanie wytłumaczyć w komentarzu, bo sporo kodu trzeba wstawić i to w kilku miejscach.

      1. Witam, poszukuję właśnie rozwiązania jak dodać ten edytor do custom fielda. Może podałabyś jakieś namiary na jakiś tutek albo codex?

        Sam edytor dodaje się za pomocą tego: 'supports’ => array(’title’, 'editor’),
        natomiast nie wiem już jak zapisać to do bazy?

  17. Witam, bardzo fajny artykuł, dużo się dowiedziałem, trafiłem tu jednak trochę za późno bo sam się najpierw męczyłem kilka godzin z tym. Problemu jednak do końca sam nie rozwiązałem, a i tutaj niestety artykuł przed tą częścią się urywa – chodzi mianowicie o archiwum, i dalsze konsekwencje związane z taksonomią.

    Stworzyłem Custom_post_type o nazwie „portfolio”, będę tam dodawał kolejne realizacje. Chcę podzielić te strony na kategorie (’html/css(w rzeczywistości wszystkie)’,’Wordpress’,’jQuery’,’Responsywne’). Wszystko fajnie działa, mogę kolejne strony przypisywać do tych kategorii ale największy problem pojawia mi się z wyświetleniem archiwum dla tych podkategorii, oraz wyświetlenie menu które automatycznie pobierze nazwy kategorii i da linki odpowiedni do ich archiwów.

    Potrzebuje informacji czego szukać aby:
    1. Wyswietlic archiwum pełne (archive-nazwa_typu.php – to chyba dzialalo ale nie jestem pewien teraz)
    2. Wyswietlic archiwum kategorii (category-nazwa_typu.php niedziala dla customowych taksonomii, dziala tylko dla kategorii zwyklych wpisow)
    3. Pobrac wszystkie taksonomie mojego custom-post-type
    4. Pobrac wszystkie taksonomie konretnego postu tego typu
    5. Dla kazdego archiwum tego typu (nadrzędnego, kategorii, oraz pojedynczego postu) wyswietlic menu ktore prowadzi do archiwum z postami konkretnego typu (czyli po kliknieciu w responsive ma wyswietlic wszystkie wpisy z kategorii responsive).

    6.Czym sie rozni w praktyce podział na kategorie od podziału na tagi w konktekscie custom_post_types?

    Jakich funkcji szukać w Codexie? Na razie jest to na zasadzie osobnego menu, gdzie ręcznie dodałem linki do kategorii i przypisanego do wczesniej zarejestrowanego menu globalnego (nav_menu), ale jest to BARDZO nieeleganckie rozwiązanie, i na pewno nie chcę takiego czegoś w przyszłości oferować klientowi.

      1. W sumie to poradziłem już sobie ze wszystkim, podszedłem do tematu jeszcze raz, wszystko wyzerowałem i udało się bez większego problemu. Musiałem mieć jakiś mały błąd wcześniej który mi blokował.

        Może tylko 6, jakiś przykład do czego lepsze są tagi a do czego kategorie.

        1. Nie wiem, czy powiem coś odkrywczego, ale to zależy od specyfiki dziedziny, którą definiujesz za pomocą custom post type’ow, a różnicy między kategorią a tagiem w cpt jest analogiczna jak dla normalnych kategorii i tagów. Kategoria różnią się tym od tagów, że można je układać w wielopoziomowe hierarchie i generalnie to kategorie są podstawowym mechanizmem grupującym w WP.

          A przykład. Powiedzmy, że cpt to u nas Lekarze stomatolodzy. Za pomocą kategorii można ich podzielić wg tytułów, np. 1) lekarz stomatologii 2) lekarz stomatologii i medycyny itd. bo dajmy na to z jakiś powodów taki podział jest ważny.

          A za pomocą tagów można ich przypisać do konkretnej usługi stomatologicznej np. chirurgia, protetyka, ortodoncja, implantologia.

          Ja wraz z ctp używam tylko kontekstu kategorii.

  18. Hej,

    bardzo fajny poradnik i przejrzyście napisany 🙂

    Natrafiłem jednakże na jeden problem. Otóż potrzebuję zdefiniować 3 typy wpisów na stronie i analogicznie robiąc wkleiłem ten kod do functions.php trzykrotnie zmieniając przy tym oczywiście zmienne na odpowiednie nazwy jednakże problem pojawia się z meta options. Jeśli już się pojawiają to w każdej podstronie edycji typów wpisu pojawiają się wszystkie pola edycji (łacznie z tymi z pozostałych ctp).

    Proszę o radę lub sugestię jak to poprawić.

  19. Korzytsam z Twego tutoriala AGA. Jest świetny.
    Opieram o to całą stronę by nie bawic sie w robienie kategorii itp. User dostaje juz w menu wytluszczone pdtsrony jako własne typy.

    Mam pytanie w zwiazku z tym. Jak zrobic by byla mozliwosc komentowania tylkoe jednego typu postów. Chcialbym miec wordpressa jako CMS i jeden typ postów nim jako BLOG. tak by ludzie mogli to komentować.

    Prosze o podpowiedz.

    Pozdrawiam Serdecznie

    1. Bogdan, tak na szybciora, to po prostu zrób osobny plik do pojedynczego widoku i tam umieść form z kometarzami. Czy Ty rozumiesz jak działa hierarchia plików WP? Bo jak nie, to pewnie nic z tej odpowiedzi nie zrozumiesz. Ja jestem taka zabiegana teraz i piszę na szybko. Będziesz na WordCampie za tydzień?

  20. Hej, dzieki za ciekawy tutorial.

    Podczas edycji utworzonej wczesniej notki wszystko jest ok. Niestety podczas dodawania nowej pojawiaja sie nastepujace ostrezenia:

    1.
    Notice: Trying to get property of non-object in function.php on line 200
    Notice: Undefined index: note_content in function.php line 200
    Notice: Trying to get property of non-object in function.php on line 201
    Notice: Undefined index: ref_post in function.php on line 201

    Kod zrodlowy lini 200 y 201:
    update_post_meta($post->ID, „note_content”, $_POST[„note_content”]);
    update_post_meta($post->ID, „ref_post”, $_POST[„ref_post”]);

    2.
    Notice: Undefined index: note_content in function.php on line 185
    Notice: Undefined index: ref_post in function.php on line 189

    Kod zrodlowy:
    $note_content = $custom[„note_content”][0];
    $ref_post = $custom[„ref_post”][0];

    Wiesz co jest tego przyczyna i jak temu zapobiec?

  21. Hej, przeszukałem cały Internet żeby w końcu trafić na tego bloga. Super, sporo ułatwił, a w zasadzie pozwolił uzyskać przeze mnie pożądany efekt.
    Dożyłem do tego aby dodawane wpisy wyświetlały sie jeden pod drugim w głównej części strony.
    Pozostał mi jeszcze jedna rzecz, z która nie mogę sobie poradzić. Wyszukiwarka WordPressa nie znajduje tych wpisów. Możesz podsunąć jakieś rozwiązanie ? Z góry dzięki 😉

  22. Witam

    Mam pewien problem, opiszę go tutaj, moze akurat sie uda i ktos mi wreszcie pomoze, moze nawet Pani :).

    Moj problem polega na tym, ze nie wiem czym sie rozni strona page-xxx.php od archive-xxx.php. Przerobilem kilka kursów, jeden angielski drugi polski. W angielskim tworza swoj wlasny custom post i page-xxx.php i dodaja tam normalnie posty czyli dynamiczna strona a w polskim tworza archive-xxx.php i tez dodaja tam normalnie posty. W obu przypadkach zostal stworzony wlasny post na takiej samej zasadzie jak home.php ale w jednym kursie uzyta zostala strona page a w drugim archive, a wiec moje pytanie brzmi, czym to sie tak naprawde rozni?

    Jesli chce stworzyc wlasny typ postow np: sport i dodawac codziennie tam po 2-3 posty to nie ma roznicy czy bedzie to page-sport.php lub archive-sport.php?

    Bardzo prosze o pomoc.

    Pozdrawiam

  23. Witaj,

    Świetny poradnik, ale chyba mam gdzieś „czeski błąd” w kodzie i nie mogę tego namierzyć. Czy możesz zaktualizować link do paczki z kodem?

    Mam na mysli to:
    „Niżej znajdują paczka plików do pobrania, zawierająca wszystkie kody źródłowe wykorzystane w tym tutorialu.”

  24. Hej, podobno tworzenie custom postów się trochę zmieniło, jeśli chodzi o taxonomię i się trochę pogubiłam…

    Mam podobny problem do pana w tym wątku https://teamtreehouse.com/community/why-dont-i-see-the-options-to-assign-a-category-in-my-custom-post-type czyli nie widzę możliwośći przypisania kategorii do wpisu podczas jego redagowania, mogę to jedynie zrobić z poziomu listy wpisów za pomocą szybkiej edycji. W odpowiedzi Pan dostał, że trzeba teraz utworzyć własną taxonomię i nie do końca to rozumiem…

    Pomożesz? 🙂

          1. No świetnie, że sobie tak dobrze radzisz, tylko wiesz, zastanawia mnie, czemu musisz stosować takie hacki – ten ticket jest bardzo stary i wszystko to powinno działać sprawnie bez takich sztuczek. Używasz najnowszej wersji WP?

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.