HTML może być wielką sprawą dla WordPressa

Opublikowany: 2024-05-10

Tworzenie bogatego doświadczenia użytkownika w przeglądarce może być trudnym zadaniem, które często wymaga znacznej ilości kodu JavaScript. Wraz ze wzrostem potrzeb i ambicji naszej aplikacji rośnie także złożoność naszego kodu JavaScript. Nie jest zatem zaskoczeniem, jak często programiści zmieniają sposób, w jaki myślimy i piszemy o aplikacjach JavaScript.

Dni od ostatniego frameworku JS.

Twórcy wtyczek WordPress mają gorzej. Środowisko, na które kierujemy, nie jest serwerem, nad którym mamy kontrolę, ani takim, który ma pełną kontrolę nad całą stroną. Chociaż bardzo możliwe jest pomyślne użycie frameworka JavaScript we wtyczce WordPress, niezwykle łatwo może być również stworzenie projektu, którego skala i złożoność przekraczają zamierzenia lub oczekiwania.

Ale co, jeśli nie musiało tak być? W tym artykule zbadamy, w jaki sposób nowoczesne interfejsy internetowe są budowane przy użyciu JavaScript, trudności, z jakimi borykają się programiści, oraz alternatywę oferowaną przez HTML. W szczególności przyjrzymy się, dlaczego HTML i WordPress mogą być idealnym połączeniem.

Jak tu dotarliśmy

Przed JavaScriptem przeglądarki były po prostu gloryfikowanymi czytnikami dokumentów. W związku z tym większość doświadczeń w Internecie to „aplikacje wielostronicowe”, w skrócie MPA. MPA to aplikacje internetowe składające się z wielu dokumentów HTML, po jednym dla każdej strony aplikacji. Gdy użytkownik korzysta z aplikacji, wyświetlane są mu różne dokumenty z różnymi dostępnymi działaniami.

Budowa MPA jest bardzo prosta. Nawigacja odbywa się za pomocą znaczników <a> , które łączą się z innymi dokumentami, a dane wprowadzane przez użytkownika można przechwycić za pomocą elementu <form> . Serwer odpowiada na żądania linków i formularzy nowymi dokumentami HTML, zastępując stronę wyświetlaną na ekranie.

Dobrym przykładem MPA, który prawdopodobnie dobrze znasz, jest WP Admin. Każda strona administracyjna to dokument HTML generowany przez kod PHP WordPress działający na serwerze. Większość stron w WP Admin, podobnie jak strony ustawień WordPress, składa się głównie z formularzy, które Ty, użytkownik, możesz przesłać.

I odwrotnie, aplikacja jednostronicowa (SP) to aplikacja korzystająca z pojedynczej strony HTML. Nawigacja i wprowadzanie danych przez użytkownika są następnie obsługiwane przez kod JavaScript, dynamicznie zmieniający części strony na miejscu, bez konieczności zamieniania całej strony lub jej odświeżania. Zapewnia to płynniejszą i bardziej responsywną obsługę użytkownika.

Obecnie wiele aplikacji internetowych wykorzystuje SPA jako interfejs sieciowy. W RebelCode zbudowaliśmy SPA dla interfejsów administracyjnych naszych dwóch głównych wtyczek WordPress: Spotlight i Aggregator. Stosunkowo nowy edytor witryn w WordPressie to także SPA, podobnie jak blokowy edytor postów.

Cena, którą płacimy

SPA to własne aplikacje, napisane w JavaScript i działające w przeglądarce. Ich własna definicja jest jednocześnie ich największym zastrzeżeniem: nie mają bezpośredniego dostępu do zasobów serwera. Oznacza to, że musimy ustalić kanał komunikacji pomiędzy SPA a serwerem.

Stwórzmy prostą wtyczkę WordPress, aby skorzystać z przykładu. Ta wtyczka zapewnia
prosty interfejs użytkownika CRUD do zarządzania książkami. Wewnętrzne API wtyczki na serwerze może wyglądać mniej więcej tak:

 <?php function get_books(?int $count = null, int $page = 1): Book[]; function get_book(int $id): Book; function insert_book(Book $book): Book; function update_book(Book $book): Book; function delete_book(int $id): void;

