Blog

Twórz niestandardowe bloki tylko z PHP. Żegnajcie stare shortcode'y 🥳

David Wang
Autor: David Wang ·

Tworzenie bloków Gutenberga oznaczało React, Node.js i pipeline kompilacji od czasu, gdy WordPress 5.0 wprowadził edytor bloków. Jeśli Twoje umiejętności dotyczą PHP — jak moje i większości deweloperów WordPress — ta bariera trzymała Cię z boku przez prawie dekadę. WordPress 7.0 to zmienia. Bloki tylko w PHP pozwalają zarejestrować w pełni funkcjonalny blok Gutenberga za pomocą jednego pliku PHP i flagi autoRegister.

Piszesz PHP. Otrzymujesz blok. Bez toolingu. Bez kompilacji. 🥳 W tym artykule zobaczysz, jak działają bloki tylko w PHP, i przejdziesz przez prawdziwy przykład zastępujący klasyczny shortcode jego odpowiednikiem w formie bloku.

Czym są bloki tylko w PHP?

Do tej pory tworzenie niestandardowego bloku Gutenberga oznaczało konfigurowanie toolchainu JavaScript: npm install, plik block.json, krok kompilacji z webpack.config.js lub @wordpress/scripts i komponent edit.js napisany w JSX. Każda zmiana wymagała kroku kompilacji, zanim można było ją zobaczyć w edytorze. Dla dewelopera PHP, który chce jedynie zarejestrować prosty blok wyświetlający treść, ten narzut zawsze wydawał się nieproporcjonalny do zadania.

Bloki tylko w PHP eliminują to wszystko. Teraz w register_block_type() wystarczy przekazać 'autoRegister' => true, a WordPress automatycznie obsługuje wszystko po stronie JavaScript za pomocą ServerSideRender. Blok pojawia się w inserterze, renderuje podgląd na żywo na kanwie i generuje kontrolki Inspektora w panelu bocznym — wszystko bez ani jednej linii JavaScript z Twojej strony.

Kontrolki są generowane automatycznie na podstawie typu atrybutu:

Typ atrybutuGenerowana kontrolka Inspektora
stringPole tekstowe
integer / numberPole numeryczne
booleanPrzełącznik
string + enumLista rozwijana

Automatycznie generowane kontrolki obejmują na razie tylko cztery powyższe typy. Cokolwiek bardziej złożonego, jak selektory obrazów, przesyłanie mediów lub dane zagnieżdżone, nie jest jeszcze obsługiwane i wymagałoby bloku zarejestrowanego z JavaScript. Deweloperzy mogą też oznaczać poszczególne atrybuty rolą local, aby oznaczyć je jako stan wewnętrzny; WordPress pomija je podczas budowania kontrolek panelu bocznego.

Bloki tylko w PHP są dziś dostępne w WordPress 7.0 bez żadnych dodatkowych zależności. Więcej informacji w oficjalnej notatce dla deweloperów na Make WordPress Core.

Dla kogo to jest?

Mniejsze agencje i freelancerzy bez głębokiej wiedzy o JavaScript mogą teraz tworzyć rozwiązania dla edytora bloków, które w pełni korzystają z natywnych funkcji WordPress bez konieczności dotykania pipeline kompilacji. Jeśli chcesz tworzyć niestandardowe bloki Gutenberga specyficzne dla motywu — takie jak ramki autora, wyróżnione cytaty, opinie, banery CTA, powiadomienia i podobne elementy — zamiast używać shortcode'ów, bloki tylko w PHP znacznie pomagają obniżyć tę barierę.

Nie zastępują bloków zarejestrowanych z JavaScript, gdy potrzebujesz wbudowanej edycji tekstu sformatowanego, reaktywnego interfejsu w czasie rzeczywistym lub zagnieżdżania bloków wewnętrznych — ale dla dużej klasy ustrukturyzowanych bloków wyświetlających treść trafiają w dziesiątkę.

Stara metoda: shortcode'y

