
⚡ Jak dodać swój shortcode w WordPress: przykłady i kod
Potrzebują Państwo wyświetlić datę ostatniej aktualizacji wpisu w stopce każdego artykułu. Albo wstawić formularz subskrypcji dokładnie w środku tekstu, bez edytora kodu i kombinowania z szablonami. W WordPressie służą do tego shortkody.
Shortkod to krótki znacznik w nawiasach kwadratowych: [myshortcode]. WordPress znajduje go w treści i podmienia na wynik funkcji PHP. Standardowych shortkodów, takich jak [gallery] czy [embed], używają Państwo stale, nawet się nad tym nie zastanawiając. Ale własny shortkod to dźwignia: raz napisana logika, a redaktor wstawia ją gdziekolwiek trzema kliknięciami.
W 10 minut stworzą Państwo pierwszy działający shortkod: od pustej funkcji po znacznik z atrybutami i zagnieżdżoną treścią. Kod jest prawdziwy, uruchamia się na każdym współczesnym WordPressie, przetestowany na witrynie testowej.
💡 Szybki przegląd:
- Funkcja
add_shortcode: co przyjmuje i jak jest zbudowana od środka - Podstawowy shortkod
[current_year], bieżący rok w tekście - Shortkod z atrybutami
[cta text="Скачать"], niestandardowy przycisk - Shortkod z zagnieżdżoną treścią
[notice]Текст[/notice], stylizowany blok - Podłączanie przez wtyczkę lub
functions.php: plusy i minusy każdego sposobu - Typowe błędy:
echozamiastreturn, konflikt nazw, pusty atrybut w PHP 8+
Co potrafi add_shortcode i jak działa
Funkcja add_shortcode to jedyny standardowy sposób zarejestrowania nowego shortkodu w WordPressie. Przyjmuje dwa parametry:
$tag(string), nazwa shortkodu, którą będą Państwo wpisywać w nawiasach kwadratowych. Tylko litery, cyfry i podkreślenia. Spacje i znaki specjalne& / < > [ ] =są zabronione, WordPress po cichu odmówi rejestracji takiego znacznika.$callback(callable), nazwa funkcji PHP, która uruchomi się po wykryciu shortkodu. To właśnie ona generuje ten HTML, który zobaczy odwiedzający.
Kod źródłowy funkcji to pięć linii logiki i dwa zabezpieczenia przed błędami (pełny listing na developer.wordpress.org):
1 function add_shortcode( $tag, $callback ) { 2 global $shortcode_tags; 3 4 if ( '' === trim( $tag ) ) { 5 _doing_it_wrong( 6 __FUNCTION__, 7 __( 'Invalid shortcode name: Empty name given.' ), 8 '4.4.0' 9 ); 10 return; 11 } 12 13 if ( 0 !== preg_match( '@[<>&/\[\]\x00-\x20=]@', $tag ) ) { 14 _doing_it_wrong( 15 __FUNCTION__, 16 sprintf( 17 /* translators: 1: Shortcode name, 2: Space-separated list of reserved characters. */ 18 __( 'Invalid shortcode name: %1$s. Do not use spaces or reserved characters: %2$s' ), 19 $tag, 20 '& / < > [ ] =' 21 ), 22 '4.4.0' 23 ); 24 return; 25 } 26 27 $shortcode_tags[ $tag ] = $callback; 28 }
Kluczowy moment: $shortcode_tags to globalna tablica. WordPress przechowuje w niej wszystkie zarejestrowane shortkody. Podczas renderowania treści rdzeń przechodzi przez tę tablicę i dla każdego znalezionego znacznika wywołuje powiązaną funkcję. Wynikają z tego dwie konsekwencje:
- *Rejestruj na haku
init.* Jeśli podepną Państwoadd_shortcodebezpośrednio w pliku wtyczki, może ona zadziałać przed pełną inicjalizacją WordPressa. Prawidłowy sposób to opakowanie w hak:
1 add_action( 'init', 'my_register_shortcodes' ); 2 3 function my_register_shortcodes() { 4 add_shortcode( 'mytag', 'my_shortcode_callback' ); 5 }
- Prefiks jest obowiązkowy. Globalna tablica jest jedna dla wszystkich wtyczek i motywu. Nazwą Państwo shortkod
[button], a Państwa[button]po cichu nadpisze taki sam shortkod z wtyczki formularzy. Prefiks w rodzajumyplugin_lub unikalnego skrótu rozwiązuje problem. W poniższych przykładach używam prefiksumysite_, w rzeczywistym projekcie proszę go zastąpić własnym.
Krok 1: prosty shortkod bez parametrów
Najkrótsza droga do działającego shortkodu to trzy linie w functions.php motywu potomnego (lub we wtyczce Code Snippets, tak jest bezpieczniej, nie zginie przy aktualizacji motywu).
Proszę dodać ten kod i zapisać:
1 add_shortcode( 'mysite_current_year', 'mysite_display_current_year' ); 2 3 function mysite_display_current_year() { 4 return date( 'Y' ); 5 }
Teraz w dowolnym wpisie lub na stronie proszę wpisać [mysite_current_year]. Na froncie zamiast shortkodu wyświetli się bieżący rok: „2026".
Co tu się dzieje. Funkcja mysite_display_current_year nie przyjmuje argumentów, wywołuje funkcję PHP date('Y') i zwraca ciąg czterech cyfr. WordPress podstawia ten ciąg dokładnie w to miejsce, w którym stał shortkod. Żadnej magii.
Gdzie to zastosować w praktyce: rok w stopce (© [mysite_current_year]), wiek projektu w tekście („działamy od [mysite_current_year] roku"), automatyczna aktualizacja dat na stronach prawnych.
Krok 2: shortcode z atrybutami
Shortcode bez parametrów jest przydatny, ale prawdziwa elastyczność zaczyna się od atrybutów. Klasyczny przykład: przycisk z konfigurowalnym tekstem i linkiem:
1 add_shortcode( 'mysite_cta', 'mysite_cta_button' ); 2 3 function mysite_cta_button( $atts ) { 4 $atts = shortcode_atts( 5 array( 6 'text' => 'Learn more', 7 'url' => '#', 8 ), 9 $atts, 10 'mysite_cta' 11 ); 12 13 return sprintf( 14 '<a href="%s" class="mysite-cta-button">%s</a>', 15 esc_url( $atts['url'] ), 16 esc_html( $atts['text'] ) 17 ); 18 }
W edytorze należy użyć go tak:
1 [mysite_cta text="Download plugin" url="https://example.com/myplugin/"]
Funkcja shortcode_atts robi trzy rzeczy jednocześnie: scala atrybuty użytkownika z wartościami domyślnymi, filtruje tylko znane klucze i normalizuje pusty ciąg do tablicy (bez niej, przy wywołaniu [mysite_cta] bez atrybutów w PHP 8+, wystąpi TypeError, ponieważ pierwszy parametr funkcji callback otrzyma pusty ciąg, a nie tablicę).
*Dlaczego esc_url i esc_html.* Shortcode wstawia edytor, dziś jest to Pan/Pani, a jutro content manager bez dostępu do kodu. Eskapowanie na wyjściu zabezpiecza przed przypadkowym XSS, gdyby do atrybutu text trafił nawias lub znacznik.
Krok 3: shortcode z zagnieżdżoną treścią
Niektóre shortkody opakowują fragment tekstu: [mysite_notice]Важное сообщение[/mysite_notice]. Zagnieżdżona treść trafia do callbacka jako drugi parametr, $content. Typowy scenariusz: stylizowany blok z ostrzeżeniem:
1 add_shortcode( 'mysite_notice', 'mysite_notice_box' ); 2 3 function mysite_notice_box( $atts, $content = null ) { 4 $atts = shortcode_atts( 5 array( 6 'type' => 'info', 7 ), 8 $atts, 9 'mysite_notice' 10 ); 11 12 $class = 'notice-' . esc_attr( $atts['type'] ); 13 14 return sprintf( 15 '<div class="mysite-notice %s"><p>%s</p></div>', 16 $class, 17 do_shortcode( $content ) 18 ); 19 }
Proszę zwrócić uwagę na do_shortcode( $content ). Jeśli wewnątrz Pana/Pani shortcodu edytor wstawił inny shortcode (na przykład [mysite_current_year]), to opakowanie uruchomi również i jego. Bez do_shortcode zagnieżdżone shortkody wyświetlą się jako tekst w nawiasach kwadratowych, surowe [mysite_current_year] zamiast „2026".
CSS dla bloku, minimalny, na początek:
1 .mysite-notice { 2 border-left: 4px solid #2271b1; 3 background: #f0f6fc; 4 padding: 1em 1.2em; 5 margin: 1.5em 0; 6 border-radius: 4px; 7 } 8 .mysite-notice.notice-warning { 9 border-left-color: #dba617; 10 background: #fcf9e8; 11 }
Proszę dodać style w style.css motywu potomnego lub przez Wygląd → Dostosuj → Dodatkowy CSS.
Krok 4: shortcode wewnątrz wtyczki (podejście obiektowe)
Gdy shortkodów jest więcej niż trzy, functions.php zamienia się w śmietnik. Czas wynieść logikę do osobnej wtyczki, a najlepiej do klasy. Oto szkielet miniwtyczki z jednym shortkodem:
1 <?php 2 /** 3 * Plugin Name: MySite Shortcodes 4 * Description: Custom shortcodes for the site. 5 * Version: 1.0.0 6 * Requires PHP: 7.4 7 */ 8 9 defined( 'ABSPATH' ) || exit; 10 11 class MySite_Shortcodes { 12 13 public static function init() { 14 add_action( 'init', array( __CLASS__, 'register' ) ); 15 } 16 17 public static function register() { 18 add_shortcode( 'mysite_email', array( __CLASS__, 'email_obfuscated' ) ); 19 } 20 21 public static function email_obfuscated( $atts ) { 22 $atts = shortcode_atts( 23 array( 'address' => '' ), 24 $atts, 25 'mysite_email' 26 ); 27 28 if ( ! is_email( $atts['address'] ) ) { 29 return ''; 30 } 31 32 return sprintf( 33 '<a href="mailto:%1$s">%1$s</a>', 34 antispambot( $atts['address'], 1 ) 35 ); 36 } 37 } 38 39 MySite_Shortcodes::init();
Proszę umieścić ten plik w wp-content/plugins/mysite-shortcodes/mysite-shortcodes.php i aktywować wtyczkę w panelu administracyjnym. Shortcode [mysite_email address="hello@example.com"] wyświetli link zabezpieczony przed spam-botami, funkcja antispambot koduje znaki adresu e-mail na encje HTML.
Dlaczego klasa, a nie zestaw funkcji. Przestrzeń nazw: trzy shortkody w klasie nie kolidują z zewnętrznymi funkcjami. Plus autoloading, plus czytelny kod, jeśli wtyczka rozrośnie się do kilkunastu shortkodów.
Testowanie shortcodu przed publikacją
Po dodaniu kodu proszę sprawdzić trzy scenariusze:
- Shortcode bez atrybutów. Po prostu
[mysite_cta], powinien wyrenderować się z wartościami domyślnymi (tekst „Learn more", link#). - Shortcode z atrybutami. Pełen zestaw parametrów, wszystkie wartości zostały pobrane i wyświetlone poprawnie.
- Błąd w atrybutach. Nieprawidłowy email w
[mysite_email], funkcja po cichu zwraca pusty ciąg, zamiast zepsuć stronę.
Ważne: nigdy nie należy używać echo wewnątrz funkcji callback. Shortcode musi zwracać ciąg znaków przez return. Jeśli wyprowadzi się HTML przez echo, pojawi się on nie w miejscu shortcodu, ale na samej górze strony, ponieważ WordPress uruchamia renderowanie shortkodów przed wyprowadzeniem treści. Ta sama logika co w filtrach: funkcja oddaje wartość, a silnik sam decyduje, gdzie ją wstawić.
Drugi niuans: jeśli shortcode się nie wyświetla (widzą Państwo [mysite_cta] jako tekst, a nie przycisk), proszę sprawdzić, czy funkcja jest zarejestrowana na haku init, a nie bezpośrednio w ciele wtyczki. Bez init globalna tablica $shortcode_tags może nie być jeszcze gotowa na przyjęcie nowych znaczników.
Shortcode w motywie a we wtyczce: co wybrać
Kryterium |
| Osobna wtyczka |
|---|---|---|
Szybkość startu | Szybciej, plik jest już załadowany | Nieco wolniej, osobny plik |
Przenośność | Związany z motywem | Działa z każdym motywem |
Przetrwanie podczas aktualizacji | Ginie podczas aktualizacji motywu | Żyje niezależnie |
Wygoda edycji | Wygląd → Edytor plików motywu | Edytor wtyczek lub FTP |
Dla ilu shortkodów | 1-3 | 4+ |
Zasada: zaczynają Państwo od functions.php na stronie testowej, tworzą trzy shortkody, a następnie wynoszą je do wtyczki. Aktualizacja motywu za pół roku nie pogrzebie Pana/Pani logiki, a przeniesienie shortkodów na inny projekt zajmie minutę.
⁉️🤔 Często zadawane pytania
Jaka jest różnica między shortcode’em a blokiem Gutenberga?
Shortcode to tekstowy tag w nawiasach kwadratowych, który jest przetwarzany po stronie serwera. Blok to wizualny komponent edytora, komponent React z ustawieniami w panelu bocznym. Shortcode’y pojawiły się w WordPress 2.5 (2008), bloki, w 5.0 (2018). Dziś bloki są podstawowym sposobem wstawiania dynamicznej treści, ale shortcode’y pozostają aktualne: są prostsze w tworzeniu, nie wymagają znajomości JavaScript i działają w każdym edytorze, w tym w Classic Editor i konstruktorach stron.
Shortcode to tekstowy tag, który WordPress zastępuje wynikiem funkcji PHP podczas generowania strony. W przeciwieństwie do bloku Gutenberga, shortcode nie ma interfejsu wizualnego w edytorze: content manager wpisuje
[myshortcode]jako tekst, a na froncie widzi gotowy HTML.
Czy można użyć shortcode’a wewnątrz innego shortcode’a?
Tak. Jeśli funkcja callback zewnętrznego shortcode’a opakowuje zagnieżdżoną treść w do_shortcode(), wewnętrzne shortcode’y zadziałają poprawnie: [notice][current_year][/notice] wyświetli stylizowany blok z bieżącym rokiem. Bez do_shortcode() zagnieżdżony shortcode pozostanie tekstem w nawiasach kwadratowych.
Zagnieżdżone shortcode’y są przetwarzane rekurencyjnie: WordPress przechodzi przez ciąg znaków kilka razy, aż nie pozostaną żadne nieprzetworzone tagi. Ale aby to zadziałało, zewnętrzny shortcode musi jawnie wywołać
do_shortcode($content). W przeciwnym razie ciąg[current_year]pozostanie tekstem, zamiast zamienić się na „2026".
Dlaczego mój shortcode nie działa i wyświetla się jako tekst w nawiasach kwadratowych?
Trzy częste przyczyny. Pierwsza: add_shortcode zostało wywołane przed hookiem init, proszę przenieść rejestrację do wnętrza add_action('init', ...). Druga: literówka w nazwie tagu: [my_shortcode] w edytorze, a zarejestrowano myshortcode. Trzecia: funkcja callback używa echo zamiast return, przez co wynik trafia na początek strony, a w miejscu shortcode’a jest pusto.
Najczęściej winowajcą jest
echozamiastreturnw funkcji callback. WordPress wywołuje procedury obsługi shortcode’ów przed wyświetleniem głównej treści, więc wynikechotrafia do bufora wyjściowego wcześniej niż nagłówek strony. Proszę otworzyć kod źródłowy strony (Ctrl+U): jeśli widzi Pan/Pani HTML shortcode’a na samej górze, przed<html>, problem leży właśnie w tym.
Czy należy eskejpować dane wyjściowe shortcode’a?
Obowiązkowo. Shortcode przyjmuje atrybuty od redaktora, a zatem potencjalnie od dowolnego użytkownika z uprawnieniami autora lub redaktora. esc_html() dla tekstu, esc_url() dla linków, esc_attr() dla atrybutów HTML. Wyjątek stanowi sytuacja, gdy świadomie zwraca Pan/Pani znaczniki HTML (np. <div class="notice">). Ale nawet wtedy należy eskejpować atrybuty wewnątrz tych znaczników.
Tak, eskejpowanie jest obowiązkowe dla wszystkiego, co pochodzi z atrybutów shortcode’a lub danych wprowadzonych przez użytkownika. Nawet jeśli dziś shortcode’y wstawia tylko Pan/Pani, jutro dostęp do edytora może otrzymać content manager.
esc_html()dla tekstu,esc_url()dla linków,esc_attr()dla atrybutów HTML chronią przed przypadkowym lub celowym atakiem XSS.
Ile shortcode’ów można zarejestrować na jednej stronie?
Nie ma technicznego limitu: $shortcode_tags to zwykła tablica PHP, więc o pamięć serwera oprze się Pan/Pani znacznie później niż o zdrowy rozsądek. W praktyce po 15-20 niestandardowych shortcode’ach warto się zastanowić: czy nie pora przenieść części z nich do bloków Gutenberga? Shortcode’y z unikalną logiką (zaciemnianie adresów e-mail, warunkowe wyświetlanie według roli) proszę zostawić. Shortcode’y służące wyłącznie do stylizacji tekstu ([highlight]) lepiej zastąpić stylem bloku lub klasą CSS.
Technicznie rzecz biorąc, można ich mieć dowolną liczbę, tablica
$shortcode_tagsnie ma sztucznego limitu. W praktyce ponad 20-25 shortcode’ów na jednej stronie świadczy o tym, że część logiki warto już przenieść do bloków. Każdy shortcode dodaje narzut na parsowanie treści: przed wyświetleniem WordPress przechodzi przez całą tablicę zarejestrowanych tagów i szuka dopasowań w tekście wpisu.
Czy warto pisać własne shortcode’y, czy wystarczą gotowe wtyczki?
Gotowa wtyczka pokrywa większość typowych zadań: formularze, Contact Form 7, tabele, TablePress, siatki, dowolny page builder. Własny shortcode jest potrzebny, gdy logika jest specyficzna dla Pana/Pani strony i nie ma gotowego rozwiązania: wyświetlenie pola niestandardowego dokładnie w tym miejscu strony, data następnego webinaru z bazy danych, spersonalizowane powitanie zależne od roli użytkownika.
Krótko mówiąc: do typowych funkcji proszę użyć wtyczki i nie programować. Do unikalnej logiki, add_shortcode + functions.php lub miniwtyczka. Kodu w każdym z powyższych przykładów jest mniej niż dziesięć linijek. Po opanowaniu tych trzech wzorców (prosty, z atrybutami, z zagnieżdżoną treścią) rozwiąże Pan/Pani zdecydowaną większość zadań, do których w ogóle pisze się niestandardowe shortcode’y.



