Reklama sponsora

2. Widget



Wstęp

Własny Widget to jeden ze sposobów komunikacji z użytkownikiem. Czym jest widget? To pole, które możemy dodać w zarejestrowanym miejscu szablonu (w kursie własny szablon zobaczysz jak się rejestruje widgety w szablonie) na przykład w standardowym szablonie WordPressa „Twenty Sixteen”, który wykorzystamy w tej części kursu, Widgety  są wyświetlane po prawej stronie strony.

Co stworzymy?

Jest to kolejna część typu „Hello world” z tym że tym razem napis wyświetlimy użytkownikowi. Żeby było ciekawiej, napis będzie można wpisać w panelu administratora w momencie dodawania Widgetu do szablonu, tak więc stworzymy coś bardzo podobnego do standardowego Widgetu „Tekst” wyświetlającego dowolny tekst na stronie.

Zaczynamy

Analogicznie do poprzedniej wtyczki stworzymy sobie katalog i wewnątrz plik o takiej samej nazwie z tym że naszą wtyczkę nazwiemy moja_druga_wtyczka. Otwieramy plik moja_druga_wtyczka i wprowadzamy analogiczny do poprzedniego nagłówek.

/**
Plugin Name: Moja druga wtyczka
Version: 1.0
Description: Wtyczka tworząca Widget wyświetlający dowolny tekst na stronie.
Author: Daniel Kuczewski
Author URI: http://zaawansowanywordpress.pl
Plugin URI: http://zaawansowanywordpress.pl/2-widget/
 */

No i w zasadzie na tym analogia do pierwszej wtyczki się kończy.

Tworzenie widgetu

Do utworzenia wykorzystujemy klasę dziedziczącą po WP_Widget.

 


class Pierwszy_Widget extends WP_Widget {
    function __construct() {
        // Przetwarzanie widgetu.
    }
    function form($instance) {
        // Formularz w kokpicie administratora (tam gdzie przeciągamy widgety)
    }
    function update($new_instance, $old_instance) {
        // zapis opcji widgetu
    }
    function widget( $args, $instance) {
         // Wyświetlanie widgetu uzytkownikowi 
    }
}

Właśnie stworzyliśmy naszą klasę, którą zaraz wykorzystamy do stworzenia naszego widgetu. Są tam 4 funkcje.

  • __construct() – konstruktor, czyli funkcja wywoływana przy tworzeniu obiektu widgetu. Tutaj możemy na przykład przypisywać różne wartości do zmiennych, itd.
  • form( $instance ) – Funkcja odpowiedzialna za wyświetlanie formularza w panelu administratora (Kokpicie).
  • update( $new_instance, $old_instance) – Funkcja odpowiedzialna za aktualizację naszego widgetu po wysłaniu formularza w panelu administratora. Funkcja ta pobiera dwa parametry, pierwszy zawiera wartości wysłane w formularzu zaś drugi zawiera stare wartości.

Rejestrujemy widget

Teraz już przechodzimy do budowy naszego widgetu. Na początek musimy go zarejestrować wykorzystując w tym celu zaczep akcji. W tym przypadku wykorzystujemy zaczep widgets_init dzięki czemu nasz kod wykona się od razu po załadowaniu widgetów systemowych.

 


add_action( 'widgets_init', 'mdw_register_first_widget' );

W powyższej akcji zaczepiamy funkcję mdw_register_first_widget i to właśnie w niej powinna się odbyć rejestracja widgetu. Do tego celu służy funkcja register_widget( $klasa ) ,która jako parametr przyjmuje nazwę klasy naszego widgetu, czyli klasę, którą utworzyliśmy na początku o nazwie Pierwszy_Widget.

 


function mdw_register_first_widget() {
    register_widget( 'Pierwszy_Widget');
}

Jednocześnie możemy zarejestrować nieograniczoną ilość widgetów, należy jednak pamiętać aby nazwy każdej z klas widgetu były unikalne.

Konfiguracja klasy widgetu

Teraz nadszedł czas na konfigurację klasy naszego widgetu. Uzupełnimy tutaj funkcje klasy Pierwszy_Widget przedstawionej wyżej. Po koleii cztery funkcje. Na początek idzie klasa konstruktora __construct(). Odpowiedzialna za przetworzenie naszego widgetu. W tym miejscu tworzymy tablicę konfiguracji a następnie przekazujemy ją klasie WP_Widget.

 

function Pierwszy_Widget() {
    // tablica opcji.
    $widget_ops = array(
        'classname' => 'Pierwszy_widget', //nazwa klasy widgetu
        'description' => 'To mój pierwszy widget', //opis widoczny w panelu
    );
    //ładowanie 
    parent::__construct( 'Pierwszy_Widget', 'Pierwszy Widget', $widget_ops );
}