Przed blokami tylko w PHP, praktycznym podejściem dewelopera PHP był shortcode. Oto prosty shortcode opinii z trzema atrybutami: imię autora, firma, ocena w gwiazdkach oraz wewnętrzna treść dla tekstu opinii:

function testimonial_shortcode( $atts, $content = '' ) {
    $atts = shortcode_atts( [
        'name'    => '',
        'company' => '',
        'stars'   => 5,
    ], $atts );
 
    $stars_count = max( 1, min( 5, intval( $atts['stars'] ) ) );
    $stars_html  = str_repeat( '★', $stars_count )
                 . str_repeat( '☆', 5 - $stars_count );
 
    return sprintf(
        '<blockquote class="testimonial">
            <p class="testimonial__stars">%s</p>
            <p class="testimonial__body">%s</p>
            <footer class="testimonial__attribution">
                <strong>%s</strong>%s
            </footer>
        </blockquote>',
        esc_html( $stars_html ),
        wp_kses_post( $content ),
        esc_html( $atts['name'] ),
        $atts['company'] ? ', ' . esc_html( $atts['company'] ) : ''
    );
}
add_shortcode( 'testimonial', 'testimonial_shortcode' );

Użycie:

[testimonial name="Sarah K." company="Acme Corp" stars="4"]
	Saved us hours every week.
[/testimonial]

Działa... ale to tylko shortcode 🤷🏻‍♂️

Oto tylko kilka problemów ze shortcode'ami:

  • Niewidoczny w edytorze. Autor widzi [testimonial name="Sarah K." ...] w edytorze, nie wyrenderowaną kartę. Nie ma podglądu.
  • Nie jest wykrywalny. Musisz wiedzieć, że shortcode istnieje i pamiętać nazwy jego parametrów. Nic nie ujawnia go w interfejsie.
  • Brak natywnych kontrolek stylów. Dostosowanie koloru, odstępów lub typografii wymaga niestandardowego CSS lub dodatkowych atrybutów połączonych ręcznie.
  • Wewnętrzna treść nie jest tekstem sformatowanym. Treść opinii jest przekazywana jako zwykły ciąg znaków w $content — nie edytowalne pole tekstowe z formatowaniem.

Shortcode'y były właściwym narzędziem dla swoich czasów. Edytor bloków oferuje coś lepszego, ale trudno było z tego skorzystać. WordPress 7.0 oferuje skrót w postaci bloków tylko w PHP.

Żeby było jasne: właściwy nowoczesny sposób tworzenia bloku Gutenberga to nadal blok zarejestrowany z JavaScript z pełnym komponentem edit. Bloki tylko w PHP to uproszczona ścieżka — celowo ograniczona do bloków renderowanych po stronie serwera, które nie potrzebują bogatej edycji na kanwie. Nie zastępują bloków JavaScript, ale stanowią nową opcję dla prostszych przypadków użycia, gdzie narzut pipeline kompilacji i komponentów React nie jest uzasadniony.

Prostsze rozwiązanie: bloki tylko w PHP

Zbudujmy tę samą opinię jako niestandardowy blok WordPress tylko z PHP. Przepis: register_block_type() z 'autoRegister' => true w supports oraz render_callback.

Oto pełny kod bloku:

