Użycie filtrów w Wordpresie

.

WordPress jest w znacznej mierze oparty na filtrach i akcjach. Niniejszy wpis ma na celu objaśnienie zasady działania oraz sposób użycia tych pierwszych.

Treść poniżej przeznaczona jest dla osób, które znają jezyk PHP na poziomie co najmniej podstawowym.

Co to jest filtr ?

Filtr to rodzaj haka, który WordPress wykorzystuje i udostępnia do modyfikacji łańcuchów znaków przed ich zapisem do bazy danych lub wyświetleniem w przeglądarce. WordPress posiada dwa rodzaje haków, tj. filtry i akcje.
Modyfikacje danych z udziałem filtra są dokonywane za pomocą metody klasy PHP lub funkcji modyfikującej. Możliwe jest wykorzystanie już istniejeącego kodu, niezależnie od tego czy pochodzi on z jądra Wordpresa, funkcji PHP czy klas tworzonych przez osoby trzecie. Innymi słowy podczepić do filtra da się wszystko co ujęto w kod języka PHP.

Funkcja filtra pownna przyjmować co najmniej jeden argument ( za wyjątkiem przypadku gdy modyfikuje ona globalne zmienne) i zwracać łańcuch znaków. Pod jeden filtr można podłączyć wiele funkcji modyfikujących, które kolejno będą zmieniać podane im dane. Z racji tego, że funkcje filtrów są skolejkowane, należy pamiętać, o tym, że każda z nich powninien zwracać zmodyfikowane przez sibie dane. Jeżeli w którejś z nich zapomnimy zwrócić dane cały filtr zwróci null.

Umiejscowienie filtrów w kodzie Wordpresa

Funkcje lub klasy z metodami dla filtrów mogą zostać umieszczone w którymś z plików wtyczki lub w functions.php aktywnego motywu. Na potrzeby tego wpisu użyta zostanie ta druga opcja.

Rejestracja funkcji dla filtra

Po zdefiniowaniu funkcji modyfikującej dane wejściowe w pliku functions.php należy ją dodać do filtra co realizuje się za pomocą funkcji add_filter

Funkcja add_filter przyjmuje cztery argumenty, z których tylko dwa pierwsze są wymagane i są to:
nazwa filtra ( np. the_title, the_content czy pre_kses ),
nazwa funkcji modyfikująca dane ( np. my_func ) ,
waga filtra (np. 1 ),
liczba argumentów jaką przyjmuje funkcja podana jako drugi argument ( np. 2) .

Waga funkcji filtra służy określeniu jej miejsca w kolejce do modyfikacji danych, im mniejsza jej wartość tym później funkcja zostanie wywołana.

Popatrzmy na trywialny przykład, który używa filtra the_title z funkcją, która dodaje gwiazdkę przed pierwszą i za ostatnia literą tytułu wpisu. Kod powinien znaleźć się pliku functions.php


 add_filter("the_title","modify_the_title")
 function modify_the_title($title){
  return '*'. $title . '*';
 }

Wywoływanie funkcji dla filtra

Załóżmy, że chcemy dodać do filtra funkcję modyfikującą, która jest domyślnie zdefiniowana w PHP.

W pliku functions.php umieszczamy linijke kodu jak poniżej:


add_filter('my_own_title_hook',"str_repeat",10,2);

następnie w jednym z plików aktywnego motywu, np. index.php dodajemy kod:


<?php echo apply_filters('my_own_title_hook',get_the_title(),3); ?>

Powyższa linijka kodu, gdy umieszczona w pętli Wordpresa, wyświetli tytuł każdego wpisu 3 razy.

Przykład powyżej, mimo, że niezbyt użyteczny, pokazuje jak dodać własny filtr i wywołać doczepione do niego funkcje wykorzystując funkcję apply_filters.

Funkcja apply_filters, która jako argumenty przyjmuje kolejno nazwę filtra oraz argumenty dla funkcji modyfikującej ( w ilości określonej w funkcji add_filter ) pozwala wywołać wszystkie funkcje podczepione do filtra, jak również tworzyć własne filtry.

Wyrejestrowywanie funkcji filtrów

Do wyrejestrowywania funkcji dla filtra służy funkcja remove_filter. Funkcja ta przyjmuje kilka argumentów i są to kolejno:
nazwa filtra, dla którego dana funkcja ma zostać wyrejstrowana (np. the_title),
nazwa funkcji do wyrejestrownia (np. my_func),
waga wyrejestowywanej funkcji, tak jak została zdefiniowana w funkcji add_filter (np. 3),
liczba akceptowanych argmentów ( np . 3).

