Jak tworzyć własne widgety Elementora z kontrolami i renderowaniem? To jedno z tych pytań, które pojawiają się, gdy standardowe klocki przestają wystarczać, a projekt wymaga czegoś naprawdę „twojego”. Dobra wiadomość: stworzenie własnego widgetu nie jest trudne, jeśli podejdziesz do procesu metodycznie. Poniżej znajdziesz praktyczny przewodnik: od przygotowania środowiska, przez definicję kontrolek, aż po bezpieczne renderowanie treści i dołączanie skryptów.
Jak tworzyć własne widgety Elementora z kontrolami i renderowaniem? — przegląd procesu
W skrócie: zbuduj szkielet wtyczki, zarejestruj widget, dodaj kontrolki, a następnie wyrenderuj je w sposób bezpieczny i wydajny.
Tworzenie widgetu sprowadza się do kilku kroków:
- Przygotowanie wtyczki (lub modułu w motywie potomnym), w której „zamieszka” widget.
- Rejestracja klasy widgetu rozszerzającej klasę bazową Elementora.
- Definicja kontrolek (Controls) dostępnych w edytorze.
- Renderowanie HTML na podstawie ustawień.
- Podpinanie stylów i skryptów tylko wtedy, kiedy są potrzebne.
- Testy, optymalizacja, tłumaczenia i publikacja.
Wymagania wstępne i środowisko
Upewnij się, że Twoje środowisko jest gotowe: aktualny WordPress, Elementor i podstawowa znajomość PHP/JS/CSS.
Co warto przygotować:
- Aktualny WordPress, Elementor (wersja zgodna z dokumentacją API, najlepiej najnowsza).
- Znajomość struktury wtyczek WordPressa.
- Włączony tryb debugowania w środowisku deweloperskim (WP_DEBUG).
- Edytor kodu z lintingiem i PSR-4 (np. PHP CS Fixer).
Dodatkowo zwróć uwagę na:
- Nazewnictwo przestrzeni nazw (namespace) dla unikania kolizji.
- Tłumaczenia (i18n), używając tekstów opakowanych w __() z własną domeną tekstową.
Struktura wtyczki i rejestracja widgetu
Zacznij od prostego szkieletu wtyczki i jednego pliku klasy widgetu — mniej znaczy lepiej.
Minimalna struktura:
- folder: wp-content/plugins/moj-elementor-widget
- plik: moj-elementor-widget.php (nagłówek wtyczki, autoloader PSR-4 lub proste require)
- folder: includes/ (tam trzymasz klasę widgetu)
- folder: assets/ (style i skrypty)
W pliku głównym:
- Sprawdź, czy Elementor jest aktywny.
- Podłącz hook init lub elementor/widgets/register do rejestracji widgetu.
- Zarejestruj style/skrypty. Możesz użyć funkcji WordPressa: wp_register_style oraz wp_register_script.
W klasie widgetu:
- Rozszerz klasę ElementorWidget_Base.
- Zaimplementuj metody: get_name(), get_title(), get_icon(), get_categories().
- (Opcjonalnie) get_keywords() dla lepszej wyszukiwalności w edytorze.
Przykładowe nazwy:
- get_name: my_custom_card
- get_title: „Karta: wyróżniony blok”
- get_icon: eicon-posts-grid (lub inna ikona z zestawu Elementora)
- get_categories: [‘general’] lub własna kategoria, jeśli ją rejestrujesz.
Definiowanie kontrolek (Controls)
Kontrolki decydują o tym, jak edytorzy będą konfigurować Twój widget — zaprojektuj je jasno i logicznie.
Dodawaj kontrolki w metodzie register_controls() korzystając z:
- start_controls_section(‘sekcja’, [‘label’ => ‘Ustawienia’])
- add_control(‘pole’, [ ‘label’ => ‘Tytuł’, ‘type’ => Controls_Manager::TEXT, … ])
- end_controls_section()
Ważne typy kontrolek:
- TEXT, TEXTAREA, WYSIWYG — treści
- MEDIA — obrazy
- URL — linki
- SWITCHER — tak/nie
- SELECT, CHOOSE — wybory
- COLOR, SLIDER, DIMENSIONS, TYPOGRAPHY (w sekcji Style) — wygląd
Praktyczne wskazówki:
- Grupuj kontrolki w sekcje (Content, Style) dla lepszej ergonomii.
- Używaj domyślnych wartości (default), aby widget dobrze wyglądał „po wyjęciu z pudełka”.
- Dodawaj opisy (description), kiedy label to za mało.
Repeater — gdy potrzebujesz listy elementów
Repeater pozwala tworzyć powtarzalne elementy, np. listę funkcji, slajdy lub karty.
- Utwórz obiekt repeatera.
- Dodaj do niego pola (np. tytuł, ikonę, opis).
- Użyj Controls_Manager::REPEATER z fields => $repeater->get_controls().
- W renderowaniu przeiteruj po ustawieniach repeatera i wygeneruj HTML.
Warunki wyświetlania i logika
Pokaż tylko te kontrolki, które mają sens w danym kontekście — mniej rozproszeń to lepszy UX.
- Użyj ‘condition’ => [‘switcher’ => ‘yes’] dla kontekstowych pól.
- Pamiętaj, że condition działa tylko w panelu — w renderowaniu nadal weryfikuj wartości.
- Możesz kontrolować widoczność CSS/HTML w render() na podstawie ustawień użytkownika.
Dynamic Tags, kontrola stylów i selektory
Pozwól treściom być dynamicznymi i styluj je bez pisania CSS w motywie.
- Włącz obsługę dynamicznych tagów przez ‘dynamic’ => [‘active’ => true] dla odpowiednich pól.
- Dla kontrolek stylu możesz użyć ‘selectors’ => [‘{{WRAPPER}} .tytul’ => ‘color: {{VALUE}};’].
- Użyj ‘prefix_class’ aby dodawać klasy do wrappera w zależności od opcji (np. wariant wyglądu).
Renderowanie: od ustawień do czytelnego HTML
Renderowanie to serce widgetu: pobierz ustawienia, zbuduj atrybuty, bezpiecznie wyrenderuj HTML.
W metodzie render():
- Pobierz ustawienia: settings = $this->get_settings_for_display()
- Zbuduj atrybuty za pomocą: add_render_attribute(‘wrapper’, ‘class’, ‘moja-klasa’)
- Wstaw atrybuty do znaczników: print_render_attribute_string(‘wrapper’)
- Zadbaj o bezpieczeństwo: escapuj wyjście (esc_html, esc_attr, esc_url), a dla bogatego HTML — wp_kses_post z dozwolonymi tagami.
Przykładowy schemat:
- Sprawdź, czy tytuł nie jest pusty.
- Jeżeli jest obraz — wyrenderuj z odpowiednim alt (fallback do tytułu).
- Linkuj przyciski tylko, gdy URL istnieje; atrybuty rel i target ustawiaj na podstawie ustawień.
- Dodaj klasy stanu (np. „is-featured”), korzystając z add_render_attribute.
Dodatkowe możliwości:
- inline editing: $this->add_inline_editing_attributes(‘pole’, ‘none’|‘advanced’) dla edycji bezpośredniej.
- _content_template (legacy): kiedyś używane do podglądu w JS; w nowszych wersjach wystarcza render().
Style i skrypty: get_style_depends i get_script_depends
Ładuj zasoby tylko, kiedy widget jest użyty — to klucz do wydajności.
- Zarejestruj style i skrypty w pliku głównym wtyczki (wp_register_style/wp_register_script).
- W klasie widgetu zaimplementuj get_style_depends() i get_script_depends() zwracając uchwyty zarejestrowanych zasobów.
- Jeśli używasz bibliotek JS (np. Swiper poza wbudowanym), podaj zależności i wersję.
- Upewnij się, że skrypty są zgodne z trybem edytora (często przydaje się sprawdzenie elementorFrontend w JS).
Najczęstsze błędy i jak ich unikać
Kilka pułapek potrafi zabić radość z tworzenia — ominiesz je dzięki prostym zasadom.
- Brak escapowania danych — zawsze filtruj wyjście. To podstawa bezpieczeństwa.
- Nadmiar kontrolek — użytkownik się gubi. Grupuj i upraszczaj.
- Nielogiczne domyślne wartości — widget nie wygląda dobrze po dodaniu. Daj sensowne defaulty.
- Twarde ścieżki do zasobów — zawsze korzystaj z funkcji WordPressa (plugins_url, plugin_dir_url).
- Brak zgodności z tłumaczeniami — owiń każdy tekst w __() z domain.
- Konflikty CSS — namespace’uj klasy (np. mywgt- prefiks) i używaj {{WRAPPER}} w selectors.
- Nieużywane skrypty i style — nie ładuj globalnie, tylko przez zależności widgetu.
Dobre praktyki wydajności i dostępności
Widget ma być szybki i przyjazny — zarówno dla użytkownika, jak i czytników ekranu.
- Minimalizuj DOM: generuj tylko potrzebne elementy.
- Używaj lazy-loading obrazów (WordPress robi to domyślnie, ale warto to mieć na uwadze).
- Cache’uj wyniki zapytań (transienty), jeśli widget pobiera treści dynamicznie.
- Dodawaj atrybuty aria-label, role, alt — dostępność to nie „miły dodatek”, to konieczność.
- Kontrast kolorów: jeśli pozwalasz na zmianę kolorów, dorzuć ostrzeżenie lub predefiniowane palety spełniające WCAG.
- Zadbaj o klawiaturową nawigację, jeśli widget ma elementy interaktywne (np. karuzele, zakładki).
Testowanie, debugowanie i publikacja
Dobre testy skracają czas wdrożenia i oszczędzają nerwy na produkcji.
- Testuj w trybie edytora i na froncie — nie wszystko zachowuje się identycznie.
- Sprawdzaj konsolę przeglądarki (błędy JS) i logi PHP (WP_DEBUG_LOG).
- Włącz Safe Mode w Elementorze, gdy podejrzewasz konflikt z inną wtyczką.
- Sprawdź responsywność: kontrolki responsywne (tablet/mobil) i ich wpływ na CSS.
- Upewnij się, że widget działa z motywem, którego używa klient (Child Theme, frameworki).
- Przygotuj readme i krótką dokumentację sposobu użycia.
Rozszerzenia: kategorie, panele, integracje
Kiedy podstawy działają, możesz pójść krok dalej i spiąć widget z szerszym ekosystemem.
- Własna kategoria widgetów: rejestruj, aby uporządkować zestaw komponentów.
- Integracje z ACF, Woocommerce: korzystaj z dynamic tags i własnych pól, by zasilać widget danymi.
- Globalne style: wykorzystaj system stylów Elementora, by opcje widgetu współgrały z design systemem.
Checklista bezpieczeństwa i jakości
Krótka checklista ułatwia publikację bez zgrzytów.
- Czy wszystkie dane wyjściowe są escapowane? (esc_html, esc_attr, esc_url, wp_kses_post)
- Czy skrypty i style są ładowane warunkowo przez get_script_depends/get_style_depends?
- Czy pola mają sensowne defaulty i opisy?
- Czy klasy CSS są z namespacem, by uniknąć konfliktów?
- Czy teksty są tłumaczalne i mają poprawną domenę?
- Czy widget przeszedł testy na desktopie/tablecie/telefonie?
Podsumowanie
Własny widget w Elementorze to inwestycja w elastyczność — raz zbudowany, wielokrotnie wykorzystany.
Zacznij od prostego szkicu wtyczki, zarejestruj klasę widgetu, zaprojektuj przemyślane kontrolki i zadbaj o bezpieczne renderowanie. Dodaj zależne style i skrypty tylko tam, gdzie to naprawdę potrzebne, wdroż logikę warunkową i dynamiczne tagi, a na końcu przetestuj całość w kilku scenariuszach. Dzięki temu stworzysz komponent, który nie tylko rozwiązuje konkretny problem, ale też jest łatwy w utrzymaniu, przyjazny dla edytorów i szybki na froncie.
Najważniejsze: projektuj oczami użytkownika. Jeśli edytor bez instrukcji potrafi zrozumieć, jak skonfigurować widget i osiągnąć pożądany efekt, to znak, że wykonałeś świetną robotę. A gdy zechcesz iść dalej, rozszerzaj zestaw o kolejne komponenty, budując własną bibliotekę, która przyspieszy każdy następny projekt.