Программное добавление элементов галереи внутри InnerBlock

Вопрос или проблема

Я создал пользовательский блок, который содержит информацию о продукте WooCommerce. Блок в основном представляет собой основной компонент InnerBlocks с шаблоном, который выглядит так:

  const createTemplate = (
    productName,
    productDescription,
    productImages,
  ) => [
    [
      'core/columns',
      {
        verticalAlignment: 'center',
        className: 'classes',
      },
      [
        [
          'core/column',
          {
            templateLock: false,
            className: 'whatever',
          },
          [
            [
              'core/column',
              {
                templateLock: false,
                className: 'whatever',
              },
              [
                [
                  'core/gallery',
                  {
                    images: productImages,
                  },
                ],
                [
                  'core/paragraph',
                  {
                    placeholder: 'Placeholder',
                    className: 'whatever',
                  },
                ],
              ],
            ],
            [
              'core/column',
              {
                templateLock: 'all',
                className:
                  'd-flex f-column mw-60 w-100 exp-card-left-content-right-col',
              },
              [
                [
                  'core/heading',
                  {
                    placeholder: 'Title',
                    content: productName || 'Название продукта',
                    className: 'whatever',
                  },
                ],
                [
                  'core/paragraph',
                  {
                    placeholder: 'Content',
                    content: productDescription || 'Описание продукта',
                    className: 'whatever',
                  },
                ],
                [
                  'core/navigation-link',
                  {
                    placeholder: 'Добавить ссылку...',
                    label: 'Смотреть больше',
                    url: `/product/${selectedProductId}`,
                    className: 'whatever',
                  },
                ],
              ],
            ],
          ],
        ],
      ],
    ],
  ];

Способ, которым я получаю атрибуты, – это вызов apiFetch:

      apiFetch({ path: `/wc/v3/products/${selectedProductId}` })
        .then((product) => {
          const cleanedDescription = stripHtml(product.description);

          // Устанавливаем данные продукта, полученные из API, в атрибуты блока
          setAttributes({
            productName: product.name,
            productDescription: cleanedDescription,
            productPrice: product.price,
            productImages: product.images.map((img) => ({ url: img.src })),
            productInjected: true, // Предотвращает повторные вызовы API
          });

          // Динамически заменяем содержимое InnerBlocks на полученные данные
          wp.data.dispatch('core/block-editor').replaceInnerBlocks(
            clientId,
            wp.blocks.createBlocksFromInnerBlocksTemplate(
              createTemplate(
                product.name,
                cleanedDescription,
                product.price,
                product.images.map((img) => ({ url: img.src })),
              ),
            ),
          );

          setLoading(false);
        })
        .catch((err) => {
          setError(err);
          setLoading(false);
        });

Все работает нормально, за исключением блока core/gallery. Я предполагаю, что я неправильно формирую объект галереи, но не хватает документации по этому вопросу. Я был бы признателен за любые подсказки.

Похоже, проблема возникает из-за того, что мы не передали идентификатор изображения вместе с URL изображения, поэтому, пожалуйста, попробуйте сделать то же самое и посмотрите.

Вы можете сделать это, заменив данный код

product.images.map((img) => ({ url: img.src }))

на

product.images.map((img) => ({
 id: img.id,
 url: img.src,
}))

Это изменение обеспечит наличие у каждого объекта изображения как идентификатора, так и URL, которые ожидает блок core/gallery.

Ответ или решение

Ваша проблема с использованием блока core/gallery внутри вашего кастомного блока, скорее всего, связана с неправильным форматом объекта изображения. Блок галереи ожидает, что каждый объект изображения будет содержать не только URL изображения, но и его идентификатор. Для решения этой проблемы нужно изменить формат данных, которые вы передаете в core/gallery.

Вместо того чтобы использовать следующий код:

product.images.map((img) => ({ url: img.src }))

замените его на:

product.images.map((img) => ({
  id: img.id,
  url: img.src,
}))

Это изменение гарантирует, что каждый объект изображения включает как id, так и url, что является обязательным требованием для блока core/gallery.

Обновленный фрагмент вашего кода будет выглядеть следующим образом:

apiFetch({ path: `/wc/v3/products/${selectedProductId}` })
  .then((product) => {
    const cleanedDescription = stripHtml(product.description);

    // Установка данных о продукте в атрибуты блока
    setAttributes({
      productName: product.name,
      productDescription: cleanedDescription,
      productPrice: product.price,
      productImages: product.images.map((img) => ({
        id: img.id,
        url: img.src,
      })),
      productInjected: true, // Предотвращает повторные API запросы
    });

    // Динамическая замена содержимого InnerBlocks с использованием полученных данных
    wp.data.dispatch('core/block-editor').replaceInnerBlocks(
      clientId,
      wp.blocks.createBlocksFromInnerBlocksTemplate(
        createTemplate(
          product.name,
          cleanedDescription,
          product.price,
          product.images.map((img) => ({
            id: img.id,
            url: img.src,
          })),
        ),
      ),
    );

    setLoading(false);
  })
  .catch((err) => {
    setError(err);
    setLoading(false);
  });

После внесения этих изменений, блок галереи должен работать корректно, и изображения будут отображаться как предусмотрено. Убедитесь, что зная идентификаторы изображений, вы обеспечиваете правильное взаимодействие с другими возможными блоками и компонентами в вашем проекте. Если вам потребуется более подробная информация или помощь, не стесняйтесь задавать вопросы.

Оцените материал
Добавить комментарий

Капча загружается...