WordPress Hooks — akcje i filtry w praktyce
Opublikowano: 10 kwietnia 2026 · Autor: Marcin Szewczyk-Wilgan
Hooki (hooks) to mechanizm, na którym opiera się cały ekosystem WordPressa — każda wtyczka, każdy motyw i sam rdzeń CMS korzystają z akcji i filtrów. To one pozwalają rozszerzać i modyfikować zachowanie WordPressa bez ingerencji w pliki źródłowe. W samym rdzeniu WordPress zdefiniowano ponad 2 500 hooków, a WooCommerce dodaje kolejne setki. Zrozumienie hooków to różnica między osobą, która instaluje WordPressa, a osobą, która go kontroluje. W tym artykule wyjaśniamy, czym są hooki WordPress, jak działają akcje i filtry, jak tworzyć własne hooki i pokazujemy praktyczne przykłady rozwiązujące realne problemy.
Czym są hooki w WordPress
Hooki WordPress to predefiniowane punkty w kodzie, w których możesz „zaczepić" własną funkcję. Gdy WordPress dotrze do takiego punktu podczas generowania strony, wykona wszystkie funkcje, które zostały do niego podpięte. Cały ekosystem wtyczek i motywów opiera się na tym mechanizmie — to nie hack ani obejście, lecz oficjalny, udokumentowany sposób rozszerzania WordPressa.
add_action() lub add_filter(). WordPress sam wywoła Twoją funkcję w odpowiednim momencie.
Akcje (Actions) — wykonaj kod w odpowiednim momencie
Akcje pozwalają uruchomić własny kod w określonym punkcie cyklu życia WordPressa. Akcja nie zwraca wartości — wykonuje zadanie (dodaje HTML, wysyła email, zapisuje do bazy) i kończy działanie. Definiowanie i podpinanie akcji to dwie strony tego samego mechanizmu.
do_action()
Definiuje punkt zaczepienia w kodzie: do_action('nazwa_hooka', $arg1, $arg2). Gdy WordPress natrafi na tę linię, wykona wszystkie funkcje zarejestrowane na hooku nazwa_hooka. Sam rdzeń WordPressa zawiera setki takich punktów — np. do_action('wp_head') w nagłówku każdej strony.
add_action()
Rejestruje Twoją funkcję na wybranym hooku: add_action('wp_head', 'moja_funkcja', 10, 0). Cztery parametry: nazwa hooka, nazwa callbacka, priorytet (domyślnie 10 — im niższa liczba, tym wcześniejsze wykonanie) i liczba argumentów przekazywanych do callbacka (domyślnie 1).
remove_action()
Usuwa wcześniej zarejestrowaną funkcję z hooka: remove_action('wp_head', 'wp_generator'). Warunki: musisz znać dokładną nazwę hooka, funkcji i priorytet. Przydatne do usuwania domyślnych zachowań WordPressa — np. usunięcie meta tagu generator ujawniającego wersję WP (kwestia bezpieczeństwa WordPress).
Filtry (Filters) — przechwytuj i modyfikuj dane
Filtry WordPress pozwalają przechwycić wartość w trakcie przetwarzania, zmodyfikować ją i zwrócić. W odróżnieniu od akcji, filtr zawsze musi zwrócić wartość — jeśli tego nie zrobi, dane zostaną utracone. Filtry działają w izolacji i nie powinny powodować efektów ubocznych.
apply_filters()
Definiuje punkt filtrowania: $content = apply_filters('the_content', $content). WordPress przekazuje wartość $content przez wszystkie zarejestrowane filtry i przypisuje wynik z powrotem do zmiennej. Każdy filtr modyfikuje wartość i przekazuje ją dalej — jak potok (pipeline).
add_filter()
Rejestruje filtr: add_filter('the_content', 'moja_funkcja', 10, 1). Składnia identyczna jak add_action() — nazwa hooka, callback, priorytet, liczba argumentów. Callback otrzymuje wartość do modyfikacji jako pierwszy parametr.
return
Najczęstszy błąd w filtrach: brak instrukcji return. Jeśli callback nie zwróci wartości, filtr przekaże null dalej — treść wpisu, tytuł lub inne dane po prostu znikną. Zawsze kończ callback filtra instrukcją return $wartość;.
echo), zapisywać do bazy danych, wysyłać emaili ani modyfikować zmiennych globalnych. Jeśli potrzebujesz takich efektów, użyj akcji, nie filtra. Filtr z efektami ubocznymi to częsta przyczyna trudnych do wykrycia konfliktów między wtyczkami.
remove_filter()
Działa analogicznie do remove_action(). Usuwa zarejestrowaną funkcję filtra. Nazwa hooka, callback i priorytet muszą się zgadzać. Anonimowe funkcje (closures) nie mogą być usunięte tą metodą.
Akcje vs filtry — kluczowa różnica
Choć akcje i filtry korzystają z tego samego mechanizmu wewnątrz WordPressa (w kodzie źródłowym akcje są wrapperami na filtry), różnią się przeznaczeniem i zachowaniem. Poniższe zestawienie wyjaśnia, kiedy stosować każdy typ.
return. Filtr: musi zwrócić wartość — brak return powoduje utratę danych.
do_action(), add_action(), remove_action(), did_action(). Filtr: apply_filters(), add_filter(), remove_filter(), has_filter(), did_filter().
Najważniejsze hooki WordPress — lista z opisami
WordPress oferuje ponad 2 500 hooków, ale w codziennej pracy wystarczy znać kilkanaście najczęściej używanych. Poniżej zestawienie hooków, które pokrywają większość typowych scenariuszy — od ładowania skryptów po modyfikację treści i zarządzanie panelem administracyjnym.
Najważniejsze akcje WordPress
init — inicjalizacja WordPressa (rejestracja CPT, taksonomii). wp_enqueue_scripts — ładowanie CSS i JS na frontend. wp_head / wp_footer — wstrzykiwanie kodu do nagłówka/stopki. save_post — po zapisaniu wpisu (czyszczenie cache, powiadomienia). admin_init / admin_menu — inicjalizacja panelu i menu. widgets_init — rejestracja widgetów. template_redirect — przed załadowaniem szablonu (przekierowania). wp_login / wp_logout — logowanie i wylogowanie.
Najważniejsze filtry WordPress
the_content — modyfikacja treści wpisu przed wyświetleniem. the_title — modyfikacja tytułu. excerpt_length / excerpt_more — długość i zakończenie wycinka. body_class — klasy CSS elementu body. wp_nav_menu_items — elementy menu nawigacyjnego. login_redirect — przekierowanie po logowaniu. upload_mimes — dozwolone typy plików w uploaderze. cron_schedules — niestandardowe interwały WP-Cron. the_generator — meta tag wersji WP.
Popularne hooki WooCommerce
woocommerce_before_shop_loop — przed listą produktów. woocommerce_after_single_product_summary — po opisie produktu. woocommerce_checkout_process — walidacja zamówienia. loop_shop_per_page — liczba produktów na stronie. woocommerce_product_get_price — modyfikacja ceny. WooCommerce definiuje setki hooków — pełna lista w dokumentacji WooCommerce.
Funkcje diagnostyczne hooków
did_action('nazwa') — ile razy akcja została wykonana. did_filter('nazwa') — ile razy filtr został zastosowany. has_filter('nazwa') — czy do filtra jest podpięta funkcja. current_filter() / current_action() — aktualnie wykonywany hook. Wtyczka Query Monitor wyświetla wszystkie hooki na danej stronie wraz z priorytetami i callbackami.
Priorytet i kolejność wykonywania hooków
Gdy na jednym hooku zarejestrowanych jest wiele funkcji, WordPress wykonuje je w kolejności wyznaczonej przez priorytet. Zrozumienie priorytetu to klucz do przewidywalnego działania hooków — szczególnie gdy kilka wtyczek modyfikuje te same dane.
add_action() / add_filter(). Domyślna wartość to 10. Im niższa liczba, tym wcześniej funkcja się wykona. Funkcja z priorytetem 5 wykona się przed funkcją z priorytetem 10, a ta przed funkcją z priorytetem 20.
add_action() / add_filter() zostały wywołane. W praktyce zależy to od kolejności ładowania wtyczek i motywu.
the_content z priorytetem 10. Wtyczka B dodaje przycisk „Udostępnij" z priorytetem 20. Wynik: treść wpisu → reklamy (priorytet 10) → przycisk udostępniania (priorytet 20). Zmiana priorytetu jednej z wtyczek zmienia kolejność wyświetlanych elementów.
$accepted_args
Czwarty parametr add_action() / add_filter() określa, ile argumentów zostanie przekazanych do callbacka. Domyślnie 1. Jeśli hook przekazuje więcej argumentów (np. save_post przekazuje $post_id, $post, $update), ustaw $accepted_args na 3, aby otrzymać wszystkie.
Tworzenie własnych hooków WordPress
Własne hooki to mechanizm, dzięki któremu Twoja wtyczka lub motyw staje się rozszerzalny — inni deweloperzy mogą podpiąć się do Twojego kodu bez jego modyfikowania. To fundamentalna zasada architektury WordPressa: buduj kod, który inni mogą rozszerzać.
do_action() w Twoim kodzie
Umieść do_action('moj_prefix_po_zapisie', $post_id) w punkcie, w którym inne wtyczki mogą wykonać dodatkowy kod — np. po zapisaniu danych, po imporcie, po aktywacji. Inni deweloperzy podepną swoje funkcje przez add_action('moj_prefix_po_zapisie', 'ich_funkcja').
apply_filters() w Twoim kodzie
Umieść $url = apply_filters('moj_prefix_url', $url) w miejscu, gdzie inne wtyczki mogą zmodyfikować wartość. Jeśli nikt nie podepnie filtra, zwrócona zostanie oryginalna wartość. Filtr daje innym deweloperom kontrolę nad danymi bez ingerencji w Twój kod.
Unikanie kolizji nazw
Zawsze dodawaj unikalny prefiks do nazw własnych hooków — nazwę wtyczki lub identyfikator projektu. do_action('wp_learn_delete_book') zamiast do_action('delete_book'). Bez prefiksu ryzykujesz kolizję z hookiem innej wtyczki o tej samej nazwie.
Sprawdzanie typu zwracanego
Wartość zwrócona z filtra nie jest gwarantowanego typu — ostatni callback decyduje. Zawsze waliduj typ po apply_filters(): jeśli oczekujesz stringa, sprawdź is_string(). Jeśli typ jest nieprawidłowy, zresetuj wartość lub zgłoś błąd. To zabezpieczenie przed źle napisanymi wtyczkami.
Praktyczne przykłady hooków WordPress
Teoria jest ważna, ale hooki najlepiej zrozumieć przez praktykę. Poniżej osiem przykładów, które rozwiązują realne, codzienne problemy — od bezpieczeństwa po WooCommerce. Każdy snippet możesz umieścić w functions.php motywu potomnego lub we własnej wtyczce.
remove_action('wp_head', 'wp_generator'); — usuwa meta tag <meta name="generator" content="WordPress X.X"> z kodu strony. Ujawnianie wersji WordPressa ułatwia atakującym identyfikację podatności — szczegóły w artykule o bezpieczeństwie WordPress.
add_filter('excerpt_length', function(){ return 25; }); — zmienia domyślną długość wycinka z 55 wyrazów na 25. Prosty filtr, który przyjmuje liczbę i zwraca zmodyfikowaną liczbę.
add_filter('login_redirect', function($url, $request, $user){ return home_url('/panel/'); }, 10, 3); — po zalogowaniu użytkownik trafia na /panel/ zamiast na domyślną stronę profilu. Parametr $accepted_args = 3 daje dostęp do obiektu użytkownika — możesz różnicować przekierowanie wg roli.
add_filter('upload_mimes', function($mimes){ $mimes['svg'] = 'image/svg+xml'; return $mimes; }); — dodaje SVG do dozwolonych typów plików w uploaderze mediów. Pamiętaj o sanityzacji SVG ze względu na ryzyko XSS.
add_action('save_post', 'moja_funkcja_czyszczenia_cache'); — automatyczne wyczyszczenie cache strony po każdej aktualizacji wpisu. W callbacku wywołaj API cache swojej wtyczki cache'ującej (WP Super Cache, W3 Total Cache, LiteSpeed Cache).
add_filter('wp_nav_menu_items', function($items, $args){ if($args->theme_location === 'primary') $items .= '<li><a href="/kontakt">Kontakt</a></li>'; return $items; }, 10, 2); — programatyczne dodanie elementu do menu nawigacyjnego bez edycji w panelu.
add_filter('loop_shop_per_page', function(){ return 24; }); — zmienia liczbę produktów na stronie sklepu z domyślnych 16 na 24. Jeden filtr zamiast szukania ustawienia w opcjach WooCommerce.
add_filter('cron_schedules', function($s){ $s['co_5_minut'] = ['interval' => 300, 'display' => 'Co 5 minut']; return $s; }); — dodaje interwał „co 5 minut" do WP-Cron, którego domyślnie WordPress nie oferuje (dostępne są tylko hourly, twicedaily, daily).
Hooki a WordPress 7.0 — nowe API i możliwości
WordPress 7.0 rozbudowuje system hooków o nowe warstwy — Abilities API, Interactivity API i WP AI Client korzystają z tego samego fundamentu, rozszerzając go o możliwości po stronie klienta i integrację z AI.
Hooki jako fundament AI
Abilities API korzysta z systemu hooków do rejestracji zdolności strony. Wtyczki deklarują swoje możliwości przez hooki, a asystenci AI (Claude, ChatGPT, Gemini) odkrywają je za pomocą adaptera MCP. To hooki WordPress połączone z protokołem komunikacji AI.
watch() — hooki po stronie klienta
Nowa funkcja watch() w Interactivity API to odpowiednik hooków po stronie przeglądarki — subskrybuje zmiany stanu i reaguje na nie programatycznie, niezależnie od DOM. Analogia do add_action() / add_filter(), ale w świecie JavaScript i reaktywnego frontendu.
Filtrowanie promptów i odpowiedzi AI
WP AI Client udostępnia hooki do filtrowania promptów przed wysłaniem do modelu AI i odpowiedzi przed ich wykorzystaniem. To ten sam wzorzec co apply_filters('the_content', $content) — ale dla komunikacji z AI. Deweloperzy mogą modyfikować, logować i walidować interakcje z AI.
Hooki w edytorze blokowym
WordPress 7.0 rozwija Full Site Editing o nowe hooki blokowe — filtry dla breadcrumbs, niestandardowe CSS per instancja bloku i rozszerzone Block Bindings. Wzorzec jest spójny: apply_filters() w PHP, dyrektywy w Interactivity API po stronie klienta.
Najczęstsze błędy i dobre praktyki
Hooki są proste w użyciu, ale łatwo popełnić błędy, które prowadzą do trudno diagnozowalnych problemów. Poniżej najczęstsze pułapki i sprawdzone praktyki, które oszczędzą Ci godzin debugowania.
return w filtrze
Najczęstszy błąd. Filtr bez instrukcji return zwraca null — treść wpisu, tytuł, menu lub inne dane znikają. Zawsze kończ callback filtra jawnym return $wartość;, nawet jeśli jej nie modyfikujesz.
echo), wysyła email lub zapisuje do bazy, powoduje konflikty z innymi wtyczkami i trudne do wykrycia błędy. Filtry modyfikują dane — jeśli potrzebujesz efektów ubocznych, użyj akcji.
wp-includes/, wp-admin/). Każda aktualizacja nadpisze Twoje zmiany. Hooki istnieją właśnie po to, aby tego uniknąć. Jeśli nie ma hooka w miejscu, które chcesz zmodyfikować — to rzadkość, ale zgłoś zapotrzebowanie na Trac WordPressa.
do_action('save_data')) mogą kolidować z hookami innych wtyczek. Zawsze dodawaj prefix: do_action('weboptimo_save_data'). Konwencja: nazwa_wtyczki_nazwa_hooka.
add_filter('hook', function(){...})) są wygodne, ale nie mogą być usunięte przez remove_filter(). Jeśli budujesz wtyczkę lub motyw, który inni mogą rozszerzać, używaj nazwanych funkcji lub metod klasy.
functions.php motywu potomnego (child theme). Kod funkcjonalny, niezależny od motywu → własna wtyczka (mu-plugin lub standardowa wtyczka). Szybkie testy → wtyczka Code Snippets. Nigdy w functions.php motywu głównego — zmiana motywu usunie kod.
did_action('hook_name') sprawdza, czy akcja się wykonała. has_filter('hook_name') sprawdza, czy filtr ma podpięte funkcje. W środowiskach z PHP 8.x sprawdź kompatybilność typów w callbackach.
Najczęściej zadawane pytania o hooki WordPress
Akcja wykonuje zadanie w określonym momencie i nie zwraca wartości — np. dodaje kod do nagłówka, wysyła email po publikacji. Filtr przechwytuje dane, modyfikuje je i zwraca zmodyfikowaną wartość — np. zmienia treść wpisu lub długość wycinka. Zasada: akcja ROBI coś, filtr ZMIENIA coś.
Kod związany z wyglądem strony umieść w pliku functions.php motywu potomnego (child theme). Kod funkcjonalny, niezależny od motywu — we własnej wtyczce lub za pomocą wtyczki Code Snippets. Dzięki temu zmiana motywu nie usunie Twojego kodu. Nigdy nie edytuj pliku functions.php motywu głównego.
Oficjalna dokumentacja zawiera referencje akcji i filtrów w Plugin Handbook na developer.wordpress.org. Wtyczka Query Monitor wyświetla wszystkie hooki wykonywane na danej stronie wraz z priorytetami. Narzędzie WP-CLI pozwala listować hooki z linii poleceń.
Tak. Funkcje remove_action() i remove_filter() pozwalają usunąć callbacki dodane przez inne wtyczki. Musisz znać dokładną nazwę hooka, funkcji i priorytet. Anonimowe funkcje (closures) nie mogą być usunięte tą metodą — to powód, dla którego dobrą praktyką jest używanie nazwanych funkcji.
Sam rdzeń WordPressa definiuje ponad 2 500 hooków. WooCommerce dodaje setki kolejnych. Każda wtyczka i motyw mogą rejestrować własne. Typowa strona z kilkunastoma wtyczkami może mieć tysiące aktywnych hooków — to normalny element architektury, nie problem wydajnościowy.
Sam mechanizm hooków jest bardzo lekki. Problem pojawia się, gdy callback podpięty do hooka wykonuje kosztowne operacje — zapytania do bazy, zewnętrzne API, generowanie plików. To nie hook jest wolny, lecz funkcja do niego podpięta. Query Monitor pozwala zidentyfikować wolne callbacki.