- Przygotowanie środowiska i narzędzi
- Wymagania wstępne i instalacja
- Tworzenie wtyczki lub pakietu bloków
- Generator create-block – szybki start
- Ręczna konfiguracja @wordpress/scripts
- Podstawy tworzenia bloku i rejestracja
- block.json – serce konfiguracji
- Rejestracja w edytorze i PHP
- Funkcje edit i save – przepływ danych
- Model atrybutów i synchronizacja
- Obsługa błędów i niezgodności schematów
- Interfejs edycji: panele, kontrolki i komponowanie
- InspectorControls, BlockControls i pasek narzędzi
- Najczęstsze komponenty UI
- useBlockProps i semantyka HTML
- Stan, selektory i architektura danych
- Wzorce komponowania i InnerBlocks
- Walidacja i ograniczenia wejścia
- Zaawansowane wzorce i wdrożenie
- Bloki dynamiczne i serwerowe renderowanie
- Internationalization (i18n) i dostępność
- Wydajność i stylowanie
- Testy, jakość i typowanie
- Transformacje, warianty i wzorce
- Kompatybilność i migracje
- Bezpieczeństwo, sanitizacja i uprawnienia
- Publikacja i dystrybucja
- Praktyczny plan działania – od zera do wydania
- Częste pułapki i jak ich unikać
- Integracja z ekosystemem motywów i design system
- Rozszerzenia edytora i SlotFills
- Kiedy blok, a kiedy shortcut lub pattern
- Checklist przed release
Własne bloki to najkrótsza droga, by zamienić edytor Gutenberg w dopasowane do potrzeb środowisko tworzenia treści. Dzięki nim rozszerzysz WordPress o powtarzalne komponenty, lepsze UX i pełną kontrolę nad wyglądem oraz danymi. Ten przewodnik przeprowadzi Cię od konfiguracji narzędzi, przez model danych i interfejs edycji, po wdrożenie oraz utrzymanie. Znajdziesz tu praktyczne kroki, dobre praktyki i gotowe wzorce do natychmiastowego użycia.
Przygotowanie środowiska i narzędzi
Wymagania wstępne i instalacja
Zanim napiszesz pierwszy blok, przygotuj środowisko developerskie. Potrzebujesz Node.js (zalecana bieżąca LTS), npm lub yarn, oraz lokalnej instancji WordPressa: np. wp-env, Docker z obrazem PHP+MySQL, Local WP czy dev stack od hostingodawcy. Włącz tryb debugowania (WP_DEBUG) dla szybszego wykrywania problemów i ustaw stały URL oraz permalinki, by backendowe punkty końcowe działały przewidywalnie.
Dodatkowo zainstaluj oficjalne narzędzia: @wordpress/scripts do budowania kodu, @wordpress/create-block do szybkiego scaffoldu oraz biblioteki komponentów. Te paczki standaryzują bundling (webpack, Babel), transpile kod i minimalizują konfigurację. Dzięki nim bez wysiłku wykorzystasz nowoczesny stos, w tym React i JSX, a także wsparcie dla ESNext.
Tworzenie wtyczki lub pakietu bloków
Najczęściej blok umieszcza się we wtyczce. Pozwala to dystrybuować go niezależnie od motywu, aktualizować bez ryzyka nadpisania oraz łatwo wyłączyć. Struktura podstawowej wtyczki może wyglądać następująco:
- my-plugin/
- my-plugin/my-plugin.php – plik bootstrap rejestrujący zasoby i bloki
- my-plugin/build/ – artefakty produkcyjne (JS/CSS)
- my-plugin/src/ – źródła bloku
- my-plugin/block.json – metadane bloku
W pliku głównym wtyczki dodasz rejestrację autoloadera, ładowanie textdomain i hooki inicjalizujące. To dobry moment, aby ustalić prefiksy nazw (namespace) i spójne konwencje nazewnictwa.
Generator create-block – szybki start
Najszybsza droga to uruchomienie generatora: npx @wordpress/create-block my-block. Kreator zapyta m.in. o nazwę, opis, kategorię i styl. Na końcu otrzymasz działający szkielet z block.json, plikami edycji (edit) i zapisu (save), stylami oraz skryptami build i start. Po aktywacji wtyczki zobaczysz blok w edytorze i natychmiast zaczniesz iterować nad jego funkcjonalnością.
Ręczna konfiguracja @wordpress/scripts
Jeśli wolisz pełną kontrolę, dodaj do package.json skrypty: wp-scripts start (watch + dev server), wp-scripts build (produkcyjne bundlowanie). Następnie w src/index.js zaimportuj funkcje z @wordpress/blocks i @wordpress/i18n, a także komponenty z @wordpress/components i @wordpress/block-editor. Pliki stylów rozdziel na edytor (editor.scss) i front (style.scss), by uniknąć nadmiarowych klas w panelu administracyjnym.
Podstawy tworzenia bloku i rejestracja
block.json – serce konfiguracji
Plik block.json opisuje blok w sposób zrozumiały dla edytora i CLI. Najważniejsze właściwości to: name (unikalna nazwa z namespace), title, category, icon, attributes, style, editorStyle, script, editorScript oraz supports. Dzięki temu WordPress automatycznie wczyta zasoby i zarejestruje blok bez dodatkowego PHP. Dobrym nawykiem jest trzymanie wszystkich definicji w block.json i importowanie go zarówno po stronie edytora, jak i serwera.
Atrybuty definiują model danych bloku. Możesz zdefiniować typy (string, number, array, object, boolean), defaulty i źródła (np. children, text, attribute). To one determinują, jak dane są zapisywane w treści i jak reagują na zmiany użytkownika. Operując atrybutami, pamiętaj o minimalizmie: przechowuj tylko to, czego nie da się odtworzyć wyłącznie ze struktury HTML.
Rejestracja w edytorze i PHP
W przypadku bloków statycznych wystarczy import block.json w kodzie JS i wywołanie registerBlockType z definicjami edit i save. Dla bloków dynamicznych (renderowanych po stronie serwera) dodaj register_block_type_from_metadata w PHP, co umożliwi wskazanie callbacku renderującego i kontrolę zależności. Ta hybryda ułatwia utrzymanie, bo jedna definicja metadanych obsługuje obie strony.
Funkcje edit i save – przepływ danych
Funkcja edit odpowiada za UI w edytorze: renderuje panele, pola i podgląd. W niej używasz hooków edytora, setAttributes oraz komponentów. Funkcja save zwraca finalny HTML zapisywany do treści wpisu. W prostych blokach oba te światy są równoważne: atrybuty ustawione w edycji pojawią się w wynikowym markupie. To naturalny obszar dla JSX i idiomów React, w tym kompozycji i propsów.
Model atrybutów i synchronizacja
Kluczem do przewidywalności bloku są dobrze zaprojektowane atrybuty. Każdy atrybut przekłada się na fragment UI (np. RichText, ColorPalette), a jego aktualizacja odbywa się przez setAttributes. Dbaj o spójne nazwy i typy, nie duplikuj danych, przechowuj znaczenie, a nie prezentację (np. hex koloru zamiast klas). Takie podejście upraszcza migracje i redukuje konflikty przy refaktorach.
Obsługa błędów i niezgodności schematów
Gdy zmieniasz strukturę HTML w save, ryzykujesz niedopasowanie do istniejących treści. Wykorzystaj mechanizm deprecated: dodaj poprzednie definicje save/attributes do tablicy deprecated, aby edytor mógł bezpiecznie zaktualizować stare wystąpienia bloku. Testuj migracje na kopiach wpisów i trzymaj historię zmian w repozytorium.
Interfejs edycji: panele, kontrolki i komponowanie
InspectorControls, BlockControls i pasek narzędzi
InspectorControls to panel boczny ustawień bloku. Umieszczaj w nim przełączniki, suwaki i selektory, które nie wymagają natychmiastowej interakcji w płótnie. BlockControls to toolbar nad blokiem – idealny dla często używanych akcji, np. wyrównania. Czytelne rozdzielenie opcji między te dwa miejsca podnosi ergonomię edycji i ułatwia użytkownikom ich odnalezienie.
Najczęstsze komponenty UI
RichText umożliwia edycję treści inline (nagłówki, akapity, przyciski). MediaUpload i MediaPlaceholder obsługują wgrywanie plików i wybór z biblioteki. URLInput steruje linkami. ColorPalette i GradientPicker pomagają dobrać kolorystykę. FontSizePicker reguluje rozmiar tekstu. Wszystkie te komponenty współgrają z modelem atrybutów i automatycznie aktualizują stan bloku w edytorze.
useBlockProps i semantyka HTML
Hook useBlockProps zapewnia zgodność z edytorem: dostarcza klasy, identyfikatory i obsługę wyboru bloku. Dla elementów potomnych używaj useBlockProps.save. Pamiętaj o semantyce: tam, gdzie to możliwe, generuj znaczniki odwzorowujące przeznaczenie treści (np. button dla CTA). Semantyczny HTML ułatwia stylowanie, poprawia dostępność i późniejszą integrację z motywami.
Stan, selektory i architektura danych
W bardziej złożonych blokach przydają się selektory i akcje z @wordpress/data. useSelect pobiera dane ze store (np. media, wpisy, ustawienia), a useDispatch aktualizuje je. Dzięki temu ograniczysz props drilling i zachowasz czytelność kodu. Łącz to z lokalnym stanem Reacta tam, gdzie nie wymaga się persystencji w atrybutach.
Wzorce komponowania i InnerBlocks
InnerBlocks pozwala budować bloki kontenerowe i layoutowe. Zdefiniuj allowedBlocks (białą listę) oraz template (układ startowy), a edytor wymusi poprawną strukturę. To świetny sposób na komponenty złożone: karty, sekcje hero, listy ofert. Ustalając templateLock, możesz zablokować dodawanie lub usuwanie elementów i uprościć edycję dla autorów treści.
Walidacja i ograniczenia wejścia
Używaj prostych reguł walidujących w onChange (np. maksymalna długość tekstu, zakres liczb), by zapobiec błędom przy zapisie. Dodawaj wizualne podpowiedzi i komunikaty o błędach. Rozważ automatyczne normalizacje, np. obcinanie spacji, zamianę pustych wartości na domyślne, aby zachować spójność danych w treści wpisu.
Zaawansowane wzorce i wdrożenie
Bloki dynamiczne i serwerowe renderowanie
Blok dynamiczny generuje HTML po stronie serwera poprzez render_callback w PHP. To idealny wybór, gdy wyjście zależy od danych zmiennych w czasie (np. ostatnie wpisy, ceny, stock, personalizacja). Po stronie edytora prezentuj placeholder z podglądem, a w frontendzie serwer złoży finalny markup. W callbacku pobieraj atrybuty, sanituzuj je i buduj HTML, wykorzystując funkcje esc_* i wp_kses.
Dynamiczne bloki dobrze współgrają z REST API i shortcachem. Możesz cache’ować fragmenty HTML per konfiguracja bloku (np. transienty), co zwiększy wydajność przy wielu wystąpieniach na stronie. Zachowaj ostrożność przy paginacji i parametrach zapytań – najlepiej jasno ogranicz dostępne opcje, by uniknąć nadmiernych kosztów zapytań.
Internationalization (i18n) i dostępność
Tłumacz wszystkie teksty poprzez funkcje i18n: w JS używaj __ i _x, w PHP __ i _x. Dołącz pliki .json lub .mo. Pamiętaj o a11y: aria-labels, role, fokus management i kontrast. Komponenty z @wordpress/components spełniają standardy dostępności, ale własne elementy muszą być testowane klawiaturą i czytnikami ekranu. Dodawaj również informacyjne komunikaty w UI, gdy blok zmienia stan.
Wydajność i stylowanie
Dbaj o podział pakietów i tree shaking: importuj tylko potrzebne moduły. Prefiksuj klasy CSS i używaj edytorowych zmiennych (np. var(–wp–preset–color–primary)), by zachować zgodność z motywem. Oddziel style dla edytora i frontu, a w miarę potrzeb dołącz warunkowo style tylko dla użytych bloków. Rozważ CSS logical properties dla wsparcia RTL oraz redukcję zagnieżdżeń, by uprościć kaskadę.
Testy, jakość i typowanie
Automatyzuj jakość: ESLint i Stylelint, Prettier, a do testów interfejsu Playwright lub @wordpress/e2e-test-utils-playwright. Snapshoty dla save pomagają wychwycić niezamierzone zmiany HTML. W większych projektach rozważ TypeScript, by typować propsy, atrybuty i serwisy – ograniczysz liczbę błędów i przyspieszysz refaktoryzacje.
Transformacje, warianty i wzorce
Transformacje pozwalają konwertować blok w inny (np. paragraf w cytat), zachowując dane tam, gdzie to możliwe. Warianty (block variations) to zestawy prekonfigurowanych atrybutów i ikon pod jednym typem bloku – ułatwiają szybkie wstawianie często używanych odmian. Wzorce (block patterns) łączą wiele bloków w gotowe sekcje i powinny być dołączane jako reużywalne układy.
Kompatybilność i migracje
Ustal politykę wersjonowania (semver) i zapisuj zmiany w CHANGELOG. Przy każdej modyfikacji struktury zapisanego HTML dodawaj wpis do deprecated z migracją. Testuj zachowanie bloku na różnych wersjach WordPressa i PHP, a także w popularnych motywach. Zwracaj uwagę na supports (align, spacing, color) – mogą zmienić markup i wpłynąć na kompatybilność CSS.
Bezpieczeństwo, sanitizacja i uprawnienia
W miejscach, gdzie użytkownik może wprowadzić dane, stosuj sanitizację. W PHP używaj esc_html, esc_attr, esc_url i wp_kses dla dozwolonego HTML. Sprawdzaj uprawnienia current_user_can przed wykonywaniem wrażliwych akcji. Jeśli blok komunikuje się z backendem, zabezpieczaj żądania nonce i sprawdzaj ich ważność. Dbałość o bezpieczeństwo jest krytyczna zarówno dla edytora, jak i frontu.
Publikacja i dystrybucja
Gdy blok jest gotowy, zbuduj wersję produkcyjną (minifikacja, hash nazw plików). Do dystrybucji użyj repozytorium WordPress.org, packagistu lub prywatnego rejestru. Zapewnij dokumentację: opis atrybutów, przykłady użycia, zrzuty ekranu i GIF-y. Rozważ telemetrię anonimową (za zgodą) lub system feedbacku, by rozumieć, jak blok jest używany, i planować rozwój.
Praktyczny plan działania – od zera do wydania
- Skonfiguruj środowisko lokalne z czystą instalacją WordPress.
- Uruchom generator create-block i wybierz typ bloku (np. static).
- Zdefiniuj minimalny zestaw atrybutów i warianty stylów.
- Zaimplementuj edit z czytelnym UI (InspectorControls, toolbar).
- Zapisz semantyczny HTML w save i dodaj test snapshot.
- Dodaj style dla edytora i frontu, spójne z motywem.
- Opcjonalnie dodaj tryb dynamiczny z render_callback.
- Zadbaj o i18n, a11y, linting i build produkcyjny.
- Przygotuj dokumentację oraz przykład wzorca/patternu.
- Wydaj wtyczkę i monitoruj zgłoszenia użytkowników.
Częste pułapki i jak ich unikać
- Nadmierna liczba atrybutów – przechowuj tylko to, co nie wynika z HTML.
- Brak deprecated – utrudnia migracje i niszczy istniejące treści.
- Mieszanie CSS edytora i frontu – prowadzi do konfliktów stylów.
- Nieoptymalne zapytania w blokach dynamicznych – powodują wolne strony.
- Brak sanitizacji – ryzyko XSS i błędów wyświetlania.
- Nieprzemyślana semantyka – gorsza dostępność i SEO.
Integracja z ekosystemem motywów i design system
Oprzyj stylowanie o globalne presety i Theme JSON, umożliwiając przejęcie kontroli przez motyw: kolory, typografia, odstępy. Ustal tokeny projektowe i stosuj je w stylach bloków, aby zachować spójność. Udostępnij filtry lub context, jeśli blok ma współpracować z innymi elementami. Dzięki temu Twoje komponenty będą elastyczne i przewidywalne w różnych środowiskach.
Rozszerzenia edytora i SlotFills
Gdy potrzebujesz globalnych integracji (np. dodatkowe panele w ustawieniach wpisu), użyj SlotFill API. Pozwoli to dokleić UI w przewidzianych miejscach edytora bez hakowania jego struktury. W połączeniu z blokami tworzy to pełny pakiet doświadczeń – od mikrointerakcji w obrębie bloku po ustawienia globalne treści.
Kiedy blok, a kiedy shortcut lub pattern
Nie wszystko musi być blokiem. Jeśli potrzebujesz jedynie złożonego układu bez logiki, wybierz pattern. Jeśli chodzi o pojedynczą komendę (np. wstawienie bieżącego roku), rozważ makro lub małą funkcję dynamiczną. Blok jest najlepszy, gdy łączy własny model danych, UI i markup, które muszą być edytowalne oraz przenaszalne między wpisami.
Checklist przed release
- Przegląd atrybutów: minimalne, opisane, posiadają domyślne wartości.
- UI: sensowny podział opcji między toolbar a InspectorControls.
- Semantyka: poprawne znaczniki, a11y, aria-label, focus states.
- Wydajność: podział pakietów, brak ciężkich zależności.
- Bezpieczeństwo: sanitizacja, esc_*, nonces, walidacja uprawnień.
- Kompatybilność: testy w popularnych motywach i wersjach WP.
- Migration/deprecated: zdefiniowane, pokryte testami.
- Dokumentacja: opis, przykłady, zrzuty ekranu.
Po przejściu tej listy Twoje bloki powinny być stabilne, przewidywalne i gotowe do pracy w różnych środowiskach. W miarę rozwoju projektu rozszerzaj je o warianty, transformacje i wzorce, a także rozważ integrację z design systemem, by skrócić czas budowy kolejnych widoków i komponentów.
Pamiętaj, że najwięcej jakości przynosi iteracja: zbieraj feedback od redaktorów, analizuj najczęstsze ścieżki i upraszczaj interfejs. Aktualizacje wprowadzaj w małych porcjach, korzystając z deprecated i testów. Dzięki temu Twoja biblioteka bloków będzie rosła bez długu technicznego, a autorzy treści zyskają szybkie, spójne i przewidywalne narzędzia pracy.