Wykorzystanie menadżera mediów we własnych wtyczkach

Dzięki wykorzystaniu menadżera mediów we własnych wtyczkach możemy znacząco ułatwić życie użytkownikowi – nie musi on z pamięci wprowadzać adresów do wybranych grafik. W tym wpisie chciałbym pokazać jak łatwo dodać obsługę menadżera mediów do własnej wtyczki/motywu.

Uproszczony schemat działania jakie chcemy osiągnąć prezentuje się następująco:

    1. Dodajemy do określonych przycisków akcję otwierania menadżera mediów po ich kliknięciu
    2. Definiujemy właściwości okna menadżera mediów wykorzystywanego przez nasz skrypt
    3. Dodajemy obsługę operacji wyboru obrazka
    4. Dodajemy obsługę operacji zamknięcia menadżera

Jak widać sama idea nie wygląda zbyt skomplikowanie – na szczęście większość operacji wykonywania jest po stronie skryptów menadżera mediów – musimy obsłużyć tylko kluczowe operacje takie jak wybór zdjęcia i zakończenie korzystania z menadżera.

Zacznijmy od szkieletu naszego kodu:

var dziudek_media_init = function(selector, button_selector)  {
    var clicked_button = false;

    jQuery(selector).each(function (i, input) {
        var button = jQuery(input).next(button_selector);
        button.click(function (event) {
            event.preventDefault();
            var selected_img;
            clicked_button = jQuery(this);

            // sprawdzenie czy dana instancja menadżera mediów już istnieje

            // konfiguracja instancji menadżera mediów

            // obsługa zamknięcia menadżera mediów

            // obsługa operacji wyboru zdjęcia

            // otworzenie okna
       });
   });
};

Powyższa funkcja pobiera dwa argumenty – selektor pól, które będą pobierały dane z menadżera mediów oraz selektor przycisków, które znajdą się obok tych pól a po ich kliknięciu pojawi się menadżer mediów.

Po każdym kliknięciu ustawiamy dwie zmienne – uchwyt do klikniętego przycisku (clicked_button) i uchwyt do wybranego obrazka (selected_img). Zmienna clicked_button jest nam potrzebna gdyż będziemy implementowali wykorzystanie tylko jednej instancji menadżera mediów, a co za tym idzie będziemy musieli zmieniać uchwyt do klikniętego przycisku tak by raz zdefiniowane funkcje zawsze odwoływały się do poprawnego przycisku.

Sprawdzanie istnienia instancji menadżera mediów wygląda następująco:

if(wp.media.frames.dziudek_frame) {
    wp.media.frames.dziudek_frame.open();
    return;
}

Testujemy czy istnieje obiekt dziudek_frame (nazwa naszej instancji) w obiekcie wp.media.frames. Jeżeli istnieje to od razu otwieramy okno menadżera mediów korzystając z metody open. Można powiedzieć, że to wykorzystanie wzorca Singletonu gdyż korzystamy z raz utworzonej instancji menadżera mediów zamiast tworzyć za każdym razem nową instancję.

Gdy instancja menadżera mediów nie istnieje, musimy ją stworzyć:

wp.media.frames.dziudek_frame = wp.media({
   title: 'Wybierz grafikę',
   multiple: false,
   library: {
      type: 'image'
   },
   button: {
      text: 'Użyj tej grafiki'
   }
});

Warto pamiętać o dodaniu wsparcia dla tłumaczeń do użytych w powyższym kodzie ciągów znaków z użyciem funkcji wp_localize_script.

Jak widać wywołujemy konstruktor wp.media z obiektem zawierającym konfigurację nowej instancji menadżera mediów w której określamy tytuł okna (title), możliwość wyboru wielu grafik naraz (multiple), określamy zakres wykorzystywanych mediów (obiekt library – w tym wypadku ograniczamy się tylko do grafik) oraz definiujemy nazwę przycisku wysyłania formularza wyboru (obiekt button).