function my_plugin_register_testimonial_block() {
    register_block_type(
        'my-plugin/testimonial', // Block name: namespace/slug
        array(
            'title'      => 'Testimonial', // Shown in the block inserter
            'attributes' => array(
                // string attributes generate a text input in the sidebar
                'name'    => array(
                    'type'    => 'string',
                    'default' => '',
                ),
                'company' => array(
                    'type'    => 'string',
                    'default' => '',
                ),
                // integer attributes generate a number input
                'stars'   => array(
                    'type'    => 'integer',
                    'default' => 5,
                ),
                'body'    => array(
                    'type'    => 'string',
                    'default' => '',
                ),
            ),
            // render_callback is the PHP function that outputs the block's HTML
            'render_callback' => function ( $attributes ) {
                $stars_count = max( 1, min( 5, intval( $attributes['stars'] ) ) );
                $stars_html  = str_repeat( '★', $stars_count )
                             . str_repeat( '☆', 5 - $stars_count );
 
                // Translatable string for screen readers — standard WordPress i18n, nothing extra needed
                /* translators: %d: star rating out of 5 */
                $stars_label = sprintf( __( '%d out of 5 stars', 'my-plugin' ), $stars_count );
 
                return sprintf(
                    '<blockquote %s>
                        <p class="testimonial__stars" aria-label="%s">%s</p>
                        <p class="testimonial__body">%s</p>
                        <cite class="testimonial__attribution">
                            <strong>%s</strong>%s
                        </cite>
                    </blockquote>',
                    // Merges your class with editor-added colour, spacing, and typography styles
                    get_block_wrapper_attributes( array( 'class' => 'testimonial wp-block-quote' ) ),
                    esc_attr( $stars_label ),
                    esc_html( $stars_html ),
                    wp_kses_post( $attributes['body'] ),
                    esc_html( $attributes['name'] ),
                    $attributes['company'] ? ', ' . esc_html( $attributes['company'] ) : ''
                );
            },
            'supports' => array(
                // The key flag — tells WordPress to handle JS registration automatically
                'autoRegister' => true, 
                // The rest unlock native colour, typography, and spacing panels in the sidebar
                'color'      => array(
                    'background' => true,
                    'text'       => true,
                ),
                'typography' => array(
                    'fontSize' => true,
                ),
                'spacing'    => array(
                    'padding' => true,
                    'margin'  => true,
                ),
            ),
        )
    );
}
add_action( 'init', 'my_plugin_register_testimonial_block' );

Wynik:

Przykład niestandardowego bloku WordPress utworzonego tylko z PHP
Blok opinii tylko w PHP z automatycznie generowanymi kontrolkami i podglądem na żywo na kanwie edytora w porównaniu z wersją opartą na shortcode.

Kilka rzeczy do odnotowania. Po pierwsze, wewnętrzna treść shortcode'a nie ma bezpośredniego odpowiednika w blokach tylko w PHP. Treść opinii staje się atrybutem string edytowanym przez kontrolki Inspektora w panelu bocznym — jednoliniowym polem tekstowym, nie edytowalnym polem tekstowym z formatowaniem na kanwie. Dla krótkiego cytatu opinii to wystarczy. W przypadku dłuższej treści będziesz potrzebować bloku zarejestrowanego z JavaScript z komponentem RichText.

Po drugie, get_block_wrapper_attributes() łączy Twoją klasę z tym, co edytor dodaje dla koloru, typografii i odstępów — dzięki czemu natywne panele stylów działają bez żadnego dodatkowego okablowania CSS. render_callback otrzymuje tablicę $attributes zawierającą tylko wartości ustawione przez użytkownika; bez parametru $content, ponieważ wewnętrzna treść nie jest obsługiwana.

Co zyskujesz w porównaniu z wersją opartą na shortcode:

  • Podgląd na żywo na kanwie edytora. Koniec z surową składnią shortcode — autor widzi wyrenderowaną kartę opinii podczas edycji.
  • Automatycznie generowane kontrolki. Imię, firma, treść (pola tekstowe) i gwiazdki (pole numeryczne) pojawiają się automatycznie w kontrolkach Inspektora w panelu bocznym.
  • Natywne panele koloru, czcionki i odstępów. Pochodzą z supports — bez potrzeby niestandardowego CSS.
  • Wykrywalny. Blok pojawia się w inserterze pod swoją nazwą, z ikoną.

Gotowy do tłumaczenia od razu

Podczas pracy z blokami tylko w PHP istnieją dwa odrębne zagadnienia związane z tłumaczeniem i warto wyraźnie rozróżnić, o które chodzi.

