InnerBlocks добавляет любой блок и сохраняет, но редактор не показывает дочерние блоки при перезагрузке.

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

Итак, у меня есть свой пользовательский блок, и он имеет InnerBlocks, который принимает любой блок. По умолчанию используется один абзацный блок.

wp.blocks.registerBlockType('accordion/child', {
apiVersion: 2,
title: 'Accordion Child',
category: 'design',
parent: [ "accordion/child" ],
attributes: {
    title: {
        type: 'string',
        default: 'This is an accordion'
    },
},
edit({ attributes, setAttributes }) {
    const { title } = attributes;
    const { createElement, Fragment } = wp.element;
    const { PanelBody, TextareaControl } = wp.components;
    const { InnerBlocks, InspectorControls } = wp.blockEditor;
    let blockProps = wp.blockEditor.useBlockProps();
    
    return createElement(Fragment, {},
        createElement(InspectorControls, null,
            createElement(PanelBody, { title: 'Settings' },
                createElement(TextareaControl, {
                    label: 'Title',
                    value: title,
                    onChange: function (newTitle) {
                        setAttributes({ 'title': newTitle });
                    },
                })
            ),
        ),
        createElement('div',
            {  ...blockProps  },
            createElement('div', {className:'accordion-child-content'},
                createElement('div', {
                    className: 'accordion-child-title', 
                }, 
                title
                ),
                createElement(InnerBlocks,
                    {template: ["core/paragraph",{content:'This is the accordion content'}],
                    templateLock: false
                }),
            ),
        )
    );
},
save: function ({ attributes }) {
    const { createElement } = wp.element;
    const { InnerBlocks } = wp.blockEditor;
    const { title } = attributes;
    
    return createElement('div',{className: 'accordion-child'},
        createElement('div', {className: 'accordion-child-title',tabIndex: 0}, 
        title
        ),
        createElement('div', {className: 'accordion-child-content'},
            createElement(InnerBlocks.Content)
        )
    );
}

});

Добавляется один или несколько блоков, и они сохраняются нормально. На фронтэнде они отображаются так, как и ожидалось. Но когда я перезагружаю редактор, он возвращается к одному абзацному блоку по умолчанию.

Как сделать, чтобы редактор показывал сохраненные блоки?

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

Проблема, с которой вы столкнулись при использовании InnerBlocks в вашем кастомном блоке WordPress, связана с тем, что добавленные дочерние блоки не сохраняются должным образом в редакторе после перезагрузки страницы. Это распространённая проблема, связанная с внутренними механизмами сохранения и восстановления состояний блоков в редакторе Gutenberg.

Причины проблемы

  1. Неправильное использование атрибута InnerBlocks: После перезагрузки редактора, кажется, что блоки сбрасываются к шаблонному значению, потому что содержимое блока не сохраняется корректно.

  2. Атрибут template и templateLock: Темплейты применяются каждый раз при загрузке блока в редакторе. Если сохранённые данные не учитываются, это может быть причиной проблемы.

Решение проблемы

  1. Проверка правильности сохранения данных: Убедитесь в том, что редактор корректно сохраняет данные в post_content, и они корректно извлекаются при загрузке редактора.

  2. Использование InnerBlocks и InnerBlocks.Content: Убедитесь, что InnerBlocks.Content корректно извлекается в функции save. Это может влиять на восстановление внутреннего состояния блоков в редакторе.

  3. Устранение коллизий в шаблоне блоков (template):

    • Убедитесь, что template и templateLock не конфликтуют с содержимым, которое должно был загружено из сохранённого состояния. Подумайте об удалении или настройки template таким образом, чтобы он не вмешивался в процесс загрузки сохранённых данных.
  4. Правильное использование useBlockProps:

    • useBlockProps может быть неправильно применён, если не передавать все необходимые параметры. Убедитесь, что все атрибуты и их состояния корректно передаются и извлекаются в блоке.
  5. Проверка на совместимость с API:

    • Убедитесь, что вы используете правильную версию API (в вашем случае — версия 2), и что все функции и их параметры корректно соответствуют используемым API.

Пример корректного использования InnerBlocks

Если проблема сохраняется, рассмотрите рефакторинг вашего кода, основываясь на следующих шагах:

edit({ attributes, setAttributes }) {
  const { title } = attributes;
  const blockProps = wp.blockEditor.useBlockProps();
  return (
    <Fragment>
      <InspectorControls>
        <PanelBody title="Настройки">
          <TextareaControl
            label="Заголовок"
            value={title}
            onChange={(newTitle) => setAttributes({ title: newTitle })}
          />
        </PanelBody>
      </InspectorControls>
      <div {...blockProps}>
        <div className="accordion-child-content">
          <div className="accordion-child-title">{title}</div>
          <InnerBlocks
            template={[["core/paragraph", { content: "Это контент аккордеона" }]]}
            templateLock={false}
          />
        </div>
      </div>
    </Fragment>
  );
},
save({ attributes }) {
  const { title } = attributes;
  const blockProps = wp.blockEditor.useBlockProps.save();
  return (
    <div className="accordion-child" {...blockProps}>
      <div className="accordion-child-title" tabIndex={0}>{title}</div>
      <div className="accordion-child-content">
        <InnerBlocks.Content />
      </div>
    </div>
  );
}

Убедитесь, что ваш код соответствует актуальным стандартам блоковой реализации в WordPress, что поможет избежать подобных проблем.

Заключение

Следуя этим рекомендациям, вы сможете корректно внедрить InnerBlocks в ваш кастомный блок и добиться его корректной работы как в редакторе, так и на фронтенде. Главное, внимательно следите за атрибутами и используемыми API, чтобы избежать ошибок в будущем.

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

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