Pora na określenie zachowania się naszego kodu w sytuacji wyboru obrazka lub zamknięcia menadżera mediów – zaczynamy od stworzenia funkcji, którą wykorzystamy przy tych zdarzeniach:

var dziudek_media_set_image = function() {
    var selection = wp.media.frames.dziudek_frame.state().get('selection');

    if (!selection) {
        return;
    }

    // iterujemy po wybranych elementach
    selection.each(function(attachment) {
        var url = attachment.attributes.url;
        clicked_button.prev(selector).val(url);
    });
};

Powyższa funkcja spowoduje wykonanie trzech kluczowych operacji:

  1. Przechwyci zaznaczony element lub elementy
  2. Pobierze z zaznaczonych elementów adres URL do wstawienia
  3. Wstawi tekst do pola tekstowego obok klikniętego przycisku

Wywołujemy tą funkcję przy zamykaniu menadżera mediów (ten fragment jest opcjonalny – w tym wypadku spowoduje on, że jeżeli użytkownik wybierze jakiś obrazek to niezależnie od sposobu zamknięcia okna menadżera mediów jego URL zostanie ustawiony jako zawartość pola tekstowego obok przycisku):

wp.media.frames.dziudek_frame.on('close', dziudek_media_set_image);

oraz przy wybieraniu obrazka (kliknięcie przycisku Użyj tej grafiki):

wp.media.frames.dziudek_frame.on('select', dziudek_media_set_image);

Na koniec musimy już tylko otworzyć okno menadżera mediów:

wp.media.frames.dziudek_frame.open();

Cały kod obsługi menadżera mediów prezentuje się następująco:

var dziudek_media_init = function(selector, button_selector)  {
    var clicked_button = false;

    jQuery(selector).each(function (i, input) {
        var button = jQuery(input).next(button_selector);
        button.click(function (event) {
            event.preventDefault();
            var selected_img;
            clicked_button = jQuery(this);

            // sprawdzenie czy dana instancja menadżera mediów już istnieje
            if(wp.media.frames.dziudek_frame) {
                wp.media.frames.dziudek_frame.open();
                return;
            }
            // konfiguracja instancji menadżera mediów
            wp.media.frames.dziudek_frame = wp.media({
                title: 'Wybierz grafikę',
                multiple: false,
                library: {
                    type: 'image'
                },
                button: {
                    text: 'Użyj tej grafiki'
                }
            });
            
            // funkcja używana przy wyborze obrazka i przy zamknięciu menadżera mediów
            var dziudek_media_set_image = function() {
                var selection = wp.media.frames.dziudek_frame.state().get('selection');
                
                // brak wybranych elementów
                if (!selection) {
                    return;
                }

                // iterujemy po wybranych elementach
                selection.each(function(attachment) {
                    var url = attachment.attributes.url;
                    clicked_button.prev(selector).val(url);
                });
            };

            // obsługa zamknięcia menadżera mediów
            wp.media.frames.dziudek_frame.on('close', dziudek_media_set_image);
            // obsługa operacji wyboru zdjęcia
            wp.media.frames.dziudek_frame.on('select', dziudek_media_set_image);
            // otworzenie okna
            wp.media.frames.dziudek_frame.open();
        });
   });
};

Aby wykorzystać ten kod musimy sobie stworzyć odpowiednią strukturę np.:

<input type="text" class="media-input" /><button class="media-button">Wybierz grafikę</button>

Oraz wywołać funkcję dziudek_media_init w następujący sposób:

dziudek_media_init('.media-input', '.media-button');

Stworzyliśmy w ten sposób podstawową implementację obsługi menadżera mediów do wykorzystania we wtyczkach i motywach na bazie selektorów pól i przycisków. W najbliższym czasie postaram się rozwinąć ten temat o więcej szczegółów konfiguracyjnych menadżera mediów.