Aby stworzyć nasz nowoczesny interfejs SPA, użyjemy frameworku JavaScript, takiego jak React; najpopularniejszy framework JavaScript, z którego korzysta także WordPress. Zacznijmy od dodania strony administracyjnej:

 <?php add_action('admin_menu', function () { add_menu_page('Books', 'Books', 'manage_options', 'books', 'books_page'); }); function books_page() { echo '<div></div>'; }

Nasza strona wyrenderuje pojedynczy, pusty element <div> , który posłuży jako korzeń naszej aplikacji React, gdzie będzie renderowana reszta interfejsu użytkownika.

 const rootEl = document.getElementById("books-app"); const root = ReactDOM.createRoot(rootEl); root.render(<BooksApp />); function BooksApp() { return ( <div> <h1>My Books</h1> ... </div> ); }

Jak więc wyświetlić listę książek przechowywanych w bazie danych? Kod do wykonania tej operacji znajduje się na serwerze, więc potrzebujemy sposobu, aby go wywołać i uzyskać wynik.

Aby to zrobić, możemy udostępnić API JSON z serwera. Aplikacja React może następnie wysłać żądanie pod adresem URL naszego interfejsu API, odebrać książki w formacie JSON, a następnie wyrenderować listę. W tym przykładzie załóżmy, że dodaliśmy punkt końcowy do interfejsu API REST WordPress:

 GET https://my-wp-site.com/wp-json/books { "books": [ { "id": 15, "title": "Mistborn", "author": "Brandon Sanderson", }, { "id": 44, "title": "The Hobbit", "author": "JRR Tolkien", }, ] }

Następnie możemy napisać komponent React, który pobiera książki i wyświetla je jako listę:

 function BookList() { const [books, setBooks] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect( function () { setIsLoading(true); fetch("https://my-wp-site.com/wp-json/books") .then((res) => res.json()) .then((data) => setBooks(data.books)) .else((error) => setError(error)) .finally(() => setIsLoading(false)); }, [setBooks, setIsLoading], ); if (isLoading) { return <div>Loading...</div>; } if (error) { return <div>Error: {error}</div>; } return ( <ul> <li> {books.map((book) => ( <a key={book.id} href={book.url}> {book.title} </a> ))} </li> </ul> ); }

Ale to rozwiązanie jest zbyt naiwne i powoduje trudne wrażenia użytkownika. Nie uwzględnia zmian stanu po odmontowaniu komponentu, buforowaniu odpowiedzi, ponawianiu nieudanych zapytań ani zapobieganiu nadpisywaniu nowszego stanu przez nieaktualny stan. W rzeczywistości sposób, w jaki używamy fetch() w efekcie React, jest ogólnie odradzany.

Pod wieloma względami może to być gorsze niż tradycyjne MPA. Aby zrobić to poprawnie, będziemy musieli zaimplementować w naszym kliencie jeszcze kilka rzeczy. Lub, bardziej realistycznie, użyj pakietów stron trzecich.

Ale wszystko to zaczyna wydawać się nieproporcjonalnym wysiłkiem, aby wyrenderować listę książek. Czy naprawdę musimy tworzyć aplikację JavaScript i API JSON, aby zapewnić płynną obsługę użytkownika?

Porównajmy to z MPA, gdzie wyświetlenie listy książek można wykonać w zaledwie kilku linijkach kodu PHP, bez żadnych zależności:

 <?php function render_books() { ?> <ul> <?php foreach (get_books() as $book): ?> <li> <a href="<?= $book->url ?>"> <?= $book->title ?> </a> </li> <?php endforeach; ?> </ul> <?php }

Ale oczywiście nie jest to uczciwe porównanie. Ta lista książek to po prostu statyczny kod HTML; nie reaguje na zmiany stanu ani dane wejściowe użytkownika.

Jeśli chcemy uzyskać wrażenia podobne do SPA, jednocześnie renderując kod HTML na serwerze, gdzie nasz kod ma natychmiastowy dostęp do bazy danych, musimy znaleźć sposób, aby renderowany przez serwer kod HTML trafił do przeglądarki i zastąpić poprzednią listę książek. Jednak osiągnięcie tego bez żadnego kodu JavaScript jest obecnie niemożliwe, więc musielibyśmy przejść do rzeczy i mimo wszystko używać JavaScript.

Ale nie musimy tego pisać sami.

Przedstawiamy HTML

HTMX to mała biblioteka JavaScript, która przede wszystkim robi jedną rzecz: pozwala HTML na żądanie nowego HTML z serwera. Robi to za pomocą nowych atrybutów, które pozwalają nam powiedzieć HTMX, skąd pobrać nowy kod HTML, na co go zamienić i co uruchamia zamianę. Działa jako pomost pomiędzy naszym serwerem HTML a stroną w przeglądarce.

To zupełnie inny sposób myślenia o SPA, ponieważ nie tworzymy klienckiej aplikacji JavaScript w celu aktualizacji bieżącej strony. Zamiast tego po prostu dodajemy pewne atrybuty HTML, aby poinformować HTML, jak strona ma się zmieniać, gdy wystąpią określone zdarzenia.

Nawet bez HTML możesz już zmieniać to, co jest wyświetlane na ekranie, używając samego HTML, aczkolwiek w bardzo ograniczony sposób. Znasz już tę funkcję HTML: skromny element linku <a> .

 <a href="https://my-wp-site.com/books">View books</a>

Element link daje przeglądarce wszystkie informacje niezbędne do przeprowadzenia nawigacji. Po kliknięciu przeglądarka pobiera href z elementu, wysyła żądanie pod ten adres URL, pobiera odpowiedź i zakładając, że zawierała ona kod HTML, zastępuje zawartość strony nowym kodem HTML.

Element <form> to kolejny przykład tego, jak HTML może zażądać nowego HTML.

 <form action="/contact.php"> <label> Your message: <input type="text" name="message" /> </label> <button type="submit">Send message</button> </form>

Tym razem przeglądarka zbiera wartości ze wszystkich wejść w formularzu, wysyła je do serwera, pobiera odpowiedź i wyświetla ją na ekranie.

Dlaczego tylko <a> i <form> powinny móc wysyłać żądania HTTP? Dlaczego wymiana może dotyczyć tylko całego ekranu?

Z pliku Readme GitHuba HTMX

Cóż, HTML to zmienia.

 <a href="https://my-wp-site.com/books" hx-target="#books"> View books </a> <div></div>

Dzięki atrybutowi HTMX hx-target kliknięcie linku spowoduje umieszczenie odpowiedzi z https://my-wp-site.com/books wewnątrz elementu z identyfikatorem "books" . Oczywiście osadzenie strony w innej nie jest tu celem. Nasz serwer nie musi odpowiadać całą stroną, może zamiast tego po prostu odpowiedzieć fragmentem HTML.

Ujawniając fragmenty HTML z naszego serwera i informując HTML, jak, skąd i kiedy pobrać te fragmenty, możemy stworzyć aplikację internetową przypominającą SPA bez JavaScript, nad którą serwer ma pełną kontrolę. W pewnym sensie HTML stał się naszym nowym JSON-em.

Wszystko, co musimy zrobić, to załadować skrypt HTML na naszą stronę:

 <script src="https://unpkg.com/[email protected]"></script>

(Pamiętaj o zapoznaniu się z dokumentacją HTML w celu uzyskania instrukcji, ponieważ powyższy kod może być nieaktualny).

Spójrzmy na inny przykład:

 <button hx-get="/button/off" hx-target="this" hx-swap="outerHTML"> Turn off </button>

Dzieje się tu dużo więcej, więc podzielmy to na części:

  • hx-get określa adres URL, na który ma zostać wysłane żądanie GET po kliknięciu przycisku.
  • hx-target="this" mówi HTMX, aby zamienił kliknięty przycisk z odpowiedzią.
  • hx-swap="outerHTML" mówi HTMX, aby zamienił cały przycisk, a nie tylko to, co jest w środku.

Wszystko razem mówi HTMX:

Po kliknięciu przycisku wyślij żądanie GET do /button/off i zastąp ten przycisk odpowiedzią.