$widget_ops to tablica zawierająca konfiguracje widgetu:

  • classname – nazwa klasy dodana do elementu listy widgetów. Widgety są zazwyczaj wyświetlane w panelach bocznych w postaci nieuporządkowanej listy. Ponieważ każdy z widgetów jest elementem tej listy dodanie opcji classname będzie najlepszym sposobem na określenie klasy dla arkuszy stylów, dzięki czemu możemy nadać widgetowi w prosty sposób indywidualny wygląd.
  • description – to opis widgetu widoczny w panelu Wygląd/Widgety, powinien zawierać, krótką informacje o widgecie. Powyższy kod da efekt jak na obrazku poniżej.

Screenshot_2


Po zbudowaniu tablicy przekazujemy ją do konstruktora, jednak wcześniej przekazujemy jeszcze dwa inne parametry. Pierwszym z nich, w tym przypadku Pierwszy_Widget to identyfikator naszego widgetu zaś drugi to nazwa widoczna w panelu administratora przedstawiona na obrazku powyżej. Trzecim parametrem jest wcześniej utworzona tablica opcji.

Kolejną funkcją klasy WP_Widget, którą wykorzystamy jest form($instance) odpowiedzialna za wyświetlenie formularza widgetu w panelu administratora umożliwiającego zapis dowolnych konfiguracji.

 

function form($instance) {
    // Formularz w kokpicie administratora (tam gdzie przeciągamy widgety)
    $defaults = array('tekst' => 'Mój tekst');
    $instance = wp_parse_args( (array) $instance, $defaults);
    $tekst = $instance['tekst'];
    ?>
    <p>
        <label>Twój tekst</label>
        <input type="text" name="<?= $this->get_field_name('tekst');?>" value="<?= esc_attr($tekst);?>" />
    </p>
    <?php
}

Na początek tworzymy zmienną $defaults zawierającą domyślne wartości w postaci tablicy, czyli w tym przypadku domyślny tekst. Następnie zmienne są przekazywane do zmiennych egzemplarza, w tym miejscu jeśli widget już był wcześniej zapisany to są tutaj przypisywane wcześniejsze wartości zaś jeśli nie to są wczytywane domyślne.

Następnie mamy zwykły kod HTML wyświetlający formularz. Warto tutaj zwrócić uwagę na trzy rzeczy. Po pierwsze nie trzeba otwierać i zamykać formularza ani tworzyć przycisku zatwierdzającego, które domyślnie tworzy wordpress. Po drugie pobieramy nazwę pola wykorzystując funkcję klasy WP_Widget w następujący sposób $this->get_field_name(‚nazwa_pola’). Po trzecie do parametru value wczytujemy wartość atrybutu (tą domyślną lub wcześniejszą, jeśli była) wykorzystując esc_attr( $atrybut ). Możemy tutaj oczywiście wykorzystywać dowolne pola jak checkbox, select itd. Powyższy kod daje efekt jak na obrazku poniżej.

Screenshot_1


Aby powyższy formularz działał musimy uzupełnić klasę update($new_instance, $old_instance). Tym razem nie dzieje się zbyt wiele.

 

function update($new_instance, $old_instance) {
    // zapis opcji widgetu
    $instance = $old_instance;
    $instance['tekst'] = strip_tags( $new_instance['tekst']);
    return $instance;
}

Ta funkcja zajmuje się zapisem wszystkich danych widgetu dlatego też na samym początku pobieramy cały obiekt, jaki istniał do tej pory. Następnie zmieniamy interesujące nas pole, czyli w tym przypadku tekst (tutaj także usuwamy niepotrzebne znaczniki. Na koniec zwracamy zaktualizowany obiekt do zapisu

Na koniec pozostaje nam najważniejsza funkcja odpowiedzialna za wyświetlenie treści ostatecznemu odbiorcy. Do tego celu służy fukcja widget(), która jako parametry pobiera tablicę argumentów i instancje, których zapisem wcześniej się zajmowaliśmy.

 

function widget( $args, $instance) {
    // Wyświetlanie widgetu uzytkownikowi
    extract($args);
    echo $before_widget;
    if(!empty($instance['tekst'])) {
        echo '<p>' . $instance['tekst'] . '</p>';
    }
    echo $after_widget;

}

Na początku za pomocą funkcji extract() wyodrębniamy parametr $args, który zawiera zmienne $before_widget oraz $after_widget. Wartości tych zmiennych są zdefiniowane w szablonie lub też mogą zostać zdefiniowane w momencie rejestracji panelu z widgetem. Służą one opakowaniu widgetu np w znaczniki \<div\>. Następnie na wszelki wypadek sprawdzamy czy został wprowadzony jakikolwiek tekst i jeśli tak to go wyświetlamy. A na obrazku poniżej ostateczny efekt po umieszczeniu naszego widgetu w panelu bocznym.

Screenshot_3


A poniżej pełny kod naszej wtyczki.

 

<?php
/**
Plugin Name: Moja druga wtyczka
Version: 1.0
Description: Wtyczka tworząca Widget wyświetlający dowolny tekst na stronie.
Author: Daniel Kuczewski
Author URI: http://zaawansowanywordpress.pl
Plugin URI: http://zaawansowanywordpress.pl/2-widget/
 */

add_action( 'widgets_init', 'mdw_register_first_widget' );

function mdw_register_first_widget() {
    register_widget( 'Pierwszy_Widget');
}

class Pierwszy_Widget extends WP_Widget {
    function Pierwszy_Widget() {
        // tablica opcji.
        $widget_ops = array(
            'classname' => 'Pierwszy_widget', //nazwa klasy widgetu
            'description' => 'To mój pierwszy widget', //opis widoczny w panelu
        );
        //ładowanie
        parent::__construct( 'Pierwszy_Widget', 'Pierwszy Widget', $widget_ops );
    }
    function form($instance) {
        // Formularz w kokpicie administratora (tam gdzie przeciągamy widgety)
        $defaults = array('tekst' => 'Mój tekst');
        $instance = wp_parse_args( (array) $instance, $defaults);
        $tekst = $instance['tekst'];
        ?>
        <p>
            <label>Twój tekst</label>
            <input type="text" name="<?= $this->get_field_name('tekst');?>" value="<?= esc_attr($tekst);?>" />
        </p>
        <?php
    }
    function update($new_instance, $old_instance) {
        // zapis opcji widgetu
        $instance = $old_instance;
        $instance['tekst'] = strip_tags( $new_instance['tekst']);
        return $instance;
    }
    function widget( $args, $instance) {
        // Wyświetlanie widgetu uzytkownikowi
        extract($args);
        echo $before_widget;
        if(!empty($instance['tekst'])) {
            echo '<p>' . $instance['tekst'] . '</p>';
        }
        echo $after_widget;

    }
}

Dodatkowo działający kod wtyczki można pobrać moja_druga_wtyczka

 

 

Dodany przez Paweł
2016-11-17 19:50:27

Dzięki bardzo, do tego folderu też dotarłem, tak więc biorę się do pisania ;) Natomiast wtyczka jak widzę idealna, ale zawsze staram się je ograniczać do minimum także to zostawię jako plan B, wolę te widgety powiązać bezpośrednio z motywem ;)

