До сих пор мы визуализировали вывод блока в Javascript. Однако с динамическим контентом, таким как последние сообщения или отображение сообщения, нам нужно отображать вывод блока в PHP. В этом посте мы узнаем, как и почему.
Почему нам нужно по-разному обрабатывать динамические блоки?
Некоторые примеры очевидны; блок, который отображает последние сообщения в категории, является динамическим, потому что сообщения будут меняться с течением времени. Вы не выбираете посты в блоке; вместо этого у вас, вероятно, будут настройки для выбора категории, информации, отображаемой для каждого сообщения, количества сообщений, количества столбцов и так далее. Каждый раз, когда WordPress загружает пост с этим блоком, он должен запрашивать у WordPress в это время самые новые посты. Просмотр того же поста через месяц может привести к другим результатам, даже если сам пост с блокировкой не был обновлен.
Но необходимость динамических блоков иногда не так очевидна. Вы можете представить, что блок рекомендуемых сообщений, в котором вы выбираете один конкретный пост для его отображения, не обязательно является динамическим. Но может быть – и должно быть. Помните, что выбранный пост может обновить свой заголовок, отрывок или избранное изображение в любое время — и это должно быть отражено в блоках, содержащих этот пост.
Чтобы сделать нединамический блок для показа одного сообщения, вам нужно сохранить идентификатор сообщения, его URL-адрес, URL-адрес избранного изображения, строку отрывка или все, что вам нужно для предварительного просмотра сообщения, в атрибутах блока. И в этом заключается проблема. Если вы обновите избранное изображение выбранного сообщения, сообщение с блоком избранного сообщения не будет автоматически обновлять свои атрибуты. Он останется сохраненным со старым URL-адресом избранного изображения. Только когда вы отредактируете сообщение с блоком и убедитесь, что он повторно сохраняет атрибуты с обновленной информацией, блок покажет правильную обновленную информацию.
Поэтому всякий раз, когда мы имеем дело с динамическим контентом — постами, категориями или чем-то еще, что может меняться со временем — мы имеем дело с динамическими блоками. А для динамических блоков нам нужно использовать PHP — код на стороне сервера — для рендеринга нашего блока, чтобы гарантировать, что он будет получать обновленную информацию каждый раз, когда он рендерится.
Измененный характер динамических блоков в редакторе
Когда вы начнете разрабатывать динамические блоки, характер вашего блока в редакторе изменится. Функция вашего блока также edit
часто должна быть динамичной. Например, для блока рекомендуемых сообщений вам нужно будет выбрать сообщения, или для блока последних новостей вам нужно будет получить список категорий, из которых пользователь может выбирать.
Вполне возможно запрашивать информацию из WordPress из редактора, выполняя запросы AJAX — либо с помощью пакетов и компонентов, либо выполняя их вручную с помощью WordPress REST API. Независимо от того, какой метод вы выберете, ваш блок должен обрабатывать асинхронный поток ввода — временной интервал ожидания ответа.
Существует несколько методов и шаблонов для создания динамического блока для Гутенберга. Чаще всего вы будете использовать шаблон React, называемый компонентами более высокого порядка, для которых WordPress предоставляет множество функций и компонентов.
Мы рассмотрим, как получать сообщения и как получать категории в нашем блоке в следующей части руководства. А пока нам нужно узнать, как заставить PHP отображать наш блок.
Готовим наш блок к PHP-рендерингу
Основная часть, которую нам нужно сделать в Javascript, — это заставить save
функцию блока возвращаться null
. Вы можете оставить исходный вывод, но как только мы укажем WordPress использовать PHP для рендеринга блока, это будет проигнорировано. Чтобы нам и другим было понятно, что вывод блока не обрабатывается в Javascript, мы изменим save
функцию.
Не забывайте, что изменение функции сохранения приведет к поломке всех существующих блоков. Повторно добавьте блок. Блок должен работать так же, как и раньше; с настройками и обновлением атрибутов. Теперь он просто ничего не выводит в интерфейсе. Блок комментариев будет там, сохраняя все атрибуты в формате JSON, но видимый HTML не отображается.
Однако; если какой-либо из ваших атрибутов использует это source
свойство, вам нужно изменить это. Это не поддерживается блоками, отображаемыми с помощью PHP, потому что они анализируются непосредственно из вывода сохранения, к которому мы сейчас возвращаемся null
. Используем исходник на втором RichText
в нашем блоке — для абзаца. В этот момент редактор вообще не сохранит то, что вы в него RichText
вставите.
Поэтому, если вы также все еще используете source
атрибут myRichText
, нам нужно удалить свойства source
и selector
, чтобы гарантировать, что атрибуты будут сохранены, а не проанализированы из save
функции:
attributes: {
...
myRichText: {
type: 'string',
},
...
После этого наш блок готов к рендерингу в PHP. Мы можем оставить файлы Javascript (не забудьте его собрать), а все остальное делается на PHP.
Отрисовка блоков в PHP
Чтобы сообщить WordPress об отображении вывода блока в PHP, мы добавляем в функцию новый аргумент register_block_type()
. Нам нужно добавить ключ render_callback
в массив со значением функции, которую он должен запускать.
Функция рендеринга PHP
Давайте определим функцию awp_myfirstblock_render
ниже functions.php
(или там, где вы поместили свой PHP-код). Наша функция получит два параметра; мы позвоним им $attr
и $content
.
function awp_myfirstblock_render($attr, $content) {
// return the block's output here
}
Параметр $attr
будет представлять собой ассоциативный массив со всеми сохраненными атрибутами. Второй параметр, $content
, предназначен для блоков внутри нашего блока. Это относится только к блокам, которые поддерживают вложенные блоки, что, например, делают Колонны или Обложка.
Функция никогда не должна echo
ничего выдавать. Все выходные данные должны быть возвращены, поэтому вам нужно построить строку и вернуть ее в конце.
Что важно помнить об атрибутах, так это то, что только сохраненные атрибуты будут отображаться в первом параметре функции. Если атрибут на самом деле никогда не изменялся и не сохранялся, т. е. просто полагался на его default
, атрибут вообще не будет включен в нашу PHP-функцию.
Вам нужно решить эту проблему, либо всегда проверяя if (isset($attr['...']))
, либо предпочтительнее: определяя атрибуты в нашем register_block_type()
вызове. Мы можем предоставить другой ключ, attributes
и установить его значение в массив со всеми атрибутами, которые мы хотим извлечь из нашего блока. Структура должна быть идентична той, которую вы определили в Javascript, но вместо объекта Javascript вам нужен массив PHP. Это может быть немного громоздко, чтобы переопределить одни и те же атрибуты, но с умным редактором кода должно быть довольно быстро скопировать + вставить и отредактировать его в несколько строк в PHP.
Добавление атрибутов для нашей функции рендеринга
Давайте добавим новый attributes
элемент register_block_type()
и вставим те же самые атрибуты, которые мы определили в нашем файле Javascript:
Имейте в виду, что если вы определяете default
для всех атрибутов, $attr
параметр вашей функции всегда должен содержать все атрибуты. Например, указанный textAlignment
выше атрибут будет существовать только в $attr
том случае, если он был изменен, и вам нужно будет проверить isset($attr['textAlignment'])
.
К сожалению, на данный момент есть две вещи, которые вы не освоите с помощью рендеринга блоков PHP. Один из них — className
поддержка, поэтому вам нужно создать класс-оболочку (если вы этого хотите) самостоятельно. Другое support
свойство — выравнивание блоков. На данный момент WordPress не поддерживает это свойство в динамических блоках. Мы не получим значение выбранного выравнивания блока, если не изменим его на атрибут и не обработаем вручную в Javascript.
Что касается HTML-вывода функции, это полностью зависит от вас!
Запрос рендеринга PHP из внутреннего редактора
Можно запросить PHP-рендеринг нашего блока внутри редактора. Это полезно, если вы хотите предварительно просмотреть вывод блока в редакторе. Мы можем сделать это с помощью компонента, вызываемого ServerSideRender
из wp.editor
пакета.
В качестве реквизита ServerSideRender
вам необходимо определить все атрибуты, которые вы хотите передать. Как минимум, вам нужно указать имя блока в свойстве block
, чтобы WordPress знал, какой метод рендеринга искать. Это доступно для вас в props.name
функции edit
. Вам также необходимо предоставить любые атрибуты, которые вам нужны в свойстве attributes
. Если вы хотите, вы также можете добавить пользовательские переменные вне атрибутов здесь. Просто имейте в виду, что это будет работать только для внутреннего редактора, а не для внешнего интерфейса.
Вы не можете использовать ServerSideRender
в функции блока save
. Ваша save
функция все равно должна возвращаться null
.
Давайте реализуем ServerSideRender
в нашем блоке, чтобы увидеть это на практике.
Использование ServerSideRender для режима предварительного просмотра/редактирования блока
Если вы следовали предыдущему шагу, где мы сделали переключатель режима предварительного просмотра/редактирования для нашего блока, теперь мы можем использовать ServerSideRender
для рендеринга предварительного просмотра блока из PHP, когда мы переключаемся в режим предварительного просмотра.
Сначала нам нужно не забыть деструктурировать ServerSideRender
вверху:
const { ServerSideRender } = wp.editor;
Если вы помните, на предыдущем шаге мы использовали компоненты Disabled
и/или Placeholder
для предварительного просмотра. Проблема с использованием Placeholder
заключается в том, что к нашему выводу применяются нежелательные стили. Заменим Placeholder
на ServerSideRender
. Вы можете сохранить Disabled
компонент, чтобы гарантировать, что ни одно из его содержимого не будет кликабельным или перетаскиваемым.
В коде отрисовки блока при ложном атрибуте editMode
делаем:
Теперь наша пользовательская кнопка на панели инструментов будет отображать вывод из PHP, когда мы переключаемся в режим предварительного просмотра. Вывод должен быть идентичен при просмотре поста во внешнем интерфейсе. Это хорошая привычка, чтобы убедиться, что вывод идентичен как в редакторе, так и во внешнем интерфейсе.
Пример: динамический блок, показывающий выбранный пост
Вывод в вашей функции рендеринга PHP может быть любым, и у вас есть полный доступ ко всем функциям WordPress. Предположим, блок, в котором идентификатор сообщения будет сохранен в атрибуте. В render_callback
функции PHP вы можете запросить сообщение по идентификатору и вывести его информацию. Это должно быть довольно понятно, как это сделать, но вот краткий пример.
NB: в этом примере мы просто добавим текстовый ввод в редактор для ручного ввода идентификатора сообщения. Это не очень интуитивно понятное и удобное решение для выбора поста, но это то, чему мы научимся на следующем шаге. Основное внимание здесь уделяется PHP-части рендеринга выбранного сообщения.
Добавим атрибут selectedPostId
типа number:
attributes: {
selectedPostId: {
type: 'number'
}
}
И где-то внутри функции нашего блока edit
мы добавляем TextControl
компонент. Он может быть где угодно — внутри блока или в Инспекторе.
Обратите внимание, что я уделяю особое внимание тому, чтобы входные данные правильно сохраняли атрибут в виде числа, преобразуя его в целое число с помощью parseInt()
. Несмотря на то, что мы установили свойство type type
для number
отображения числового ввода, измененное значение по-прежнему интерпретируется как строка. WordPress не сохранит ваш атрибут, если он будет в неправильном формате.
Не забудьте добавить новый атрибут к вашему ServerSideRender
компоненту, если он у вас есть:
Часть PHP
Это должно было позаботиться о части Javascript. Перейдем к PHP. Сначала нам нужно добавить новый атрибут selectedPostId
в attributes
массив в register_block_type()
:
Теперь в render_callback
функции мы можем получить доступ к идентификатору сообщения с помощью $attr['selectedPostId']
. С этим мы можем выполнить простое get_post()
и вывести данные сообщения; его ссылка и название:
Это очень простой пример, предназначенный в качестве отправной точки для написания более сложного и пользовательского кода.
Теперь, когда мы знаем, как обрабатывать динамические блоки рендеринга, следующим шагом будет изучение того, как сделать часть редактора более интуитивно понятной. На следующем шаге мы сосредоточимся на том, как запрашивать сообщения из редактора блоков и предоставить пользователю лучший способ выбора сообщения.