Załóżmy, że serwer odpowiada na /button/off poniższym kodem HTML:

 <button hx-get="/button/on" hx-target="this" hx-swap="outerHTML"> Turn on </button>

Czy widzisz różnicę? Atrybut hx-get wskazuje teraz na /button/on , a tekst wewnątrz przycisku brzmi teraz „Włącz”. Po kliknięciu tego przycisku zostanie on również zastąpiony odpowiedzią z /button/on . Jak możesz sobie wyobrazić, serwer może odpowiedzieć oryginalnym przyciskiem, aby zakończyć przełączanie!

Ten prosty pomysł, aby dowolny element mógł zażądać od serwera nowego kodu HTML i zdecydować, dokąd ten kod HTML ma trafić, okazuje się całkiem skuteczny. Możemy tworzyć zakładki, wyszukiwać wyniki na żywo, paski postępu i nie tylko.

Plusy i minusy

W przeciwieństwie do większości frameworków JavaScript, HTML nie wymaga kompilacji i spakowania kodu aplikacji klienckiej. Już samo to jest ogromną korzyścią; Systemy kompilacji JavaScript mogą być niezwykle trudne w konfiguracji i utrzymaniu, zwłaszcza gdy zaczynasz wprowadzać bardziej egzotyczne funkcje i biblioteki, takie jak TypeScript, JSX, preprocesory CSS itp. Nierzadko zdarza się, że średnie i duże zespoły mają jednego lub więcej członków wyznaczonych do tego zadania.

Kolejną oczywistą korzyścią jest brak osobnej aplikacji klienckiej. Ponieważ potrzebujemy tylko serwera HTTP odpowiadającego HTML, możemy użyć dowolnego języka programowania, który nam się podoba. Może to być dla Ciebie duży atut, jeśli Twój zespół nie zna współczesnego JavaScriptu lub nie jest wystarczająco duży, aby uzasadnić zbudowanie dwóch aplikacji. Może to być szczególnie kuszące, jeśli jesteś twórcą wtyczek WordPress, ponieważ możesz używać PHP do wszystkich aspektów swojej wtyczki.

Ale być może najważniejszą korzyścią jest to, że nie potrzebujesz już interfejsu API pomiędzy back-endem a front-endem swojej aplikacji. Może to zaoszczędzić ogromną ilość czasu na programowanie, a także zmniejszyć ilość kodu mogącego powodować błędy, co również oszczędza czas w dłuższej perspektywie.

Nie powinniśmy jednak być na tyle naiwni, aby zakładać, że korzystanie z HTML oznacza brak konieczności pisania kodu JavaScript. Do operacji takich jak przeciąganie i upuszczanie, tworzenie wykresów, wybieranie kolorów i dat itd. może być nadal wymagana pewna ilość kodu JavaScript. Chociaż zawsze możemy korzystać z rozwiązań niezależnych od frameworka, takich jak SortableJS i Floating UI. Ponadto w przyszłości możemy zauważyć mniejsze zapotrzebowanie na JavaScript, ponieważ standardy sieciowe będą ewoluować wraz z nowymi elementami HTML, takimi jak niedawny element <dialog> .

Po drugie, PHP, jak na ironię, nie jest zbyt dobry w tworzeniu szablonów HTML, mimo że został zbudowany właśnie do tego. Jego składnia znaczników jest zbyt gadatliwa, a składnia ciągów HereDOC ma ograniczoną obsługę interpolacji ciągów.

Wreszcie utworzenie punktu końcowego w WordPressie nie jest bardzo proste. Rozważmy wtyczkę książek z poprzednich przykładów. Musimy mieć ścieżkę na serwerze, która w odpowiedzi wyświetli listę książek w formacie HTML. Jak zarejestrować ten punkt końcowy?

  • Wykryć parametr GET podczas akcji init lub admin_init ?
  • Korzystasz z interfejsu API Ajax administratora?
  • Zarejestrować punkt końcowy interfejsu API REST?
  • Dodać niestandardową regułę przepisywania?

Opcji jest wiele, ale żadna nie sprawia, że ​​jest to tak proste, jak powinno.

HATEOAS

W naszym poprzednim przykładzie istnieje subtelny szczegół, który bardzo łatwo przeoczyć, a gdy już go zwrócimy, będzie on prawdopodobnie wydawał się oczywisty.

