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:
- Dodajemy do określonych przycisków akcję otwierania menadżera mediów po ich kliknięciu
- Definiujemy właściwości okna menadżera mediów wykorzystywanego przez nasz skrypt
- Dodajemy obsługę operacji wyboru obrazka
- 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:
- Przechwyci zaznaczony element lub elementy
- Pobierze z zaznaczonych elementów adres URL do wstawienia
- 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.