Dwa ostatnie argumenty są opcjonalne.

Załóżmy, że chcemy wyrejestrować funkcje odpowiedzialne za wyświetlanie emotikonów w wypisach wpisu.
czego można dokonać umiesczając kod jak poniżej w pliku funcitons.php.

Wyrejestrowywanie wszystkich funkcji modyfikujących dla filtra

Wszystkie funkcje dla określonego filtra można usunąć z pomocą funkcji remove_all_filters.
Funkcja ta przyjmuje nazwę filtra jako pierwszy argument i opcjonalnie wagę funkcji, które mają być usunięte (jak sprecyzowane w funkcji add_action).

Wszystkie funkcje dla filtra the_author można usunąć z pomocą kodu jak poniżej:


remove_all_filters("the_title")

Powyższy kod należy umieścić w pliku functions.php.

Zdefiniowane filtry i zarejestrowane funkcje dla nich

Pełną tablicę filtrów można zobaczyć umiesczając poniższy kod w pliku functions.php


global $wp_filter,$merged_filters;
var_dump($wp_filter);
var_dump($merged_filters);
die();

Nazwy funkcje zarejestrowanych dla wybranego filtra można sprawdzić przy pomocy kodu jak poniżej:


global $wp_filter,$merged_filters;
var_dump($wp_filter['tu_nazwa_filtra]);
die();

Jeżeli chcemy programistycznie sprawdzić czy określona funkcja została dodana do filtra, możemy skorzystać z funkcji has_filter, która przyjmuje nazwę filtra jako pierwszy argument oraz nazwę funkcji do wyszukania jako drugi i zwraca jej wagę lub false w przypadku jej braku.


if(!has_filter('the_title','convert_to_uppercase')){
  add_filter('the_title','convert_to_uppercase');
}

Filtrownanie danych w Wordpresie to dość rozległy temat, powyższe przykłady w żadnym stopniu nie wyczerpują tematu, pokazują jednak jak korzystać z fantastycznej funkcjonalności jaką oferują filtry. Zaprasza do testowania.

Listę domyślnie zdefiniowanych filtrów w Wordpresie można znaleźć w pliku wp-includes/default-filters.php.

Więcej szczegółów na temat poszczególnych filtrów można znaleźć na tej stronie kodeksu Wordpresa.


Komentarze ( 4 )


Bardzo to ładnie opisałeś. Ale jeszcze czegoś tu nie rozumiem. Czy każda funkcja wordpresa jest filtrem ? Czy filtr jest takim łącznikem miedzy funkcjami ? Potrzebowałem coś ostatnio zrobić w wordpressie i chodziło o lekką modyfikacje treści linku nastepny i poprzedni post dla posta. Theme jaki używa generuje te linki tak <?php previous_post_link( '%link', '' . _x( '>>', 'Previous post link', 'twentyten' ) . ' %title' ); ?> a potrzebowałem skrócić wartość %title do 30 znaków. No i zastosowałem to, wrzuciłem to do katalogu pluginów function change_link_prev($text) { // tu preg_match wychwytuje tekst pomiedzy // skracam do 30 znakow i tworze od nowa linka return $text; } add_filter('previous_post_link', 'change_link_prev'); No i chodzi mi o to co ja właściwe zrobiłem ? Tzn chciałbym potwierdzić sobie czy dobrze rozumiem działanie filtra. Czyli add_filter powoduje zarajestrowanie w "filtrze wordpresa" wykonania funkcji mojej, po wywołaniu innej funkcji ? :) Bo funkcja previous_post_link wykonuje normalnie echo 'linku' I to jest przechwyceone przez filtr i przekazane do mojej funkcji i potem dopiero wyknuje sie wlasciwe echo 'linku' przerobionego przez moja funkcje ? uff ciezko to pisac :) pozdrawiam Paweł


Filtry, podobnie jak akcje, są hakami. Oznacza to, że dodając kod do określonego filtra po prostu podłączasz swój kawałek funkcjonalności do wykonania. Gdzie ten kod zostanie wykonany, zależy od tego do jakiego filtra podłączyłeś. Zasadniczon filtry sa uruchamiane podczas wywołań innych funkcji i mają takie nazwy jak funkcje, których normalnie używasz w wordpresie, w tym także funkcji motywów (template tags). Filtr ze swojej natury, co stosuje się nie tylko do wordpresa, przyjmuje jakąś wartość. W jakiś sposób ją modyfikuje a następnie zwraca. Filtry w Wordpresie są przechowywane w tablicy. Funkcja add_filter ma za zadanie podczepić Twój kod do filtra (czyli w praktyce dodać funkcję lub metodę z nim do ów kontenera). Kod zostanie wywołany wówczas gdy wywołana zostanie odpowiednia funkcja, w której kodzie znajduje się odwołanie do apply_filters. Oczywiście nie każda funkcja posiada filtr. Popatrz sobie na przykład na funkcję wp_get_attachment_metadata (wp-includes/post.php). Na końcu ma ona wywołanie funkcji apply_filters. Pierwszym argumentem dla niej jest wp_get_attachment_metadata, co w praktyce oznacza, że funkcja ta wywołuje na końcu kod podczepiony do filtra wp_get_attachment_metadata. Kod ten po przefiltrowaniu jest zwracany. Kod do filtra, także tego, o którym mowa wyżej, można podczepić z poziomu wtyczki, lub w pliku functions.php motywu Wordpresa. Reasumując, jak napisałeś wyżej, podczepiając Twój kod pod określony filtr masz możliwość wykonania go zanim funkcja, w której zajduje się wywołanie funkcji apply_filters('nazwa_filtra',...) zwróci lub wyświetli określona zawartość. Filtry uruchamiane są zazwyczaj tuż przed końcem funkcji, która wywołuje apply_filters.


Hmm juz mi torche rozjaśniłeś, ale dalej mam wątpliwości :) Wracają do mojego kodu. Zajrzałem do pliku wp-insludes/link-template.php w którym zdefinowana jest funkcja previous_post_link i on dalej wywołuje adjacent_post_link i ta funkcja na końcu $adjacent = $previous ? 'previous' : 'next'; echo apply_filters( "{$adjacent}_post_link", $format, $link ); i to ten aplly_filters powoduje wywolanie mojej funkcji która przypisałem do tego filtra o nazwie 'previous_post_link' przez kod w moim pluginie add_filter('previous_post_link', 'change_link_prev'); :) ? Nie rozumiem gdzie jest jakby zarejestrowany dany filtr ? No bo moja funkcja przypięła sie do filtra 'previous_post_link'. Ale jakby go nie było w wczeniej w tej funkcji 'adjacent_post_link' to moje add_filter nie mialo by sensu ? Miałem po prostu szczescie ze to wywolanie apply_filter dla 'previous_post_link' było w funkcji 'adjacent_post_link' ? A gdybym wyknał takie przypisanie ( w sensie ze byla by fukncja 'previous_post_link2' ale nie miała by w sobie apply_filter dla 'previous_post_link2' po add_filter('previous_post_link2', 'change_link_prev'); to pewnie nic by sie nie wykonało ?


Jak wspomniałem wyżej, Twój kod wykona się tylko wtedy gdy dodasz go do odpowiedniego filtra (z pomocą funkcji add_filter). Aby kod dla danego filtra mógł zostac wykonany, gdzieś w kodzie wordpresa musi nastąpić wywołanie funkcji apply_filters('nazwa_filtra_do_którego dodałeś kod'). Filtry mają najczęściej takie nazwy jak niektóre wbudowane funkcje silnika wordpresa i to właśnie w tych funkcjach silnika wywoływana jest funkcja apply_filters ... Innymi słowy wordpress tworząc odpowiedź na określone zapytanie http wykonuje cały szereg swoich własnych funkcji. Część z nich zawiera wywołania funkcji apply_filters('nazwa_filtra' ...), która wywołuje zewnętrzny kod. Twój kod jest przechowywany w tablicy filtrów, kluczami tej tablicy są nazwy filtrów, wartościami tablice z nazwami funkcji do wykonania dla każdego klucza. Twój kod podłączasz z poziomu wtyczki lub pliku functions.php. W ten sposób, zanim jeszcze większość funkcji wordpresa zostanie wykonana, masz mozliwość podłączenia swojej funkcjonalności, którą potem wordpress uruchomi wywołując funkcjie takie jak the_title, czy previous_post_link. Zasada działania filtrów jest analogiczna do działania akcji. Tyle , że filtr zwraca wartość a akcja to po prostu dodatkowy podporgram, który ma być uruchomiony w określonej chwili tworzenie odpowiedzi na zapytanie z przeglądarki. Mam nadzieję, że trochę Ci się rozjaśniło ;)


Twój komentarz





Niektóre tagi XHTML są dozwolone
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>