Pierwsze to statyczne ciągi znaków wbudowane w Twój szablon PHP — etykiety, teksty przycisków, teksty interfejsu. Są one obsługiwane przez __() i _e(), tak jak w każdym pliku PHP WordPress. W powyższym bloku etykieta gwiazdek jest przykładem:

/* translators: %d: star rating out of 5 */
$stars_label = sprintf( __( '%d out of 5 stars', 'my-plugin' ), $stars_count );

Standardowe narzędzia WordPress wykrywają je automatycznie. Nic dodatkowego nie jest potrzebne.

Drugie zagadnienie to treść wprowadzana przez użytkownika przechowywana jako atrybuty bloku — treść opinii, imię recenzenta, firma. To jest treść, którą Twoi redaktorzy faktycznie wpisują do bloku, i __() jej nie dotyka. Na wielojęzycznej stronie te wartości atrybutów muszą być tłumaczone na każdy język osobno, a to nie jest coś, czym WordPress zarządza samodzielnie.

Gato AI Translations for Polylang obsługuje bloki tylko w PHP od razu po instalacji, tak samo jak obsługuje Gutenberg, Bricks, Elementor i inne page buildery. Nie jest wymagana żadna dodatkowa konfiguracja.

Wszystkie atrybuty typu string są automatycznie rejestrowane do tłumaczenia. Jeśli określone pole nie powinno być tłumaczone — wewnętrzne odwołanie, URL, kod numeryczny przechowywany jako ciąg znaków — możesz je wyłączyć za pomocą filtra.

Dla bloku opinii w tym artykule imię recenzenta, firma i treść są tłumaczone automatycznie — bez żadnej konfiguracji poza instalacją wtyczki.

Czego bloki tylko w PHP (jeszcze) nie mogą zrobić

Obecne ograniczenia bloków tylko w PHP:

  • Brak bloków wewnętrznych ani zagnieżdżania. Nie możesz umieszczać innych bloków wewnątrz bloku tylko w PHP.
  • Brak edycji tekstu sformatowanego na kanwie. Komponent RichText wymaga JavaScript. Kontrolki tekstowe są renderowane tylko jako pole tekstowe w panelu bocznym.
  • Pola tekstowe w panelu bocznym są jednoliniowe. Atrybut string staje się TextControl, nie TextareaControl — nie idealne dla dłuższej treści.
  • Brak atrybutów selektora obrazów ani mediów. Obsługa przesyłania obrazów/plików jest planowana na późniejsze wydanie za pomocą Block Fields API.
  • Podgląd w edytorze ma opóźnienie. Zmiany atrybutów wyzwalają żądanie REST API w celu ponownego renderowania na serwerze, więc podgląd nie aktualizuje się natychmiastowo.

W przypadku prostych ustrukturyzowanych bloków — opinii, CTA, powiadomień, biogramów autorów, list firm — bloki tylko w PHP trafiają w dziesiątkę. Dla wszystkiego wymagającego bogatej edycji na kanwie, rejestracja z JavaScript pozostaje właściwym narzędziem.

Co dalej

Bloki tylko w PHP w WordPress 7.0 sprawiają, że tworzenie bloków jest dostępne dla każdego dewelopera PHP. Jeden plik PHP, jedno wywołanie register_block_type() i masz w pełni funkcjonalny blok Gutenberga z kontrolkami w panelu bocznym, podglądem na żywo na kanwie i natywną obsługą stylów. Piszesz PHP. Otrzymujesz blok. Bez toolingu. Bez kompilacji. Bez JavaScript.

Jeśli tworzysz wielojęzyczne strony, Gato AI Translations działa bezproblemowo z blokami tylko w PHP — Twoja treść jest gotowa do tłumaczenia od pierwszego dnia.

Gotowy, żeby pójść dalej?


Dowiedz się, co będzie dalej

Zapisz się do naszego newslettera: dowiedz się, gdy wydamy nową wersję, uruchomimy nową wtyczkę lub będziemy mieli nowości do przekazania.