Kiedy otrzymamy kod HTML z serwera, przycisk na stronie jest albo w wariancie WŁĄCZONYM, albo WYŁĄCZONYM. W zależności od tego, który z nich jest wyświetlany na ekranie, działanie po kliknięciu będzie inne.

Dzięki temu przeglądarka nie musi rozumieć naszej aplikacji. Zwykle sprawilibyśmy , że przeglądarka zrozumiałaby, podając kod JavaScript do jawnego programowania wszystkich zachowań. Teraz mamy tylko HTML, a przeglądarka nie potrzebuje wcześniejszej wiedzy o tym, jak zachowuje się nasza aplikacja ani jaki jest jej stan. Wystarczy, że wyrenderuje na ekranie kod HTML, który sam koduje stan naszej aplikacji.

Ten typ architektury znany jest jako HATEOAS, co oznacza „Hypermedia jako silnik stanu aplikacji”. Jest to wyspecjalizowany typ architektury REST, który wykorzystuje hipermedia jako medium do przenoszenia stanu, a te same hipermedia stają się interfejsem, za pośrednictwem którego użytkownik wprowadza aplikację w nowe stany.

Jeśli chcesz dowiedzieć się więcej, witryna HTMX zawiera bogatą kolekcję artykułów, esejów i rozmów na ten temat. Na potrzeby tego artykułu przejdźmy do tego, dlaczego HTML może być tak ważny dla programistów WordPressa.

HTML <3 WordPress

WordPress to gigantyczny, monolityczny serwer PHP. Wtyczki WordPress są również pisane głównie w języku PHP. Mogą dodawać nowe funkcje do witryny za pomocą interfejsów API PHP udostępnianych przez WordPress, takich jak API Hooks i API Database. Te interfejsy API nie są dostępne w języku JavaScript, dlatego twórcy wtyczek powinni chcieć zachować jak najwięcej kodu wtyczki na serwerze. Jeśli kiedykolwiek istniała motywacja do korzystania z HTML, to właśnie ona!

Pod wieloma względami HTML został stworzony dla WordPressa. A raczej dla aplikacji takich jak WordPress; aplikacji, które wolełyby nie być obarczone językiem obcym zmuszającym je do porzucenia kolekcji API serwerów. Zwłaszcza nie wtedy, gdy wystarczyłoby zwykłe przeniesienie stanu za pomocą hipermediów.

Ułatwienie tworzenia dobrych interfejsów użytkownika dla wtyczek WordPress może mieć dramatyczny wpływ na ekosystem wtyczek. Programiści obsługujący bezpłatne wtyczki mogą uznać za bardziej wykonalne tworzenie lepszych doświadczeń dla swoich użytkowników, a mniejsze zespoły mogą móc szybciej iterować funkcje, oszczędzając czas. Może to pomóc w zwiększeniu konkurencyjności mniejszych wtyczek na rynku silnie zdominowanym przez duże zespoły z jeszcze większymi budżetami.

Większe wtyczki również mogą być szczególnie zainteresowane. Aplikacje JavaScript mogą rozwijać się wykładniczo szybko. HTML może pozwolić tym wtyczkom na usunięcie ich ogromnych interfejsów API JSON i aplikacji JavaScript i pozostawienie w ich miejscu oszczędnego serwera HTML, który ma pełny dostęp do interfejsów API WordPress.

Końcowe przemyślenia

Od jakiegoś czasu bawię się HTML-em, używając go z PHP i Go. Oferuje atrakcyjną alternatywę w budowaniu interfejsów użytkownika w Internecie i przekonujący argument za używaniem hipermediów do sterowania stanem aplikacji.

Jeśli jesteś twórcą wtyczek, koniecznie sprawdź HTML. W tym artykule ledwo zarysowaliśmy powierzchnię, a dokumentacja jest bardzo dobrze napisana i zawiera wiele przykładów. Jest także zaskakująco krótki, biorąc pod uwagę, ile HTML zawiera od razu po wyjęciu z pudełka. Powinieneś być w stanie rozpocząć pracę z HTML i PHP w ciągu kilku minut.