Dodany przez daniel820
2016-11-16 23:54:45

Teraz myślę że wszystko rozumiem :) Ciekawa kwestia kiedyś nawet miałem podobne zadanie ale wówczas wolałem napisać własny widget (zresztą była mi potrzebna jakaś dodatkowa opcja). Tak przeglądam kod wp i wygląda na to że nie ma takiego systemu. W wp-includes jest katalog widgets, w którym są zawarte wszystkie klasy widgetów. Możesz prześledzić kod każdego z nich (wówczas można się dowiedzieć wielu ciekawych rzeczy :)). Kod klasy po której dziedziczą wszystkie wigety znajduje się w includes > class-wp-widget.php. Myślę że najprościej byłoby dziedziczyć po interesujących widgetach i nadpisywać niepasujące funkcje, czyli konstruktor i widget(). Choć mogę się mylić i pewnie zweryfikuję w weekend. Z drugiej strony o ile nie ma takiego systemu w wp to nie znaczy że nie ma takich wtyczek. Ta wygląda na odpowiednią https://pl.wordpress.org/plugins/custom-post-type-widgets/

Dodany przez Paweł
2016-11-16 11:33:10

Cześć, dzięki za wyczerpującą odpowiedź, ale źle mnie zrozumiałeś ;) Chodzi mi o to że w motywie mamy dostępne domyślnie widgety takie jak np, lista kategorii, ostatnie wpisy, czy najnowsze komentarze, ale to wszystko dotyczy podstawowego typu wpisów, stron i taksonomii który mamy w podstawowej instalacji, a mi zależy na tym by dodając nowy typ postu oraz własne taksonomie otrzymać te same podstawowe widgety ale do mojego typu postu/mojej taksonomi ;) O ile orientuje się jak mogę je sam napisać, to jednak chcę się upewnić czy Wordpress nie ma jakiegoś wbudowanego mechanizmu co by sam generował te podstawowe widgety dla nowo dodanych typów postu czy taksonomii. Mam nadzieję że tym razem się zrozumiemy ;)

Dodany przez daniel820
2016-11-15 08:02:53

Nie jestem pewien czy dobrze zrozumiałem pytanie, ale chyba chodzi o modyfikację szablonu. W miejscu gdzie ma się wyświetlać widget dla danego typu postu sprawdzasz czy jest to ten post o który chodzi i jeśli tak to dodajesz w tym miejscu sidebar (wcześniej trzeba go zdefiniować np w functions). Kiedyś robiłem coś takiego:



if(isset($post->post_type) && $post->post_type == 'TWOJ_TYP') {
        if (is_active_sidebar('TWOJ SIDEBAR')) : 
              dynamic_sidebar('TWOJ SIDEBAR');
        endif;
}

Dodany przez Paweł
2016-11-15 01:08:52

Cześć Przy okazji tematu widżetu poruszanego na twoim blogu, chciałbym się zapytać czy wiesz może jak mogę najprościej dodać domyślne widżety wordpress do danego custom post type, chodzi tutaj np. o listę własnej taksonomi tak jak mamy domyślny widżet kategorii itp.?


Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *