Budowanie modala wyszukiwania dla stron WordPress z ograniczonym dostępem (membership)
Większość poradników dotyczących wyszukiwania w WordPress kończy się na dodaniu widgetu do nagłówka.
To podejście zawodzi, gdy masz treści chronione, takie jak płatne kursy czy prywatne wideo. Domyślna wyszukiwarka ujawni tytuły Twoich prywatnych materiałów niezalogowanym użytkownikom.
Zbudowałem modal wyszukiwania na żywo dla strony z członkostwem fitness. Strona korzysta z WordPress, WooCommerce, Divi, LearnDash i WishList Member.
Oto jak zbudować wyszukiwarkę, która szanuje Twoją ścianę płatności (paywall).
Architektura
Użyłem jednolitego indeksu z filtrowaniem uwzględniającym uprawnienia dostępu. Wybrałem to rozwiązanie, aby mieć pewność, że niezalogowany użytkownik nigdy nie zobaczy tytułu ani fragmentu posta dostępnego tylko dla członków.
Interfejs użytkownika (UI) wykorzystuje ikonę, która otwiera nakładkę (overlay) na pełny ekran. Oszczędza to miejsce na urządzeniach mobilnych i wygląda czyściej niż ciasny pasek wprowadzania danych.
Backend
Wszystko działa poprzez jedną, niestandardową trasę (route) REST w motywie potomnym (child theme).
Kluczowe zasady techniczne:
- Zabezpiecz zależności: Użyj sprawdzania funkcji dla wtyczek wyszukiwania, takich jak Relevanssi. Jeśli wtyczka nie jest zainstalowana, wyszukiwarka powinna przejść na standardowe rozwiązanie WordPress zamiast psuć stronę.
- Filtrowanie po stronie serwera: Nigdy nie filtruj wyników za pomocą JavaScript. Jeśli ukryjesz wynik w przeglądarce, dane i tak znajdą się w odpowiedzi sieciowej. Każdy korzystający z DevTools może je zobaczyć. Filtruj dane, zanim serwer wyśle odpowiedź.
- Wykluczenie z pamięci podręcznej: Musisz wykluczyć trasę REST wyszukiwarki z pamięci podręcznej stron (page caching). Jeśli zapiszesz wyniki w cache, wyszukiwanie jednego członka może zostać wyświetlone gościowi, co doprowadzi do wycieku prywatnych treści.
Frontend
Strona kliencka korzysta z vanilla JavaScript.
Trzy rzeczy, które sprawiają, że UX działa poprawnie:
- Debounce: Odczekaj 250 ms po naciśnięciu klawisza przed wysłaniem żądania. Zapobiega to niepotrzebnemu obciążeniu serwera.
- AbortController: Anuluj poprzednie żądania, gdy użytkownik nadal pisze. Zapobiega to nadpisywaniu nowych wyników przez stare.
- Stany błędów: Wyświetl jasny komunikat, jeśli pobieranie (fetch) się nie powiedzie. Kręcący się loader, który nigdy się nie zatrzymuje, to złe UX.
Lekcja mobilna
Próbowałem wstrzyknąć przycisk wyszukiwania do menu mobilnego Divi. Motyw przechwytywał kliknięcia, przez co przycisk był nieaktywny.
Rozwiązanie było proste: Przestań walczyć z motywem.
Zamiast umieszczać przycisk wewnątrz menu, wstrzyknąłem go do nagłówka jako samodzielny element. Dzięki temu pozostał poza kontrolą motywu i był łatwy do kliknięcia na ekranie dotykowym.
Podsumowanie
- Kontrola dostępu musi odbywać się na serwerze.
- Wyklucz punkty końcowe (endpoints) wyszukiwania z pamięci podręcznej.
- Używaj debounce i AbortController do obsługi żądań.
- Eskapuj wszystkie dane API przed wstrzyknięciem ich do DOM, aby zapobiec atakom XSS.
- Jeśli kreator stron (page builder) stawia opór Twojemu kodowi, umieść swój element obok niego, a nie wewnątrz niego.
Źródło: https://dev.to/highcenburg/building-a-search-modal-for-a-membership-gated-wordpress-site-b92
