Gutenberg: Ошибка валидации блока

14 февр. 2020 г., 10:50:42
Просмотры: 16.6K
Голосов: 10

Я использую кастомный блок для генерации шорткода, который затем рендерит HTML.

Когда я добавляю блок и сохраняю пост, всё работает - блок рендерит шорткод с дефолтными значениями.

Когда я изменяю какие-то значения, пост сохраняется без ошибок и работает на фронтенде.

Но когда я перезагружаю страницу редактирования поста, получаю следующую ошибку:

Block validation: Block validation failed for `fare/list-posts` ( 
Object { name: "fare/list-posts", icon: {…}, attributes: {…}, keywords: [],   save: save(t), title: "List Posts", category: "common", edit: edit(e)
 }
).

Содержимое, сгенерированное функцией `save`:

[list-posts type="post" category="" count="6"][/list-posts]

Содержимое, полученное из тела поста:

[list-posts type="post" category="" count="12"][/list-posts]

Валидация ожидает дефолтные значения, но получает отредактированный шорткод с новыми значениями.

Вот мой JavaScript код:

/* Этот участок кода регистрирует новый блок, устанавливает иконку, категорию и определяет типы полей */
wp.blocks.registerBlockType('fare/list-posts', {
  title: 'List Posts',
  icon: 'tickets',
  category: 'common',
  attributes: {
    posttype: {
      type: 'string',
      default: 'post'
    },
    postcategory: {
      type: 'string',
      default: ''
    },
    postcount: {
      type: 'number',
      default: 6
    },
  },

  /* Здесь настраивается работа полей контента и цвета, создаются необходимые элементы */
  edit: function(props) {
    function updatePostType(event) {
      props.setAttributes({posttype: event.target.value})
    }
    function updateCategory(event) {
      props.setAttributes({postcategory: event.target.value})
    }
    function updatePostCount(event) {
      props.setAttributes({postcount: event.target.value})
    }
    return React.createElement("div",{ style: { border: '2px solid #aaaaaa', 'border-radius': '3px', padding: '12px'}},
      React.createElement( "h3", null, "List Posts" ),
      React.createElement( "span", { style: { margin: '0' }}, "Post Type" ),
      React.createElement( "input", { type: "text", value: props.attributes.posttype, onChange: updatePostType, style: {} }),
      React.createElement( "hr" ),
      React.createElement( "span", { style: { margin: '0' }}, "Post Category" ),
      React.createElement( "input", { type: "text", value: props.attributes.postcategory, onChange: updateCategory, style: {} }),
      React.createElement( "hr" ),
      React.createElement( "span", { style: { margin: '0' }}, "Post Count" ),
      React.createElement( "input", { type: "number", value: props.attributes.postcount, onChange: updatePostCount, style: {} })
    )
  },

  save: function(props) {
    //
    return '[list-posts type="'+props.attributes.posttype+'" category="'+props.attributes.postcategory+'" count="'+props.attributes.postcount+'"][/list-posts]';
  }
})

Может кто-нибудь подсказать, что я делаю не так?

Спасибо.

0
Все ответы на вопрос 1
1
13

Коротко говоря, при сохранении атрибута убедитесь, что его тип соответствует тому, который вы определили в опции attributes блока.

В документации сказано:

Наконец, убедитесь, что вы учитываете тип данных при установке атрибутов, так как фреймворк не выполняет автоматическое приведение типов для метаданных. Неправильный тип в атрибутах блока приведёт к тому, что пост останется "грязным" даже после сохранения (см. isEditedPostDirty, hasEditedAttributes). Например, если authorCount является целым числом, помните, что обработчики событий могут передавать данные другого типа, поэтому значение следует явно преобразовывать:

function onChange( event ) {
  props.setAttributes( { authorCount: Number( event.target.value ) } );
}

Таким образом, проблема в атрибуте postcount, который определён как число, но сохраняется как строка (event.target.value в вашем случае является строкой).

С вашим текущим кодом, если вы установите postcategory в foo, а postcount в значение, отличное от 6, например 3, HTML-вывод блока будет выглядеть так:

<!-- wp:fare/list-posts {"postcategory":"foo"} -->
[list-posts type="post" category="foo" count="3"][/list-posts]
<!-- /wp:fare/list-posts -->

но на самом деле он должен быть таким — обратите внимание на "postcount":3:

<!-- wp:fare/list-posts {"postcategory":"foo","postcount":3} -->
[list-posts type="post" category="foo" count="3"][/list-posts]
<!-- /wp:fare/list-posts -->

А вот проблемный код:

// В updatePostCount()
props.setAttributes({postcount: event.target.value})

который должен быть записан так:

props.setAttributes({postcount: Number( event.target.value )})

То есть вам нужно явно преобразовать значение в число, а не передавать его как есть (в виде строки).

14 февр. 2020 г. 14:06:54
Комментарии

довольно странно, что это не вызывает ошибку в setAttributes

aaaaaa aaaaaa
14 февр. 2024 г. 02:10:00