Вопрос или проблема
Итак, я создал пользовательскую конечную точку для получения данных постов, которые мне нужно извлечь для функции, которую я разрабатываю для некоторых пользовательских блоков Gutenberg. После прочтения этого ответа я начал делать свою собственную реализацию. Но у меня есть сомнения по поводу того, как или когда мне следует добавлять свою пользовательскую сущность. На данный момент я добавляю свою пользовательскую сущность с помощью пользовательского хука в editor.BlockEdit
. Вот как это выглядит:
import {addFilter} from '@wordpress/hooks';
import {dispatch, select} from '@wordpress/data';
addFilter('editor.BlockEdit', 'CustomGutenberg/customEntities', ((BlockEdit) => (props) => {
registerCustomEntities();
// (...)
return <BlockEdit {...props} />;
}));
const registerCustomEntities = () => {
const {getEntitiesByKind} = select('core');
const namespace="custom/v1";
if (getEntitiesByKind(namespace).length === 0) {
dispatch('core').addEntities([
{
label: 'Пользовательские Посты',
name: 'posts',
kind: namespace,
baseURL: namespace + '/posts'
}
]);
}
}
И это работает отлично, но тот факт, что я должен проверять, была ли сущность уже добавлена в условии вверху, заставляет меня думать, что я, возможно, использую не тот хук/фильтр/функцию для регистрации своей пользовательской сущности. Поэтому я хотел бы получить больше информации, так как функция addEntities
не совсем хорошо документирована, насколько я знаю.
Дополнительный контекст: Зачем мне нужна пользовательская конечная точка в первую очередь?
Я разрабатываю блоки Gutenberg уже некоторое время, и иногда у меня возникает необходимость получить список всех существующих постов данного CPT. Поэтому я использую getEntityRecords, чтобы получить этот список, но обычно мне нужен только идентификатор поста и его сырой заголовок. Но затем я сталкиваюсь с проблемой getEntityRecords, поскольку она запрашивает – и извлекает – все атрибуты поста, из-за чего запрос занимает очень много времени, когда объем постов велик.
Я наткнулся на этот вопрос задолго после того, как его задали – но ради всех читателей, ищущих, как использовать эту действительно плохо документированную функцию, вот мой ответ:
Не используйте addEntities в фильтре. Это не та же логика, что и в PHP бэкенде. Помещение ее в фильтр BlockEdit
действительно создает проблему вызова ее при регистрации каждого блока, и поэтому вам приходится использовать эту обводку, которую вы включили в свой код.
Просто вызовите ее в основном скрипте, который зарегистрирован с блоком (обычно index.js) или вы можете вызвать ее в edit.js (если ваш блок имеет отдельный файл для редактирования). Важно вызывать ее вне функции Edit или любого элемента WordPress React, так как это вызовет те же проблемы, что и вы испытали, потому что она вызывается слишком поздно и/или повторно.
Дополнительно, если вы посмотрите на определение getEntityRecords, вы заметите, что у нее есть четвертый параметр (на самом деле третий, поскольку вы не указываете состояние, вызывая ее) query
, который вы можете использовать для получения только тех полей, которые вам нужны, без необходимости строить пользовательские REST конечные точки.
В глобальных REST параметрах WordPress есть параметр _fields, который вы должны использовать как свойство объекта в этом вызове, вот так (это вызов внутри функции Edit):
const postTitlesList = useSelect(select => select('core').getEntityRecords('postType', 'post', { ['_fields']: 'id,title' }), []);
Для большинства разработчиков я определенно рекомендую прочитать ответ Ловор, если он больше подходит для ваших нужд.
Но если вы хотите добавить пользовательскую сущность, предложенный код близок, однако нет необходимости добавлять его внутри addFilter
. Вместо этого вызовите эту функцию один раз при загрузке страницы.
Что-то вроде следующего сработало для меня:
const registerCustomEntities = () => {
const {getEntitiesByKind} = select('core');
const namespace="custom/v1";
if (getEntitiesByKind(namespace).length === 0) {
dispatch('core').addEntities([
{
label: 'Пользовательские Посты',
name: 'posts',
kind: namespace,
baseURL: namespace + '/posts'
}
]);
}
}
registerCustomEntities();
Теперь это будет доступно в getEntityRecords
, например:
const customData = select('core').getEntityRecords(
'custom/v1',
'posts',
{
per_page: 15
}
);
Ответ или решение
Как правильно добавить пользовательские сущности в Gutenberg
Введение
Добавление пользовательских сущностей в редактор блоков Gutenberg в WordPress может показаться сложной задачей, особенно если вы сталкиваетесь с недостаточной документацией. В данной статье мы детально рассмотрим процесс регистрации кастомных сущностей, а также обсудим действия, которые следует предпринять для их корректного использования.
Зачем нужны пользовательские сущности?
Причины, по которым может понадобиться создание собственных сущностей, различны. Одной из наиболее частых задач является необходимость получить данные о записях определённого пользовательского типа записи (CPT). Стандартный метод getEntityRecords
запрашивает полные данные о записях, что может замедлить работу приложения, особенно в случае большого объема данных. Создание кастомной сущности и конечной точки REST позволяет эффективно оптимизировать этот процесс.
Правильный способ регистрации пользовательских сущностей
Многие разработчики ошибаются, пытаясь зарегистрировать свои сущности внутри хуков, таких как editor.BlockEdit
. Это неэффективно, так как приводит к многократному вызову функции регистрации во время рендеринга каждого блока. Вместо этого, следует вызвать регистрацию сущности один раз при загрузке страницы. Вот как это можно реализовать:
Пример кода
import { dispatch, select } from '@wordpress/data';
// Функция регистрации пользовательских сущностей
const registerCustomEntities = () => {
const { getEntitiesByKind } = select('core');
const namespace = "custom/v1";
// Проверяем, зарегистрированы ли сущности
if (getEntitiesByKind(namespace).length === 0) {
dispatch('core').addEntities([
{
label: 'Custom Posts',
name: 'posts',
kind: namespace,
baseURL: `${namespace}/posts`
}
]);
}
}
// Вызываем функцию регистрации на стадии загрузки страницы
registerCustomEntities();
Использование пользовательских сущностей
После регистрации сущности, вы можете обращаться к ней через getEntityRecords
. Например, если вам нужно получить идентификаторы и заголовки записей, это можно сделать следующим образом:
const customData = select('core').getEntityRecords(
'custom/v1',
'posts',
{ per_page: 15 }
);
Альтернативные подходы
Если ваша цель — просто оптимизировать запросы к стандартным сущностям, рассмотрите возможность использования третьего параметра функции getEntityRecords
. Этот параметр позволяет указать, какие именно поля необходимы, тем самым минимизируя объем данных, которые вы запрашиваете. Например:
const postTitlesList = useSelect(select =>
select('core').getEntityRecords('postType', 'post', { ['_fields']: 'id,title' }),
[]
);
Заключение
Добавление пользовательских сущностей в Gutenberg — это мощный инструмент, который может существенно повысить производительность и минимизировать запросы данных. Убедитесь, что вы регистрируете сущности только один раз и избегаете лишних вызовов внутри хуков. Следуя представленным рекомендациям, вы сможете эффективно интегрировать кастомные сущности в ваш проект и добиться оптимальных результатов.
SEO-оптимизация
Чтобы материал был доступен для широкой аудитории, используйте такие ключевые слова, как "Gutenberg", "пользовательские сущности", "WordPress REST API" и "оптимизация запросов", что улучшит его видимость в поисковых системах.
Не стесняйтесь задавать вопросы или делиться своим опытом по данной теме в комментариях!