Этот пост предназначен для тех, кто создает собственный блок Гутенберга и нуждается в способе выбора или загрузки изображения из медиатеки. Большинство других типов полей, таких как флажки, ввод текста или палитры цветов, довольно легко добавить, но загрузчик мультимедиа требует немного больше кода. Мы создадим компонент Inspector, отвечающий за отрисовку кнопки для открытия медиатеки, выбора изображения и, при необходимости, его удаления или изменения позднее. Все с использованием стандартных компонентов WordPress.
Прежде чем мы углубимся в код, имейте в виду, что этот пост требует некоторых знаний Гутенберга о том, как писать пользовательские блоки. Мы сосредоточимся только на части загрузчика мультимедиа, а не на том, как зарегистрироваться и создать блок Гутенберга сам по себе. Если вы не знаете, как написать собственный блок Гутенберга, у меня есть серия руководств, посвященных именно этому:
С этим по пути, давайте погрузимся прямо в!
Что мы будем делать
Функция выбора медиа будет функционально такой же, как и функция избранного изображения в WordPress. Мы добавим в Инспектор панель, состоящую из кнопки для выбора изображения.
При нажатии на кнопку появляется всплывающее окно «Выбрать или загрузить медиа», позволяющее выбрать файл из медиатеки. Мы ограничиваем медиатеку показом только изображений. После выбора изображения всплывающее окно закрывается, и на панели отображается предварительный просмотр маленькая миниатюра выбранного изображения. Ниже появятся кнопки предварительного просмотра для изменения и удаления изображения. Точно так же, как с избранным изображением.
В этом руководстве предполагается, что вы будете использовать выбранное изображение в качестве фона блока — просто в качестве примера. Вот почему мы сохраняем URL-адрес изображения. Я включу пример того, как использовать выбранное изображение (как в функции, так edit
и в save
ней). При выборе изображения изображение будет отображаться в качестве фона для нашего блока, как внутри редактора, так и во внешнем интерфейсе.
Мы храним идентификатор мультимедиа и URL-адрес мультимедиа в атрибутах блока. В коде используется 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
as, чтобы обернуть его вокруг нашего компонента.
В возврате компонента мы визуализируем простое <div>
содержимое блока. Я предполагаю, что у вас будет или будет более реальный блок контента, чтобы заменить фиктивный пример контента. Мы также рендерим InspectorControls
(package wp.blockEditor
), чтобы добавить раздел в инспектор. А пока я добавляю пустой PanelBody
внутри InspectorControls
. Я добавляю <div>
класс с тем же классом, который используется в разделе рекомендуемых изображений WordPress. Это гарантирует, что наш стиль выглядит хорошо. Позже мы заполним PanelBody
его кодом для функций выбора мультимедиа.
Но сначала деструктурируем нужный компонент в начале файла:
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
const { Fragment } = wp.element;
Выше registerBlockType
я определяю простой компонент с именем BlockEdit
. Если вы предпочитаете переместить это в отдельный файл, вы можете это сделать. Это распространено и рекомендуется, но для этого урока я делаю все просто и храню его в том же файле.
Теперь мы хотим отобразить этот компонент в нашей edit
функции. Но мы хотим обернуть его в файл withSelect
.
Использование withSelect
в edit
функции
Если вы не знакомы с withSelect
, это полезный компонент высшего порядка, который позволяет нам выполнять запросы. Вы можете, например, запрашивать сообщения с помощью this. Однако мы будем использовать эту функцию select('core').getMedia()
для запроса идентификатора носителя. В ответ мы получим объект со всей информацией о носителе. Медиа-объект, который мы получаем в ответ, затем будет предоставлен в качестве реквизита в нашем BlockEdit
компоненте, готовом к использованию. Изящный.
Мы обязательно запрашиваем носитель только в том случае, если для атрибута идентификатора носителя действительно установлено значение, отличное от 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-адрес (который может быть огромным) для предварительного просмотра в Инспекторе. Вот тут-то и появляется реквизит withSelect
. Внутри компонента мы визуализируем простой <img>
HTML-тег.
Сначала деструктурируем нужный компонент:
const { ResponsiveWrapper } = wp.components;
Как видите, мы получаем доступ к свойству, withSelect
предоставленному нам компонентом, props.media
. Мы извлекаем ширину, высоту и URL-адрес размера миниатюры мультимедиа из объекта.
Теперь вы должны получить хороший предварительный просмотр выбранного изображения!
Поскольку мы отображаем изображение для предварительного просмотра внутри, Button
щелчок по изображению для предварительного просмотра вызовет функцию Button
, onClick
которая должна открыть медиатеку. Таким образом, вы уже можете изменить выбранное изображение.
В настоящее время нет способа удалить или сбросить выбранное изображение. Давайте исправим это!
Добавление функции удаления
Мы должны как минимум предоставить пользователю возможность удалить выбранное изображение. На данный момент, как только вы выбрали изображение, вы можете только изменить его, но не удалить.
Мы сделаем это так же, как WordPress делает для избранного изображения: новое Button
под изображением предварительного просмотра (полностью вне его MediaUploadCheck
). Предоставив несколько умных реквизитов, Button
мы делаем его похожим на ссылку (isLink
) с красным цветом текста (isDestructive
). Прочтите документацию по кнопке, чтобы узнать, что еще возможно. Мы помещаем кнопку внутрь еще одного MediaUploadCheck
, просто чтобы убедиться, что у пользователя есть нужные возможности.
Для этого события Button
мы onClick
запускаем новую функцию внутри нашего компонента: removeMedia()
. Мы определяем его где-то прямо перед функцией возврата компонента, как мы это делали с onSelectMedia
.
Все, что делает эта функция, — это сбрасывает два значения наших атрибутов.
Теперь у нас будет красивая четкая ссылка для удаления изображения:
При нажатии на новую кнопку выбранное изображение и сама кнопка исчезают, а кнопка выбора изображения появляется снова.
Добавление кнопки замены
Этот шаг является полностью необязательным. Как упоминалось ранее, щелчок по изображению для предварительного просмотра откроет медиатеку и позволит вам изменить изображение. Однако это может быть не так интуитивно понятно для всех. WordPress добавляет отдельную кнопку для смены изображения, просто чтобы было понятно. Мы можем сделать то же самое.
Чтобы отобразить кнопку изменения изображения, мы в основном повторяем код, который у нас есть для выбора изображения: другой MediaUpload
компонент. Мы предоставляем ту же функцию для и onSelect
, что allowedFileTypes
и value
раньше. Внутри render
реквизита for MediaUpload
мы просто визуализируем другой Button
, открывающий медиатеку. Давайте поместим эту кнопку перед кнопкой «Удалить», так как это имеет больше смысла для конечного пользователя:
Итак, теперь вы должны получить это:
Использование выбранного изображения
К настоящему времени должно быть довольно ясно, как вы можете использовать выбранное изображение. У вас есть идентификатор мультимедиа и URL-адрес мультимедиа, хранящиеся в атрибутах вашего блока. Однако в качестве простого примера я включу код, который устанавливает выбранное изображение в качестве фона блока. Код можно сделать одинаковым как в функциях, так edit
и в save
функциях. Мы просто создаем объект стиля, который применяем к обертке блока div. В объекте стиля мы устанавливаем фоновое изображение для URL-адреса мультимедиа.
С остальным содержимым пользовательского блока это может легко выглядеть примерно так:
Если вы примените стиль блока в обоих edit
и save
, ваш блок теперь должен получить выбранный носитель в качестве фона. Как внутри редактора, так и во фронтенде.
Вывод
Выбор изображения (или файла) из медиатеки — это функция, которая вам, как разработчику Gutenberg, без сомнения понадобится для ваших блоков. Мы узнали, как добавить функцию выбора изображения из медиатеки в наш пользовательский блок Гутенберга. Мы сделали это так же, как сам WordPress делает это для избранного изображения. (Редактировать май 2020: WordPress теперь обновил избранное изображение, чтобы useSelect
вместо этого использовать хук React). Это гарантирует, что наш код не является «хакерским» с высоким риском взлома в будущих обновлениях.
Дайте мне знать, если вы использовали это!
Полный код
Ниже приведен полный код пользовательского блока с функцией выбора мультимедиа. И ничего больше на самом деле. Эта часть зависит от вас!