Вопрос или проблема
Я пытаюсь создать динамический блок Gutenberg с выпадающим списком. Я завершил создание блока и рендеринг блока с выбранным значением выпадающего списка на фронтенде.
Как установить выпадающий список с предыдущим значением при редактировании поста?
Я пытался получить значение атрибута, используя props.attributes
, но получаю undefined
.
block.js
const { __ } = wp.i18n;
const { registerBlockType, RichText } = wp.blocks;
registerBlockType( 'gut/new-block', {
title: __( 'new-block - Test' ),
category: 'common',
attributes: {
category_id: {
type: 'number'
}
},
edit: function( props ) {
const { attributes: { category_id }, setAttributes } = props;
function setCategory( event ) {
const selected = event.target.querySelector( 'option:checked' );
setAttributes( { category_id: selected.value } );
event.preventDefault();
}
return (
<div className={ props.className }>
<select value={ category_id } onChange={ setCategory }>
<option value="120">Животные</option>
<option value="350">Архитектура</option>
<option value="700">Природа</option>
<option value="800">Люди</option>
<option value="432">Технологии</option>
</select>
</div>
);
},
save ( props ) {
return null
},
});
PHP
function gut_my_new_block() {
wp_register_script(
'gut-my-new-block',
plugins_url( 'new-block/dist/blocks.build.js', __FILE__ ),
array( 'wp-blocks', 'wp-element' )
);
register_block_type( 'gut/new-block', array(
'render_callback' => 'gut_render_block_my_newblock',
'editor_script' => 'gut-my-new-block',
) );
}
add_action( 'init', 'gut_my_new_block' );
function gut_render_block_my_newblock($params) {
return '<h3>выбранная категория '.$params['category_id'].'</h3>';
}
Когда атрибут регистрируется с type: 'number'
, он не вернет строковое значение в объекте атрибутов. Это сбивало меня с толку несколько раз.
Решение заключается в том, чтобы убедиться, что вы устанавливаете значение как число при установке атрибута. Один из способов сделать это:
setAttributes( { category_id: parseInt( selected.value ) } );
Учитывая, что этот вопрос довольно старый, в настоящее время рекомендуется использовать встроенный компонент SelectControl, а не нативный HTML select
.
Вам просто нужно получить значение из атрибутов и установить его в <select>
. В вашем случае это будет так: <select value={ props.attributes.category_id } onChange={ setCategory }>
В общем, вы мыслите в правильном направлении, но переменная, которую вы объявляете на 13 строке, недоступна за пределами {}, и вы устанавливаете значение как undefined.
Ответ или решение
Для создания динамического блока в Gutenberg с выпадающим списком и корректным отображением ранее сохраненных данных при редактировании, важно правильно работать с атрибутами блока. В вашем коде возникают проблемы из-за неверной инициализации и обработки значений атрибутов. Ниже представлено подробное руководство по решению этой проблемы.
Шаг 1: Инициализация атрибутов
Атрибуты вашего блока следует правильно определять, чтобы они могли корректно сохранять и извлекать данные. Для числовых значений, как в вашем случае со значением category_id
, нужно убедиться, что вы обрабатываете их как числа, чтобы избежать ошибок.
Вот как можно это исправить:
attributes: {
category_id: {
type: 'number',
default: 120, // Устанавливаем значение по умолчанию
}
}
Шаг 2: Использование выпадающего списка
При создании выпадающего списка вы можете использовать компонент SelectControl
из библиотеки WordPress, который предоставляет больше возможностей по сравнению с обычным HTML-элементом select
. Обратите внимание, как используется category_id
из атрибутов:
const { SelectControl } = wp.components;
// ... остальная часть кода
edit: function( props ) {
const { attributes: { category_id }, setAttributes } = props;
return (
<div className={ props.className }>
<SelectControl
label={ __( 'Выберите категорию', 'text-domain' ) }
value={ category_id } // Используем значение из атрибутов
options={[
{ label: 'Животные', value: 120 },
{ label: 'Архитектура', value: 350 },
{ label: 'Природа', value: 700 },
{ label: 'Люди', value: 800 },
{ label: 'Технологии', value: 432 },
]}
onChange={ ( value ) => setAttributes( { category_id: parseInt( value, 10 ) } ) } // Преобразуем в число
/>
</div>
);
},
Шаг 3: PHP обработка
Обработчик сервера должен корректно возвращать значение атрибута, чтобы оно отображалось на фронтенде. Параметры передаются в gut_render_block_my_newblock
, как у вас это сделано. Проверьте, правильно ли прописано извлечение значения:
function gut_render_block_my_newblock($params) {
return '<h3>Выбранная категория: '.$params['category_id'].'</h3>';
}
Заключение
Таким образом, исправления, которые вы должны внести в ваш код, заключаются в следующем:
- Убедитесь, что атрибут
category_id
обрабатывается как число (используйтеparseInt
). - Для более удобного управления и улучшенного пользовательского интерфейса лучше использовать компонент
SelectControl
. - Проверьте, что обработка данных на серверной стороне корректна и возвращает значения в ожидаемом формате.
Применение данных рекомендаций поможет вам создать Gutenberg блок, который корректно сохраняет и отображает выбранные значения, улучшая взаимодействие пользователя с вашим редактором.