WordPress widget tutorial – piszemy własny widget. Witajcie w trzeciej i ostatniej części kursu dla początkujących, dotyczącej tworzenia widgetów dla WordPress zupełnie od zera.
Zanim przejdziesz dalej, upewnij się, że przerobiłeś dwie ostatnie części:
- W części pierwszej tego kursu, mówiliśmy podstawach tworzenia widgetów dla WordPress. Utworzyliśmy plik z klasą naszego widgetu, na której oparliśmy część drugą i trzecią tego kursu. Plik został podpięty pod motyw, tak byśmy mogli śledzić na bieżąco postępy.
- W części drugiej natomiast, utworzyliśmy kompletny formularz do zarządzania opcjami widget-u z poziomu kokpitu WordPress-a. Uzupełniliśmy także metodę
update()
, służącą do walidacji danych przesłanych przez wspomniany formularz.
Część 3 – WordPress widget tutorial – piszemy własny widget
Przechodząc do części trzeciej powinniśmy mieć już w pełni funkcjonalny widget od strony kokpitu – dodawanie do sidebarów, zapis i odczyt opcji z bazy danych.
W tej części zajmiemy się widgetem od strony frontend-u, czyli tej widocznej dla użytkowników witryny.
Zanim przejdziemy do kodowania, proponuję umieścić nasz nowy widget na wybrany sidebar i wstępnie skonfigurować, tak abyśmy mogli sprawdzać, czy wszystko działa jak należy (np. wybierzmy kategorię w której na pewno mamy jakieś wpisy).
Możemy teraz przejść do metody widget()
w naszym pliku. Na tym etapie chciałbym ją minimalnie zmodyfikować, tak by nie zrobić zbyt dużo bałaganu, a tylko sprawić, że będziemy widzieć, czy idziemy dobrą drogą i czy spodziewany rezultat pokaże się na ekranie.
Mamy taki kod:
public function widget( $args, $instance ) { $title = apply_filters('widget_title', $instance['title']); if (empty($title)) { $title = __('Najnowsze Posty', 'NajnowszePosty'); } echo $args['before_widget']; echo $args['before_title'] . esc_html($title) . $args['after_title']; echo 'Tutaj testowa zawartość'; echo $args['after_widget']; }
Teraz pytanie skąd to wszystko się wzięło? Jak widzisz funkcja widget()
przyjmuje dwa argumenty:
$args
– tutaj znajdują się argumenty dla widgetu przesłane z motywu, ustawione podczas rejestrowania sidebara. Jeżeli pamiętasz wpis o widgetach w sidebarach, to możliwe, że pamiętasz też jak rejestruje się sidebar i jakie opcje można tam ustawić. Chodzi mi obefore_widget
,after_widget
,before_title
,after_title
.$instance
– w skrócie jest to tablica z ustawieniami widget-u pobranymi z bazy danych.
Generalnie, możliwe że z drobnymi przeróbkami, ale powyższy fragment kodu uznać można za punkt bazowy, do którego dodajemy resztę. Ważne, aby pamiętać o dodaniu znaczników, które mają się pojawić przed i po widget-cie, oraz tych pomiędzy nimi – linijka z tytułem ujętym w before_title
i after_title
, a poniżej dodajemy resztę kodu – pobranie wpisów z bazy (custom query), odpowiednio je formatujemy i wyświetlamy uzytkownikowi (the loop).
Oto, co się wyświetliło w tym momencie:
Chodzi o widget znajdujący się w prawej kolumnie. Znaczy, że wszystko jest na dobrym tropie i idziemy w dobrym kierunku. 🙂
Chyba najlepiej będzie jak wkleję od razu cały kod:
public function widget( $args, $instance ) { $title = apply_filters('widget_title', $instance['title']); if (empty($title)) { $title = __('Najnowsze Posty', 'NajnowszePosty'); } echo $args['before_widget']; echo $args['before_title'] . esc_html($title) . $args['after_title']; $query_args = array( 'cat' => implode(",", $instance['categories']), 'posts_per_page' => $instance['number'], 'post_status' => 'publish', 'ignore_sticky_posts' => true, 'orderby' => 'date', 'order' => 'DESC' ); $my_query = new WP_Query($query_args); if($my_query->have_posts()): ?> <ul> <?php while ($my_query->have_posts()): $my_query->the_post(); ?> <li class="clearfix"> <?php if ($instance['show_thumbnail'] == TRUE && has_post_thumbnail()): ?> <div class="thumbnail"> <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('post-icon'); ?></a> </div> <?php endif; ?> <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3> <?php if( $instance['show_excerpt'] == TRUE ): ?> <div class="post-excerpt"> <?php echo substr(get_the_content(), 0, $instance['excerpt_length']); ?> </div> <?php endif; ?> </li> <?php endwhile; ?> </ul> <?php else: ?> <p><?php _e('Nie znaleziono postów spełniających podane kryteria.'); ?></p> <?php endif; /* Restore original Post Data */ wp_reset_postdata(); echo $args['after_widget']; }
Jeżeli napiszemy do tego kawałek CSS, to otrzymamy prawie gotowy widget wyświetlający ostatnie posty. Jak widzisz dodane zostało zapytanie do bazy z argumentami realizującymi nasze potrzeby, a dalej znajduje się pętla wyświetlająca wyniki zapytania. U mnie wygląda to tak:
Chodzi o prawą kolumnę. I jesteśmy prawie u celu.
Uwagi końcowe
Na uwagę zasługują tutaj jeszcze dwie sprawy:
<?php echo substr(get_the_content(), 0, $instance['excerpt_length']); ?>
Proszę zauważyć, że używamy get_the_content()
zamiast the_content()
. Różnica jest taka, że pierwsza tylko zwraca zawartość posta, a nie ją wyświetla. Funkcją substr()
określamy widoczną długość treści posta. Jako trzeci argument wstawiamy ustaloną przez nas wcześniej w formularzu zmienną przechowującą wartość opcji z wymaganą długością wypisu. Można to zrobić na kilka sposobów, np. zamiast ilości znaków brać ilość słów, ale wszystko zależy od aktualnych potrzeb.
Wyświetlanie tak małych miniaturek wykonałem dzięki dodaniu dodatkowego rozmiaru miniatury do motywu:
add_image_size('post-icon', 60, 60, array('center', 'center'));
Dzięki tej instrukcji, podczas wczytywania nowych obrazków do galerii, WordPress sam wykonuje dodatkowy rozmiar miniatury zdjęcia.
Mam nadzieję, że reszta jest zrozumiała, ale oczywiście bardzo chętnie odpowiem na wszystkie pytania. 🙂
No i właściwie jest to już wszystko w tym wpisie i kursie. W najbliższych wpisach chciałbym jeszcze pokazać kilka przykładów związanych z widgetami w WordPress-ie.
Dziękuję za przeczytanie mojego kursu – WordPress widget tutorial – i mam nadzieję, że okazał się pomocny!
Pełny plik php tego przykładu (najnowsze-posty).
Dzięki mistrzu. 🙂
A gdzie dodajemy to??
add_image_size('post-icon', 60, 60, array('center', 'center'));
Może być w
functions.php
– poszukaj innych wywołań tej funkcji w pliku i dodaj pod nimi. Albo na samym końcu, coś takiego:Warto dodać, że lepiej użyć mb_substr zamiast substr()
jak chcemy uniknąć krzaków wynikających z podzielenia na dwu bajtowym znaku unicode.
Dzięki za tutorial bardzo się przydał, tylko pytanie jest takie mam w htmlowym select w option pewien id, niekoniecznie zawartości z WP. Chciałbym po wysłaniu formularza zadać pytanie do bazy (innej niż ta na której stoi wordpress) pobrać jedną kolumnę z tabeli po tym id i wstawić wartość tej kolumny do bazy WP.
To jakie jest to pytanie? 🙂
Do połączenia się z inną bazą danych możesz wykorzystać klasę wpdb
-ustanowić nowe połączenie i korzystać z wbudowanych metod, albo napisać coś swojego w czystym PHP.
Dzięki chodzi o to że mam w ustawieniach widzetu w polu select 3 wartości 1, 2, 3, po zapisaniu ustawień widgeta z wyborem np „1” chcę aby wykonało się zapytanie
$mydb = new wpdb('username','password','database','host');
$data = $mydb->get_results("select slug from moja_tabela where id=tudaj_id_wybrany_z_selecta");
i zwrócony 1 slug chcę wrzucić do bazy wordpressa za pomocą funkcji update przypisując to np do $instance[’slug’]
Jeszcze jedno apropos widgetów, mógłbyś opisać jak stworzyć widżet w którym dane pochodzące od użytkownika, przesyłane poprzez formularz, są zapisywane w bazie danych? Wiem jak stworzyć formularz dla użytkownika, tylko nie wiem jak je zapisać dane w bazie, w konkretnej tabeli.
Jeżeli operujesz na jednej bazie danych, i masz customowe (albo i nie) tabele, to tak to mniej więcej powinno wyglądać:
Jeżeli chcesz się połączyć z inną bazą danych to tworzysz wcześniej nowy obiekt wpdb i na nim operujesz, tak jak podałem we wcześniejszym komentarzu.
W kontekście wordpressa jest też wiele innych możliwości, które pozwalają na zapisywanie różnych danych dotyczących strony, postów, komentarzy i użytkowników, odpowiednio:
https://codex.wordpress.org/Function_Reference/add_option
https://codex.wordpress.org/Function_Reference/add_post_meta
https://codex.wordpress.org/Function_Reference/add_comment_meta
https://codex.wordpress.org/Function_Reference/add_user_meta
W Twoim przypadku, najpierw musisz dodać tego selecta do formularza:
Warto dodać wartość domyślną dla tego pola do tablicy, tak jak jest to pokazane w artykule w metodzie
form()
.Później w metodzie
update()
:Na koniec, jak już masz w zmiennej gotową wartość, wystarczy dodać ją do tabeli
instance
, aby WordPress ją zapisał.Możliwości jest wiele, mam nadzieję, że chociaż trochę Ci to pomoże 🙂
Dzięki, a da rade jakoś wysłać formularz ajaxem z widżeta?
Tu, http://pastebin.com/6c6ZAHnG mi się udało zrobić doklejanie formularza do postów, wysyłanie formularza ajaksem i zapis do bazy jakoś działa, tylko wolałbym ten formularz wstawić w widżecie
Najprościej i najszybicej będzie dodać shortcode. Dodaj do konstruktora:
Pierwsza linijka uruchamia wykonywanie shortcode-ów w widgecie tekstowym
nazwa_shortcode
, tutaj wpisz nazwę shortcode-a, którą będziesz go uruchamiałnazwa_funkcji
, tutaj podaj nazwę metody, która ma ten shortcode obsłużyćMożesz napisać nową funkcję, albo po prostu przerobić Twoją
message_form()
, tak aby zwracała tylko kod formularza.W widgetach, dodaj nowy widget tekstowy, wstaw nowy shortcode i gotowe. 🙂
dzięki działa super
A jak mogę sobie teraz zlokalizować ten plugin ? Wiem że powinienem dodać gdzieś funkcję load_plugin_textdomain(); ale nie wiem w jaki sposób i gdzie 🙁 bez klasy bym sobie pewnie z tym szybciej poradził ale chciałem mieć całość w klasie bo tak mi się łatwiej połapać 🙂
OOP jest zawsze na propsie. 😎
Funkcję
load_plugin_textdomain();
trzeba podpiąć pod hook-ainit
. Do konstruktora dodaj kolejną instrukcję:utwórz w klasie nową metodę
myplugin_load_textdomain
i dodaj do niej funckję ładującą textdomain.dzięki czy ta nazwa myplugin musi odpowiadać czemuś (np taka sama jak nazwa klasy musi być?) czy może być obojętnie jaka? chodzi o to że moja klasa ma bardzo złożoną nazwę i niedługo się może okazać że wyjdzie słowo 64 znakowe jako nazwa klasy 🙂
To tylko przykład.
myplugin_load_textdomain
to dowolna, wybrana przez Ciebie nazwa funkcji w klasie, która będzie uruchomiona przez ten dodany hook w konstruktorze.Ważne aby ten drugi argument w add_action i nazwa metody w klasie się pokrywały.
Pochwalisz się, co tam tworzysz ciekawego? 🙂
nie klasy tylko funkcji oczywiście w ostatnim zdaniu
Na razie nie ma się czym chwalić, prosty komunikator dla zaprzyjaźnionego radia internetowego, taki żeby słuchacze mogli napisać do prowadzącego audycję wprost ze strony. Tylko jeszcze muszę ogarnąć panel odbierania w WP. Na razie odbieranie jest poza WP.
Witam, od razu chciałbym podziękować za ten tutorial 🙂 w pewniej sytuacji bardzo pomógł ale z czasem zabrakło mi 1 funkcjonalności. Czy mógłby Pan mi pomóc?? chodzi o to aby to podobnego widgetu dodać możliwość dodania zdjęcia ?? mam cholerny problem z tym i się strasznie gubię 🙁
Cześć, dzięki za ten zacny komentarz. 😉
To czego potrzebujesz nazywa się WordPress Media Uploader, dzięki któremu będziesz mógł wywołać okienko do wczytania mediów z komputera, albo wybrania ich z biblioteki. Przykład znajdziesz np. tutaj: https://code.tutsplus.com/tutorials/getting-started-with-the-wordpress-media-uploader–cms-22011
W praktyce wygląda to tak, że musisz wczytać skrypty i style CSS tego uploadera przy pomocy takiej specjalnej funkcji:
wp_enqueue_media();
. Uploader załatwi Ci sprawę uploadowania mediów i da profesjnonalnie wyglądający dialog box z wyborem mediów znajdujących się już w bibliotece.Dodatkowo musisz dołączyć skrypt JS, który będzie wyłapywał ścieżkę URL do wybranego medium i wstawiał ją np. do pola tekstowego w celu późniejszego zapisania w bazie.
Aha no i trzeba też dodać dodatkowe pola w formularzu. To wszystko znajdziesz w przykładzie powyżej. Nie sprawdzałem czy działa, ale strona raczej zaufana. 🙂 W razie czego podobnej techniki użyłem kiedyś w moim pluginie MUSLI, możesz go pobrać z repozytorium i użyć jako przykład.
Pozdrawiam
Witam, dziękuje za szybką odpowiedź 🙂 jest to jednak dla mnie bardzo jakoś zamieszane wchodząc na tę stronę powyżej, nie wiem wgl od czego zacząć już teraz 🙁 w których miejscach w widgecie dodać ten kod js ?? jeśli mogę to proszę o pomoc 🙂
Jak dobrze pójdzie to jutro postaram się dokończyć artykuł, w którym wszystko będzie opisane nieco dokładniej.
Witam serdecznie 🙂 w związku z ostatnią Pana odpowiedzą chciałbym sie zapytać czy jest już do wglądu artykuł o którym Pan pisał w ostatniej odpowiedzi ? Pozdrawiam! 🙂
Tak. Tutaj jest artykuł, w którym znajdziesz dokładniejszy opis i przykład, jak to wykorzystać razem z zamieszczonym tutaj widgetem.
http://wpadmin.pl/wordpress-media-uploader-pluginach-motywach/
Pozdrawiam