W tej ostatniej części serii samouczków dotyczących bloków niestandardowych Gutenberga dowiemy się, jak używać komponentów wyższego rzędu do wykorzystywania komponentów WordPress do wykonywania zapytań o posty i innych podstawowych informacji WordPress.
W poprzedniej części dowiedzieliśmy się o blokach dynamicznych i zakończyliśmy implementację funkcjonalności do wpisywania identyfikatora posta i używania PHP do dynamicznego pobierania posta i renderowania go w trybie frontendu i podglądu. Ręczne wpisywanie identyfikatora posta nie jest intuicyjne ani przyjazne dla użytkownika. O wiele lepiej jest zapewnić użytkownikowi możliwość wybierania lub wyszukiwania postów według tytułu posta i klikania na coś, aby wybrać jeden.
Jedna część rozwiązania tego problemu jest dość łatwa; jak wyszukiwać posty z edit
funkcji Twojego bloku. Mamy na to kilka opcji, a najlepszą opcją jest użycie niektórych tak zwanych komponentów wyższego rzędu z WordPressa. Możesz również użyć metod przeglądarki JavaScript, aby wykonać wywołanie AJAX w kierunku interfejsu API REST WordPress, na przykład [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
lub axios. WordPress faktycznie udostępnia własną wersję fetch
: apiFetch()
.
Druga część rozwiązania tego problemu zależy od ciebie; czyli jak przedstawić listę lub wybór w naszym bloku. Jak zamierzasz zaprezentować listę postów do wyboru? Na liście wyboru, na liście pól wyboru lub przycisków radiowych? A może chcesz zaoferować możliwość wyszukiwania, a tym samym wdrożyć rozwiązanie autouzupełniania lub rozwiązanie filtrujące? Czy zezwolić na wybieranie wielu postów, czy tylko jednego? Zwykle możesz rozwiązać ten problem, używając różnych komponentów WordPress, ale musisz zdecydować, które rozwiązanie chcesz wdrożyć.
Nauczmy się najpierw trochę o komponentach wyższego rzędu i module danych WordPress, zanim przyjrzymy się, jak możemy wykonywać zapytania post w naszym bloku.
Moduł WordPress Core Data i komponenty wyższego rzędu
Podczas pracy z Reactem często będziesz musiał przekazać stan do komponentów potomnych lub w górę do wspólnego komponentu rodzicielskiego, aby wszystkie inne komponenty potomne miały do nich dostęp. Rozwiązaniem problemu centralizacji stanu aplikacji jest użycie Redux. Dzięki Redux możesz budować sklepy — czyli obiekty, które przechowują stan i informacje o aplikacji.
Moduł danych WordPress jest centrum różnych sklepów i zapewnia funkcje zarządzania danymi między różnymi modułami. Jest zbudowany na bazie Redux – ale nie pomyl go jako Redux dla WordPressa, ponieważ istnieje kilka różnic. Możesz zarejestrować własne sklepy w WordPressie lub, co ważniejsze, uzyskać dostęp do zarejestrowanych sklepów WordPress.
Oto przegląd dostępnych sklepów w module danych WordPress (prawdopodobnie z czasem się zmieni). Wszystkie sklepy WordPressa zawarte są w module Core Data. Na przykład są sklepy przechowujące dane edytora (core/editor
), uwagi (core/notices
), dane bloków (core/blocks
), informacje o rzutni (core/viewport
) i wreszcie sam główny sklep – core
.
Aby uzyskać dostęp do danych ze sklepów, musisz użyć selektorów. WordPress ma selektor w wp.data
pakiecie; [select](https://developer.wordpress.org/block-editor/packages/packages-data/#select)()
. Możesz także manipulować sklepami za pomocą programu dispatch
, ale nie jest to omówione w tej serii samouczków. Możesz naprawdę łatwo wypróbować selektor, aby zobaczyć, co jest dostępne w sklepach WordPress.
Wypróbowanie selektora
Otwórz edytor Gutenberg w Chrome i otwórz narzędzie do debugowania konsoli. Wpisz:
wp.data.select('core')
I naciśnij Enter. Powinieneś otrzymać obiekt jako odpowiedź ze wszystkimi selektorami (funkcjami), których możesz użyć. Jako przykłady znajdziesz funkcje takie jak getMedia
, getTaxonomy
, getAuthors
i tak dalej. Ten, którego użyjemy do zapytania o posty, również tam jest, ale nie ma intuicyjnej nazwy; to się nazywa getEntityRecords
. W tej chwili niektóre z tych funkcji są udokumentowane, ale większość niestety nie.
Wypróbuj także inne sklepy niż core
, na przykład:
wp.data.select('core/editor').getBlocks()
Spowoduje to zwrócenie wszystkich informacji o wszystkich blokach znajdujących się obecnie w Twoim poście. Możesz pobawić się tym w debugerze konsoli Chrome i spróbować wywołać niektóre funkcje, aby zobaczyć, co otrzymasz w odpowiedzi. Niektóre wymagają parametrów, a inne nie.
Aby korzystać z selektorów i dostępu do sklepów, musimy ich używać w komponentach wyższego rzędu. Komponenty wyższego rzędu to po prostu wzór robienia czegoś w React. Przekazujemy komponent do funkcji (lub komponentu), która może dodać jakieś właściwości, a następnie zwracamy nowy komponent.
Wewnątrz modułu danych WordPress znajdujemy [withSelect](https://developer.wordpress.org/block-editor/packages/packages-data/#withSelect)
; komponent wyższego rzędu, który można wykorzystać do wstrzykiwania rekwizytów za pomocą zarejestrowanych selektorów. Innymi słowy; wewnątrz withSelect
mamy dostęp do selektora select()
i możemy go używać do wykonywania połączeń. Wynikiem selektora będą właściwości komponentu, do którego przekazujemy withSelect
. Jeśli potrzebujesz połączyć wiele komponentów wyższego rzędu, moduł danych WordPress oferuje tę compose
funkcję, ale jest to poza zakresem tego samouczka. Użyjemy tylko jednego komponentu wyższego rzędu; withSelect
.
To było dużo teorii, więc zacznijmy przyglądać się kodowi i praktycznym przykładom.
Pobieranie postów za pomocą withSelect, select and getEntityRecords
Podsumowując powyższe, musimy ustawić komponent wyższego rzędu withSelect
dla naszego bloku. Wewnątrz tego możemy użyć selektorów, aby uzyskać dostęp do sklepów WordPressa, które będą rekwizytami dla komponentu, do którego przekazujemy withSelect
. Wykorzystamy core
sklep i selektor getEntityRecords
do wyszukiwania postów.
Funkcja getEntityRecords
ta jest niestety w tej chwili mało udokumentowana . Ale nauczyłem się, że możemy przekazać postType
jako pierwszy parametr (rodzaj encji), a następnie jako drugi parametr typ posta (np. ‘ post
‘ lub ‘ page
‘). Trzeci parametr jest opcjonalny i może być obiektem z argumentami zapytania. Trzeciemu parametrowi przyjrzymy się później.
Jeśli postępowałeś zgodnie z tą serią samouczków z poprzedniej części, miałbyś niestandardowy blok, który akceptuje ręcznie wpisywany identyfikator posta we wprowadzaniu tekstu. Blok używa PHP do dynamicznego renderowania posta w interfejsie użytkownika (oraz w trybie podglądu). Usuńmy wymóg ręcznego wpisywania identyfikatora posta i zastąpmy go czymś bardziej intuicyjnym. Jak wspomniano wcześniej, musisz sam zdecydować, jak prezentować listę postów i jak najlepiej pozwolić użytkownikowi wybrać post. Dla uproszczenia dodamy do wyboru wszystkie tytuły postów.
KodowaniewithSelect
Zacznijmy to kodować. Najpierw musimy zdestrukturyzować to, czego potrzebujemy z pakietu danych;
const { withSelect, select } = wp.data;
Następnie używamy withSelect
w naszym bloku edit
funkcji i przekazujemy nasz komponent edycji; FirstBlockEdit
. Wewnątrz withSelect
destrukturyzujemy select
jako parametr i używamy selektora select()
do zapytania o posty za pomocą getEntityRecords
. Zwracamy obiekt z jedną właściwością, którą wywołujemy posts
, która przechowuje wynik select()
wywołania.
Z kodem powyżej naszego komponentu, FirstBlockEdit
, będzie miał teraz nową właściwość; posts
. Cokolwiek zwrócimy wewnątrz withSelect
komponentu wyższego rzędu, będzie dostępne jako rekwizyty dla komponentu, który przekazujemy (w nawiasie na samym końcu).
Obsługa postów z selektora
Możemy teraz przejść do naszego komponentu FirstBlockEdit
i przyjrzeć się nowemu props.posts
. Ponieważ nasz komponent jest komponentem opartym na klasach, musimy odwołać się do props za pomocą this
. Wylogujmy to w konsoli wewnątrz render()
funkcji w FirstBlockEdit
:
render() {
const { attributes, setAttributes } = this.props;
console.log(this.props.posts);
...
}
Miej oko na debugger konsoli. Możesz zauważyć, że zostanie to zarejestrowane dwukrotnie; najpierw null
, a potem jakiś czas później rejestruje tablicę postów. Dzieje się tak, ponieważ zapytania o posty są wykonywane asynchronicznie. Nasz komponent jest najpierw renderowany przed odpowiedzią, w którym to czasie props.posts
jest null
. Gdy otrzymamy odpowiedź, nasz komponent jest ponownie renderowany z wypełnioną propozycją. Należy zawsze pamiętać o przystosowaniu się do tego niewielkiego czasu bez danych w kodzie.
Dodanie wyboru, aby wyświetlić posty
Przygotujmy się do wypełnienia selekcji zwróconymi postami, a do tego użyjemy komponentu WordPress SelectControl
. Komponent SelectControl
akceptuje tablicę wyborów, gdzie każdy wybór jest obiektem z właściwościami value
i label
.
Jeśli spojrzysz na zarejestrowaną w konsoli (drugą) odpowiedź, zobaczysz, że otrzymujemy tablicę obiektów postów. Każdy post zawiera większość informacji o poście, ale w przypadku opcji wyboru interesuje nas tylko identyfikator posta jako wartość i tytuł posta jako etykieta. Przejdziemy więc przez właściwość posts
i wypełnimy zmienną tablicową, do której przekażemy SelectControl
. Nie zapomnij zająć się małymi ramami czasowymi, w których znajduje się posts
rekwizyt null
. W takim przypadku wypełnimy tablicę wyboru jedną opcją, która ma etykietę „Ładowanie…".
Pamiętaj, że musimy odnieść się do tytułu posta jako post.title.rendered
. Możesz poszukać siebie w zalogowanej konsoli posts
i zobaczyć strukturę informacji dla każdego postu.
Po tym wystarczy dodać, SelectControl
gdzie chcemy. Może znajdować się wewnątrz samego bloku (najlepiej w kodzie trybu edycji) lub wewnątrz Inspectora.
Ustawiamy, SelectControl
aby odnosiło się do atrybutu selectedPostId
, który zdefiniowaliśmy w poprzednim kroku. Ustawiamy zapisaną wartość w rekwizycie value
i zajmujemy się aktualizacją w onChange
rekwizycie – tak jak robiliśmy to kilka razy wcześniej. Zapewniamy, że numer jest przechowywany przy użyciu, parseInt()
ponieważ selectedPostId
ma typ number
. I przekazujemy wygenerowaną tablicę wyborów w prop options
.
To naprawdę wszystko! Jeśli podążałeś za kodem z poprzedniego kroku, powinieneś już mieć kod, który odczytuje zapisany identyfikator posta i wyświetla go!
Oczywiście radzę zaimplementować listę i wybór postów w inny sposób niż zwykły wybór. Nie jest to ładne ani przyjazne rozwiązanie, zwłaszcza w przypadku witryn z dużą ilością postów. Mówiąc o liczbie postów, czy zauważyłeś, że selektor getEntityRecords zwraca maksymalnie 10 ostatnich postów? Jest to domyślne zachowanie getEntityRecords, ale możemy zmodyfikować zapytanie post, przekazując trzeci parametr.
Zmodyfikuj zapytanie dla getEntityRecords
Przekazując obiekt jako trzeci parametr do getEntityRecords możemy zmodyfikować zapytanie post. Jak wspomniano wcześniej, niestety getEntityRecords
brakuje dokumentacji. Ale czytając w całej sieci, zebrałem listę możliwych argumentów zapytania;
per_page
: Ustaw liczbę, aby ograniczyć liczbę postów. Ustaw,-1
aby pobrać maksymalnie 100. Domyślnie10
.exclude
: Wyklucz niektóre posty z zapytania. Ustaw identyfikator posta lub tablicę liczb dla wielu identyfikatorów postów.parent_exclude
: Wyklucz niektóre posty nadrzędne. Ustaw na identyfikator posta lub tablicę wielu identyfikatorów posta.orderby
: Zdecyduj kolejność postów. Najprawdopodobniej możesz użyć tych samych parametrów, co w zamówieniu WP_Queryby. Może być np. „menu_order
“.order
: Albo'asc'
lub ‘desc'
dla porządku rosnącego lub malejącego.status
: Filtruj według statusu posta. Może być ciągiem, ciągiem znaków z wieloma statusami oddzielonymi przecinkiem lub tablicą ciągów statusu. Np['publish', 'draft']
. do zapytania zarówno opublikowanych, jak i przygotowanych postów.categories
: Filtruj posty według określonych kategorii. Podaj identyfikator kategorii lub tablicę identyfikatorów kategorii. Uważam, że działa to tylko w przypadku kategorii postów, a nie innych niestandardowych taksonomii.tags
: Filtruj posty według określonych tagów. Podaj identyfikator tagu lub tablicę identyfikatorów tagów. Działa tylko w przypadku tagów postów, a nie innych niestandardowych taksonomii.search
: Dodaj zapytanie wyszukiwania (ciąg).
Uwaga: to nie jest wyczerpująca lista i również może ulec zmianie!
Zmodyfikujmy nasze zapytanie. Chcemy zrobić dwie rzeczy; najpierw chcemy pobrać wszystkie posty, a nie tylko 10 ostatnich. W tym celu -1
zapewniamy per_page
. Po drugie, chcemy wykluczyć bieżący post z listy postów, podając identyfikator aktualnego posta do exclude
. Często nie ma sensu pokazywać skrótu do wpisu lub podglądu samego bieżącego wpisu.
Możesz pomyśleć; poczekaj, jak otrzymamy aktualny identyfikator posta? Nie zapominaj, że w ramach komponentu wyższego rzędu withSelect
i za pomocą select
selektora możemy uzyskać dostęp do wszystkich baz danych WordPressa. Obecny identyfikator posta to naturalna rzecz do przechowywania w jednym z głównych sklepów WordPress. Wewnątrz core/editor
znajdujemy funkcję getCurrentPostId()
.
Zmodyfikujmy withSelect
powrót do czegoś takiego:
Powyższa zmiana jest dość oczywista. Generujemy obiekt zapytania z właściwościami per_page
i exclude
przekazujemy go jako trzeci parametr do getEntityRecords()
. Teraz nasz props.posts
komponent FirstBlockEdit
powinien zawierać listę wszystkich postów, ale wykluczyć bieżący post.
Wniosek
Ten post kończy serię samouczków Jak tworzyć niestandardowe bloki Gutenberga. Seria miała na celu zapoznanie się z podstawami tworzenia własnych niestandardowych bloków, zapewniając punkt wyjścia do tworzenia własnych i bardziej złożonych bloków. Zdecydowanie miej oko na więcej samouczków związanych z Gutenbergiem tutaj. Może znajdziesz samouczek bardziej szczegółowo wyjaśniający coś, co chciałeś zrobić sam!