Dodano 2016-08-13 01:33:41 przez Daniel
Zaczepy stanowią dla nas (twórców wtyczek) podstawę działania, ponieważ to właśnie dzięki nim jesteśmy w stanie „zaczepić” nasze funkcje. Ta część jest niezwykle istotna ponieważ przedstawiam tutaj nie tylko jak posługiwać się już gotowymi zaczepami ale także jak tworzyć nowe, własne zaczepy otwierając tym samym drogę innym programistom do modyfikowania naszej wtyczki bez konieczności ingerowania w jej kod, tak samo jak platforma WordPress oferuje rozszerzanie jego funkcjonalności bez konieczności ingerowania w kod główny. Warto pamiętać że jakiekolwiek ingerencje w kod platformy WordPress są nie wskazane ze względu na aktualizacje. Podczas aktualizacji pliki WordPressa lub pliki wtyczek są nadpisywane i wszelkie modyfikacje przepadają.
Istnieją dwa rodzaje zaczepów. Pierwszym z nich są akcje zaś drugim filtry. Akcje służą do wykonania jakiejś czynności w odpowiednim momencie zaś filtry służą do manipulacji na danych wyjściowych przekazywanych za pomocą zaczepu.
Warto pamiętać że temat zaczepów występuje w całej platformie, wtyczkach oraz szablonach.
Co będzie robiła nasza piąta wtyczka? Tym razem będzie się działo nieco więcej. Wykorzystamy dotąd zdobytą wiedzę i stworzymy wtyczkę, która będzie wykorzystywała kilka różnych zaczepów. Wykorzystamy filtr do cenzurowania pewnych słów w komentarzach aby zobrazować działanie filtrów. Dodamy sobie też własną stopkę za pomocą zaczepu akcji, zapisywaną jako opcję wtyczki. Dodamy sobie także własny widget wyświetlający kilka linii tekstu pomiędzy którymi utworzymy własne zaczepy. A w międzyczasie omówię kilka innych kwestii związanych z zaczepami oraz przedstawię kilka najczęściej wykorzystywanych zaczepów. No to do dzieła.
Zaczep akcji już wykorzystywaliśmy w naszej pierwszej wtyczce kiedy zaczepialiśmy funkcje do menu w panelu administratora. Ogólnie akcje służą do wywołania funkcji w odpowiednim momencie. W pierwszej wtyczce wykorzystaliśmy zaczep wykonujący się w momencie tworzenia menu w kokpicie. Do tego celu wykorzystujemy funkcję
add_action( $tag, $function, $priority, $accepted_args);
Funkcja pobiera cztery parametry:
Możemy dodać wiele funkcji do jednego zaczepu, stąd sensu nabiera parametr „$priority”. Na przykład w zaczepie „wp_footer” możemy dodać różne elementy do stopki zaś w zaczepie „wp_head” do nagłówka.
Aby wywołać dany zaczep należy wykorzystać funkcję
do_action($tag, $arg = '');
która jest wykorzystywana bardzo często przez wordpressa do wywoływania zaczepów.
Parametry tej funkcji to:
Teraz skoro już znamy podstawy zaczepów wykorzystajmy je w naszej wtyczce. Na początek stworzymy wtyczkę z części pierwszej Tutaj oraz dodamy do niej kod powodujący wyświetlenie napisu „Witryna wykorzystuje wtyczkę Moja piąta wtyczka” w stopce serwisu. W tej części wykorzystamy standardowy szablon „Twenty FourteenWersja 1.7”. Pomijam tutaj nagłówek określający nazwę, autora, wersję i linki wtyczki i przechodzę do konkretów. na początek dodamy akcje do zaczepów.
add_action( 'admin_menu', 'm5w_add_menu' ); add_action( 'wp_footer', 'm5w_add_footer', 99);
Powyższe zaczepy są wykonywane w momencie tworzenia menu kokpitu gdzie dodaliśmy funkcję z naszym menu oraz zaczep „wp_footer”, który jest wykonywany w momencie tworzenia stopki serwisu. W drugim zaczepie dodajemy funkcję wyświetlającą tekst na samym dole strony. Teraz należy napisać funkcje, które właśnie zaczepilismy.
function m5w_add_menu(){ add_menu_page( 'Strona główna wtyczki', 'Moja piąta wtyczka', 'administrator', 'moja-piata-wtyczka', 'glowna_moja_piata_wtyczka', '', 7 ); } function m5w_add_footer() { echo '<br><p>Witryna wykorzystuje wtyczkę "Moja piąta wtyczka"</p>'; }
Podczas dodawania pozycji do menu w kokpicie wykorzystujemy funkcję odpowiedzialną za wyświetlenie strony głównej wtyczki. Teraz dodamy także i tę funkcję.
function glowna_moja_piata_wtyczka(){ echo "Strona główna wtyczki"; }
Po wrzuceniu i aktywacji wtyczki na samym dole strony powinien nam się ukazać doklejony napis. Ogólnie jeśli mamy dostęp do szablonu to stopkę lepiej utworzyć w szablonie.
Istnieje kilka ważniejszych funkcji związanych z akcjami, które są wykorzystywane na co dzień przy tworzeniu wtyczek. Postaram się je tutaj przedstawić w kolejności całkowicie losowej.
do_action_ref_array( $tag, $args );
Ta funkcja ma działanie identyczne jak funkcja do_action() z tym że zamiast kolejnych argumentów pobiera ich tablicę. Ponadto tablica ta jest dodawana przez referencje co oznacza że za pomocą akcji dodanej do danego zaczepu możemy modyfikować wartości w tej tablicy. Tablica argumentów jest tutaj jedynym oraz wymaganym parametrem.
remove_action( $tag, $function_to_remove, $priority, $accepted_args);
Parametry tej funkcji to:
Jak zapewne łatwo się domyślić, funkcja służy do usunięcia wcześniej dodanej akcji do zaczepu. Warto tutaj pamiętać że możemy także usuwać akcje dodane przez platformę WordPress co w połączeniu z możliwością dodawania akcji daje nam nieograniczone możliwości zmian. Warto tutaj także pamiętać o tym że akcja musi najpierw zostać dodana aby mogła być usunięta, tak więc jeśli wywołamy tę funkcję zbyt wcześnie, akcja nie zostanie usunięta.
Aby usunięcie akcji powiodło się pierwsze trzy parametry muszą być takie same jak w momencie dodawania akcji (można znaleźć w dokumentacji – najlepiej sprawdzić w pierwszej kolejności na codex). Jeśli usunięcie akcji powiedzie się funkcja zwróci true a jeśli nie to false.
Przetestowanie tej funkcji w naszej wtyczce nie stanowi problemu. Zaraz pod linijką, w której dodajemy akcję do zaczepu dodajmy naszą funkcję remove_action() z dokładnie tymi samymi parametrami jak na listingu poniżej.
add_action( 'wp_footer', 'm5w_add_footer', 99); remove_action( 'wp_footer', 'm5w_add_footer', 99);
Czy nasz doklejony napis na samym dole strony przestał się wyświetlać? Jeśli tak oznacza to że nasza akcja doklejająca napis na samym dole strony została usunięta zaraz po tym jak została dodana.
remove_all_actions( $tag, $priority);
Parametry tej funkcji to:
Przy wykorzystywaniu tej funkcji lepiej zachować zwiększoną ostrożność, ponieważ dzięki niej można usunąć wszystkie akcje w danym zaczepie naraz. Najłatwiej przedstawić działanie tej funkcji na przykładzie zaczepu wp_head. W tym zaczepie są ładowane najczęściej style szablonu strony. Po dodaniu kodu..
remove_all_actions( 'wp_head' );
.. strona powinna się całkowicie rozsypać (usunięte style). Aby upewnić się że kod zadziałał możesz zajrzeć do źródła strony przed i po dodaniu kodu. A teraz skoro wiemy już jak działa funkcja lepiej usuńmy ją z naszej wtyczki, aby porządek powrócił na naszą stronę główną.
has_action( $tag, $function_to_check);
Parametry tej funkcji to:
Dzięki tej funkcji jesteśmy w stanie sprawdzić czy w momencie jej wywołania zaczep ma jakiekolwiek akcje lub jeśli podamy opcjonalny parametr funkcji do sprawdzenia, czy funkcja została już zarejestrowana.
did_action( $tag );
Ta funkcja sprawdza i zwraca ilość wywołań danego zaczepu lub false jeśli zaczep nie został wywołany.
Istnieje sporo najczęściej wykorzystywanych zaczepów (niedługo powstanie), którą co jakiś czas wydłużam o kolejne pozycje.
Filtry w odróżnieniu od zaczepów akcji pozwalają na manipulację danymi wyjściowymi. Filtry filtrują dane wyjściowe co oznacza że możemy dowolnie modyfikować zwracane treści. Możemy na przykład doklejać linki na końcu lub podmieniać słowa tak jak zrobimy to w naszej wtyczce.
Najważniejsza w tym temacie wydaje się być funkcja
apply_filters( $tag, $value );
która przyjmuje dwa parametry:
W momencie tworzenia filtru nie można zapomnieć o zwróceniu wartości $value dla platformy WordPress.
Filtr to nic innego jak funkcja, która najpierw pobiera parametr, następnie przeprowadza na nim operacje a następnie zwraca ten parametr po zmianach naniesionych podczas operacji. W momencie wywołania funkcji Apply_filter( );
wszystkie dodane są wywoływane wszystkie funkcje dodane do zaczepu. Aby dodać filtr do zaczepu nalezy wykorzystać funkcję.
add_filter( $tag, $function, $priority, $accepted_args );
Parametry tej funkcji to kolejno:
Wszystkie filtry powinny pobierać i zwracać te same argumenty ponieważ są one wykonywane kolejno jeśli jest ich kilka. To co zwraca poprzedni filtr następny pobiera.
A teraz przejdźmy do naszego testowego bloga i przykładowego wpisu „Witaj świecie”, standardowo powinien już tam być przykładowy komentarz ale ja sobie dodam kolejny o treści „pierwszy wpis jest niezły ale drugi lepszy”.
Teraz przejdźmy do kodu naszej wtyczki i napiszmy nasz pierwszy filtr. Na początku dodamy naszą funkcję do zaczepu. Zaczep odpowiadający za tekst komentarzy to comment_text. Następnie napiszemy funkcję, która pobiera jeden parametr (tekst komentarza). Ustalimy sobie dwie tablice wyrazów, w pierwsze te które mają być podmienione zaś w drugiej te na które mają zostać podmienione. Następnie za pomocą funkcji PHP str_replace podmienimy wyrazy i zwrócimy nowy tekst komentarza. W tym przykładzie podmienimy pierwszy i drugi na trzeci i czwarty. A poniżej kod, który robi to wszystko:
function glowna_moja_piata_wtyczka(){ echo "Strona główna wtyczki"; } add_filter( 'comment_text', 'm5w_comment_cenzure'); function m5w_comment_cenzure( $comment_text ){ $to_cenzure = array('pierwszy','drugi'); $replace_cenz = array('trzeci', 'czwarty'); $comment_text = str_replace($to_cenzure,$replace_cenz, $comment_text); return $comment_text; }
A poniżej wynik.
Podobnie jak w przypadku zaczepów akcji także i filtry mają więcej funkcji, które w zasadzie działają podobnie. Poniżej krótko charakteryzuję najważniejsze z nich.
apply_filters_ref_array( $tag, $args );
Ta funkcja działa tak samo jak apply_filters() z tym że zamiast wielu wartości pobiera ich tablicę. Analogicznie jak w przypadku do_action_ref_array().
remove_filter( $tag, $filter_to_remove, $priority, $accepted_args);
Ta funkcja działa analogicznie do remowe_action(). Kolejno pobiera nazwę zaczepu, nazwę funkcji do usunięcia, jej priorytet oraz akceptowane argumenty. Dzięki tej funkcji możemy usunąć przetwarzanie treści wyświetlanych na stronie możemy także podmieniać funkcje na swoje usuwając funkcje systemowe.
remove_all_filters( $tag, $priority );
Ta funkcja jest analogiczna do remove_all_actions(), działa tak samo tylko że na filtrach.
has_filter( $tag, $function_to_check)
Ta funkcja także jest analogiczna jak w przypadku akcji has_action()
. Używamy tych funkcji najczęściej kiedy chcemy usunąć jakąś funkcję. Szczególnie przydatna jest kiedy chcemy za pomocą naszej wtyczki zmodyfikować jakąś inną wtyczkę. Na przykład wtyczka woocommerce bardzo popularna i często używana często wymaga jakichś modyfikacji i dzięki wykorzystaniu zaczepów możemy zmodyfikować wiele rzeczy tak jak i w innych popularnych wtyczkach.
current_filter();
Czasami zdarza się że jedną funkcję zaczepiamy do kilku zaczepów. powyższa funkcja zwraca nazwę aktualnie wykonywanego zaczepu. Działa ona nie tylko w przypadku filtrów ale także w przypadku akcji.
Lista najczęściej wykorzystywanych zaczepów… (za jakiś czas)
Często może się zdarzyć że do budowy naszej wtyczki chcemy wykorzystać klasy i obiekty. Sposób dodawania akcji i filtrów w obiektach nieco się różni od dodawania po prostu funkcji, jednakże nie jest to trudne i w obu przypadkach wygląda podobnie.
Aby zaczepić funkcję akcji lub filtru w klasie zamiast przekazywanej nazwy funkcji tworzymy tablicę z dwoma argumentami. Pierwszy to referencja do bieżącego obiektu klasy &$this zaś drugi to nazwa funkcji tak jak zostało to przedstawione poniżej.
add_action( $tag, array( &$this, $function));
add_filter( $tag, array( &$this, $function));
Aby lepiej zobrazować działanie zaczepów we własnej klasie stworzymy sobie klasę, która w momencie utworzenia obiektu doda paragraf do tekstu wpisu oraz zmieni jego kolor.
class M5w_Class { function __construct() { add_filter( 'the_content' , array( &$this, 'add_p'), 0); } function add_p( $content ) { $content = '<p style="color:yellow;">' . $content; $content .= '</p>'; return $content; } } $m5w_object = new M5w_Class();
W powyższym kodzie najpierw tworzymy klasę, następnie tworzymy konstruktor w którym dołączamy naszą funkcję do zaczepu wyświetlającego treść wpisu. na koniec piszemy naszą funkcję, która pobiera treść wpisu a następnie dodaje do niego nasz paragraf i zwraca.
A poniżej efekt działania przed i po utworzeniu obiektu klasy $m5w_object.
Wtyczka, której wygląd oraz funkcjonalności można modyfikować bez wchodzenia w jej kod źródłowy jest znacznie bardziej elastyczna i profesjonalna. Aby zmodyfikować wtyczkę nie zawierającą własnych zaczepów trzeba by zmodyfikować jej kod a nie jest to najlepsze rozwiązanie ponieważ podczas jej aktualizacji pliki są nadpisywane. I tutaj jeśli udostępniamy wtyczkę warto dać możliwość innym programistom zmianę niektórych jej elementów.
Do tworzenia zaczepów mamy do dyspozycji cztery funkcje, po dwie dla akcji i dwie dla filtrów.
do_action( string $tag, $arg = '' )
Ta funkcja pobiera dwa parametry:
do_action_ref_array( $tag, $args )
Ta funkcja działa identycznie jak powyższa z tym że jako argumenty pobiera tablicę argumentów.
W przypadku filtrów nie mamy tutaj żadnych nowości więc tylko wymienię żeby nie było wątpliwości:
apply_filters( string $tag, mixed $value )
apply_filters_ref_array( string $tag, array $args )
Teraz aby lepiej zobrazować proces tworzenia własnych zaczepów stworzymy przykład w postaci własnego widgetu, który wyświetla własny tekst, pozwala na dodanie kolejnej linijki tekstu oraz na dodanie dowolnego filtru formatującego wyświetlany w widgecie tekst.
Na początek skopiujemy sobie widget z Drugiej części czyli cały kod poza komentarzem nagłówkowym określającym nazwę i inne dane wtyczki. Następnie zmienimy prefix funkcji na „m5w” oraz dane nazwy widgetu. W funkcji formularza usuniemy pola i zostawimy tylko własny napis informacyjny. Funkcję odpowiedzialną za aktualizację danych ograniczymy do zwrócenia starej instancji (ponieważ nie wprowadzamy tutaj żadnych własnych danych. Najbardziej interesuje nas w tym momencie funkcja widget().
Utworzymy teraz własny filtr, który nazwiemy „m5w_filter” i zaaplikujemy w miejscu, w którym ma się wyświetlać nasz tekst. Jako wartość przekazywaną do zaczepu wprowadzimy po prostu tekst. Zaraz pod wyświetlonym tekstem dodajemy zaczep akcji, który pozwala na wykonanie dowolnej akcji zaraz po wyświetleniu tekstu widgetu. Możemy tam umieścić cokolwiek, ale w tym przykładzie żeby efekt był bardziej widoczny po prostu wyświetlimy linijkę tekstu.
function widget( $args, $instance) { echo $args['before_widget']; echo apply_filters( 'm5w_filter' , 'przykładowy tekst'); do_action('m5w_action'); echo $args['after_widget']; }
Następnym krokiem będzie wykorzystanie zaczepów ale najpierw dodajmy nasz widget do panelu bocznego i sprawdźmy jaki da nam to efekt.
Jak widać na obrazku efekt nie różni się niczym od tego, który stworzyliśmy w drugiej części, jednakże tutaj mamy do dyspozycji zaczepy. i nie tylko my ale także inni programiści, którzy znają te zaczepy mogą wprowadzić modyfikacje z poziomu innej wtyczki lub szablonu.
Teraz nie pozostało nic innego jak przetestować te możliwości. My zrobimy to w tej samej wtyczce dodając filtr i akcje na końcu pliku z kodem naszej wtyczki. Na początek stworzymy filtr, który zmieni kolor obecnego tekstu oraz doda linijkę nowego.
add_filter( 'm5w_filter', 'm5w_change_widget_text'); function m5w_change_widget_text($text) { $text = '<p style="color:blue;">' . $text . '</p>'; $text .= '<p>Druga linijka</p>'; return $text; }
Po zastosowaniu powyższego kodu dotychczasowy kod powinien zmienić kolor na niebieski i pod nim powinna się pojawić linijka nowego tekstu, tak jak zostało to przedstawione na obrazku poniżej.
Pozostało nam już tylko przetestować nasz zaczep akcji. Tym razem także zrobimy najprościej jak to możliwe wyświetlając po prostu trzecią linijkę tekstu.
add_action( 'm5w_action', 'm5w_add_text'); function m5w_add_text(){ echo '<p> Trzecia linijka</p>'; }
Poniżej efekt testu.
To już koniec naszego przykładu. Jak zwykle poniżej umieszczam cały kod testowej wtyczki stworzonej w tym przykładzie, który można pobrać Tutaj
<?php /** Plugin Name: Moja piąta wtyczka Version: 1.0 Description: Piąta wtyczka przedstawiająca działanie i zastosowanie zaczepów akcji oraz filtrów Author: Daniel Kuczewski Author URI: http://zaawansowanywordpress.pl Plugin URI: http://zaawansowanywordpress.pl/5-zaczepy/ */ add_action( 'admin_menu', 'm5w_add_menu' ); add_action( 'wp_footer', 'm5w_add_footer', 99); remove_action( 'wp_footer', 'm5w_add_footer', 99); function m5w_add_menu(){ add_menu_page( 'Strona główna wtyczki', 'Moja piąta wtyczka', 'administrator', 'moja-piata-wtyczka', 'glowna_moja_piata_wtyczka', '', 7 ); } function m5w_add_footer() { echo '<br><p>Witryna wykorzystuje wtyczkę "Moja piąta wtyczka"</p>'; } function glowna_moja_piata_wtyczka(){ echo "Strona główna wtyczki"; } add_filter( 'comment_text', 'm5w_comment_cenzure'); function m5w_comment_cenzure( $comment_text ){ $to_cenzure = array('pierwszy','drugi'); $replace_cenz = array('trzeci', 'czwarty'); $comment_text = str_replace($to_cenzure,$replace_cenz, $comment_text); return $comment_text; } class M5w_Class { function __construct() { add_filter( 'the_content' , array( &$this, 'add_p'), 0); } function add_p( $content ) { $content = '<p style="color:yellow;">' . $content; $content .= '</p>'; return $content; } } $m5w_object = new M5w_Class(); add_action( 'widgets_init', 'm5w_register_widget' ); function m5w_register_widget() { register_widget( 'M5w_Widget'); } class M5w_Widget extends WP_Widget { function M5w_Widget() { // tablica opcji. $widget_ops = array( 'classname' => 'M5w_Widget', //nazwa klasy widgetu 'description' => 'Widget - zaczepy', //opis widoczny w panelu ); //ładowanie parent::__construct( 'M5w_Widget', 'Widget - zaczepy', $widget_ops ); } function form($instance) { ?> <p> Widget po prostu wyświetla przykładowy tekst. </p> <?php } function update($new_instance, $old_instance) { return $old_instance; } function widget( $args, $instance) { echo $args['before_widget']; echo apply_filters( 'm5w_filter' , 'Przykładowy tekst'); do_action( 'm5w_action'); echo $args['after_widget']; } } add_filter( 'm5w_filter', 'm5w_change_widget_text'); function m5w_change_widget_text($text) { $text = '<p style="color:blue;">' . $text . '</p>'; $text .= '<p>Druga linijka</p>'; return $text; } add_action( 'm5w_action', 'm5w_add_text'); function m5w_add_text(){ echo '<p> Trzecia linijka</p>'; }
Zaczepy są najważniejszym zagadnieniem do opanowania jeśli chodzi o budowę wtyczek. Opanowanie tej części jest bardzo ważne. Przez cały kurs przewijają się różne zaczepy. Jest oficjalna lista zaczepów jądra platformy WordPress na stronach codex.