Ця публікація для вас, хто створює власний блок Гутенберга і потребує способу вибору або завантаження зображення з медіа-бібліотеки. Більшість інших типів полів, як-от прапорці, введення тексту чи засоби вибору кольорів, досить легко додати, але завантажувач медіафайлів потребує трохи більше коду. Ми створимо компонент Inspector, який відповідатиме за рендеринг кнопки для відкриття бібліотеки медіафайлів, вибору зображення та, за бажанням, видалення чи зміни його пізніше. Усі вони використовують стандартні компоненти WordPress.
Перш ніж ми заглибимося в код, майте на увазі, що ця публікація вимагає певних знань Гутенберга про те, як писати власні блоки. Ми зосередимося лише на частині медіа-завантаження, а не на тому, як зареєструвати та створити блок Gutenberg сам по собі. Якщо ви не впевнені, як написати власний блок Гутенберга, у мене є серія навчальних посібників, яка стосується саме цього:
Покінчивши з цим, давайте зануримося прямо!
Що ми зробимо
Функція вибору медіа функціонально буде точно такою ж, як функція представлених зображень WordPress. Ми додамо в Inspector панель, яка складається з кнопки для вибору зображення.
Після натискання кнопки з’явиться спливаюче вікно «Вибрати або завантажити медіа», у якому ви зможете вибрати файл із медіа-бібліотеки. Ми обмежуємо медіа-бібліотеку показом лише зображень. Після вибору зображення спливаюче вікно закривається, а на панелі відтворюється попередній перегляд невеликий мініатюра вибраного зображення. Нижче з’являться кнопки попереднього перегляду для зміни та видалення зображення. Точно так само, як і з представленим зображенням.
У цьому посібнику передбачається, що ви будете використовувати вибране зображення як фон блоку – лише як приклад. Ось чому ми зберігаємо URL-адресу зображення. Я додам приклад того, як використовувати вибране зображення (як у функції, так edit
і у save
функції). Під час вибору зображення зображення буде відображатися як фон нашого блоку, як у редакторі, так і в інтерфейсі.
Ми зберігаємо медіа-ідентифікатор і медіа-адресу в атрибутах блоку. Код використовує withSelect
, компонент вищого порядку, який надається в wp.data
пакеті, щоб запитувати більше інформації про вибраний медіа за ідентифікатором.
Я також «позичаю» назви класів із представленої функціональності зображень WordPress, щоб переконатися, що все виглядає добре та немає потреби самостійно писати CSS. Це, звичайно, необов’язково.
Збереження вибраного носія в атрибутах
Що вам потрібно зберегти в атрибутах вашого блоку, залежить від вас. Як мінімум нам потрібно зберігати медіа ідентифікатор, очевидно. Цього може бути достатньо, якщо вам не потрібно використовувати URL-адресу медіа в коді сценарію. Наприклад, якщо ви використовуєте ServerSideRender
де PHP відповідає за рендеринг виводу блоку. У такому випадку ви можете легко отримати URL-адресу зображення з ідентифікатора носія, використовуючи, наприклад [wp_get_attachment_image_src](https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src/)()
. Однак у наведеному нижче прикладі я показую простий приклад відображення зображення як фону для нашого блоку, тому я також зберігаю URL-адресу медіа як атрибут. Ми будемо використовувати атрибут URL як у edit
(щоб додати фон у редакторі), так і в save
(щоб додати фон у інтерфейс).
Почнемо з визначення наших атрибутів. Ідентифікатор носія має бути номером типу та значенням за замовчуванням 0. Це полегшує порівняння. URL-адреса медіа має бути рядком типу з порожнім рядком за замовчуванням.
attributes: {
mediaId: {
type: 'number',
default: 0
},
mediaUrl: {
type: 'string',
default: ''
}
},
Створення компонента
Щоб зробити наш код більш упорядкованим, ми визначаємо окремий компонент для функції блоку edit
. Пізніше ми передамо цей компонент withSelect
, щоб обернути його навколо нашого компонента.
У поверненні компонента ми візуалізуємо простий <div>
вміст блоку. Я припускаю, що ви заблокуєте або матимете більше реального вмісту, щоб замінити фіктивний приклад вмісту. Ми також візуалізуємо InspectorControls
(package wp.blockEditor
), щоб додати розділ до інспектора. Наразі я додаю порожній елемент PanelBody
у InspectorControls
. Я додаю <div>
з тим самим класом, який використовує розділ пропонованих зображень WordPress. Це гарантує, що наш стиль виглядає добре. Пізніше ми заповнимо це PanelBody
кодом для функції вибору медіа.
Але спочатку давайте деструктуруємо необхідний компонент на початку файлу:
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
const { Fragment } = wp.element;
Над registerBlockType
I визначає простий компонент під назвою BlockEdit
. Якщо ви бажаєте перемістити це в окремий файл, можете це зробити. Це поширене й рекомендоване, але для цього підручника я зберігаю речі простими та зберігаю це в одному файлі.
Тепер ми хочемо відобразити цей компонент у нашій edit
функції. Але ми хочемо загорнути його в withSelect
.
Використання withSelect
у edit
функції
Якщо ви не знайомі з withSelect
, це корисний компонент вищого порядку, який дозволяє нам виконувати запити. Ви можете, наприклад, запитувати повідомлення за допомогою цього. Однак ми будемо використовувати функцію select('core').getMedia()
для запиту медіа-ідентифікатора. У відповідь ми отримаємо об’єкт з усією інформацією ЗМІ. Медіа-об’єкт, який ми отримуємо у відповідь, буде надано як проп у нашому BlockEdit
компоненті, готовий до використання. Чудово.
Ми обов’язково надсилаємо запит до медіафайлу, лише якщо атрибут ID медіа дійсно має значення, відмінне від 0. Ось як виглядатиме наша функція редагування:
У самому кінці, після закриття withSelect
рядка #3
, ми просимо withSelect
повернути наш BlockEdit
компонент. Завдяки цьому наш BlockEdit
компонент тепер має доступ до props.media
.
Візуалізація вибору медіа
Нарешті настає найцікавіше: частина в «Інспекторі».
Компонент, який нас цікавить, це MediaUpload
(package wp.blockEditor
). Якщо ви зацікавлені, у репозиторії WordPress Github для Gutenberg є деяка документація щодо цього компонента. Ми також загорнемо цей компонент у компонент під назвою MediaUploadCheck
(package wp.blockEditor
). Цей компонент гарантує, що поточний користувач має можливості використовувати бібліотеку мультимедійних файлів, тому це доцільно використовувати.
Компонент MediaUpload
має необхідний проп: render
. Принцип роботи цього компонента полягає в тому, що ми визначаємо функцію для render
пропу, де ми візуалізуємо вихідні дані для «області завантаження медіа». У нашому випадку ми візуалізуємо Button
(package wp.components
). Усередині рендеринга MediaUpload ми отримуємо доступ до open
функції, яку ми можемо викликати, щоб змусити WordPress відкрити спливаюче вікно медіабібліотеки:
Є ще кілька реквізитів для MediaUpload
. У цьому підручнику ми розглянемо важливі, щоб зробити його функціональним, але є ще кілька, з якими ви можете пограти. Вас може принаймні зацікавити проп, allowedTypes
де ви можете обмежити типи файлів, які можна вибрати в бібліотеці. У нашому випадку ми встановили, що дозволено лише зображення.
ДодаванняMediaUpload
Спочатку деструктуруйте нові компоненти;
const { Button } = wp.components;
const { MediaUpload, MediaUploadCheck } = wp.blockEditor;
Давайте додамо MediaUploadCheck
і MediaUpload
всередині нашого div
в нашому PanelBody
:
Наведений вище код деструктурує open
всередині функції для render
. Ми візуалізуємо простий, Button
де його onClick
властивість запускатиме open
функцію. Я також додав ті самі назви класів, що й функціональні можливості представлених зображень WordPress, щоб гарантувати, що нам не потрібно додавати будь-які стилі.
Усередині Button
компонента ми перевіряємо, чи встановлено зображення (attributes.mediaId
). Якщо ні, ми повторюємо текст «Виберіть зображення». Тепер ми повинні отримати це в нашому блоці.
Коли ви натискаєте кнопку, має з’явитися спливаюче вікно медіатеки. Однак наразі вибір зображення не працює, оскільки нам бракує реквізитів onSelect
і. Давайте виправимо це зараз. Ми встановлюємо вибраний медіа-ідентифікатор і запускаємо функцію, яку пізніше визначимо в нашому компоненті.value``MediaUpload``value``onSelect
Давайте визначимо onSelectMedia
функцію в нашому компоненті.
Обробка вибору носія
Примітка: я визначаю свої функції як функції зі стрілками (onSelectMedia =() => { }
). Функції стрілок є досить новими в ESNext і досить чудовими. Недоліком є те, що для використання функцій зі стрілками потрібно додати підтримку для цього у вашій конфігурації Babel. Якщо ви цього не робили, я рекомендую переглянути під заголовком «Налаштування Babel» у цій публікації.
Безпосередньо перед оператором повернення компонента я визначаю onSelectMedia
функцію. Все, що нам потрібно, це оновити наші атрибути за допомогою setAttributes()
. Як параметр onSelectMedia
ми отримуємо медіа-об’єкт. Ми просто витягуємо те, що нам потрібно, з медіа-об’єкта. У нашому випадку це медіа-ідентифікатор і повнорозмірна URL-адреса, які є властивостями id
і url
відповідно.
Спробуйте зараз, і тепер ви зможете вибрати зображення з медіатеки. Вибрані носії зберігаються в атрибутах блоку. Однак в інспекторі ще немає його попереднього перегляду, і оскільки ви вибрали зображення, кнопка для вибору зображення зникне. Тепер панель порожня. Наступним кроком є рендеринг попереднього перегляду кожного разу, коли зображення вибрано, а також надання опцій для його видалення чи зміни.
Відтворення попереднього перегляду зображення
Усередині Button
компонента, який ми візуалізуємо, всередині MediaUpload
пропу render
ми повторюємо текст «Виберіть зображення», якщо зображення ще не встановлено. Але нам потрібно додати якийсь код для того, щоб тут було встановлено зображення; попередній перегляд.
Щоб допомогти нам зробити гарний попередній перегляд, ми використовуємо компонент ResponsiveWrapper
(package wp.components
). Щоб ResponsiveWrapper
повністю функціонувати, нам потрібно забезпечити опори для висоти та ширини. Нам також потрібна URL-адреса ескізу. Немає сенсу використовувати повну URL-адресу (яка може бути гігантською) для візуалізації попереднього перегляду в Inspector. Ось тут і з’являється проп withSelect
. Всередині компонента ми відтворюємо простий <img>
тег HTML.
Спочатку ми деструктуруємо необхідний компонент:
const { ResponsiveWrapper } = wp.components;
Як бачите, ми отримуємо доступ до withSelect
наданого нам компонента, props.media
. Ми отримуємо ширину, висоту та URL-адресу розміру ескізу медіа з об’єкта.
Тепер ви маєте отримати гарний попередній перегляд вибраного зображення!
Оскільки ми візуалізуємо зображення попереднього перегляду всередині, Button
клацання зображення попереднього перегляду активує Button
функцію onClick
, яка полягає у відкритті медіатеки. Таким чином ви вже можете змінити вибране зображення.
Наразі неможливо видалити або скинути вибране зображення. Давайте виправимо це!
Додавання функції видалення
Ми повинні принаймні надати користувачеві можливість видалити вибране зображення. Наразі після вибору зображення ви можете лише змінити його, але не видалити.
Ми зробимо це так само, як WordPress для представленого зображення: нове Button
під зображенням попереднього перегляду (повністю за його межами MediaUploadCheck
). Надавши деякі розумні атрибути для цього, Button
ми робимо його схожим на посилання (isLink
) із червоним кольором тексту (isDestructive
). Прочитайте документацію для Button, щоб побачити, що ще можливо. Ми загортаємо кнопку в іншу кнопку MediaUploadCheck
, щоб гарантувати, що користувач має потрібні можливості.
Для цієї події ми запускаємо нову функцію всередині нашого компонента: Button
. Ми визначаємо його десь безпосередньо перед функцією повернення компонента, як ми зробили з .onClick``removeMedia()``onSelectMedia
Усе, що ця функція робить, це скидання наших двох значень атрибутів.
Тепер у нас буде гарне, чітке посилання для видалення зображення:
При натисканні на нову кнопку вибране зображення та сама кнопка зникають, а кнопка вибору зображення з’являється знову.
Додавання кнопки заміни
Цей крок є абсолютно необов’язковим. Як згадувалося раніше, клацання зображення попереднього перегляду зображення відкриє бібліотеку медіафайлів і дозволить вам змінити зображення. Однак це може бути не настільки інтуїтивно зрозумілим для всіх. WordPress додає окрему кнопку для зміни зображення, щоб було дуже зрозуміло. Ми можемо зробити те саме.
Щоб відобразити кнопку зміни зображення, ми в основному повторюємо код, який маємо для вибору зображення: інший MediaUpload
компонент. Ми надаємо ту саму функцію для onSelect
, як allowedFileTypes
і value
раніше. Всередині render
опори для MediaUpload
ми просто візуалізуємо іншу Button
, яка відкриває Медіатеку. Давайте розташуємо цю кнопку перед кнопкою «Видалити», оскільки це має більше сенсу для кінцевого користувача:
Отже, тепер ви повинні отримати це:
Використання вибраного зображення
Тепер має бути досить зрозуміло, як ви можете використовувати вибране зображення. Ви маєте ідентифікатор медіафайлу та URL-адресу медіафайлу, які зберігаються в атрибутах вашого блоку. Проте як простий приклад я додам код, який встановлює вибране зображення як фон блоку. Код можна зробити абсолютно однаковим у функціях edit
і save
. Ми просто створюємо об’єкт стилю, який застосовуємо до div обгортки блоку. В об’єкті стилю ми встановлюємо фонове зображення для URL-адреси медіа.
З рештою вмісту вашого спеціального блоку це легко може виглядати приблизно так:
Якщо застосувати стиль блоку в обох edit
і save
, тепер ваш блок має отримати вибрані медіа як фон. Як у редакторі, так і в інтерфейсі.
Висновок
Вибір зображення (або файлу) із медіатеки — це функція, яка вам, як розробнику Gutenberg, без сумніву, знадобиться для ваших блоків. Ми навчилися додавати функцію для вибору зображення з медіа-бібліотеки в наш спеціальний блок Гутенберга. Ми зробили це так само, як сам WordPress робить це для представленого зображення. (Редагувати травень 2020: WordPress тепер оновив пропоноване зображення для використання useSelect
, а не хук React). Це гарантує, що наш код не є «хакерським» із високим ризиком зламу під час майбутніх оновлень.
Дайте мені знати, якщо ви користувалися цим!
Повний код
Нижче наведено повний код для спеціального блоку, який містить функцію вибору медіа. І більше нічого насправді. Ця частина залежить від вас!