Gutenberg: Ошибка валидации блока
Я использую кастомный блок для генерации шорткода, который затем рендерит 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]';
}
})
Может кто-нибудь подсказать, что я делаю не так?
Спасибо.

Коротко говоря, при сохранении атрибута убедитесь, что его тип соответствует тому, который вы определили в опции 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 )})
То есть вам нужно явно преобразовать значение в число, а не передавать его как есть (в виде строки).
