Вопрос или проблема
Я добавляю два пользовательских атрибута к основным блокам Гутенберга — data-delay и data-duration. Я хочу добавить эти атрибуты для управления анимацией в моем пользовательском шаблоне.
Я написал этот JS код в block-extension.js:
(function(wp) {
const { addFilter } = wp.hooks;
const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, TextControl } = wp.components;
// Добавьте новые атрибуты к блокам
const addCustomAttributes = (settings, name) => {
if (typeof settings.attributes !== 'undefined') {
settings.attributes = Object.assign(settings.attributes, {
dataDelay: {
type: 'string',
default: '0',
},
dataDuration: {
type: 'string',
default: '0',
},
});
}
return settings;
};
// Добавьте элементы управления для новых атрибутов
const withCustomControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
if (props.isSelected) {
return wp.element.createElement(
Fragment,
null,
wp.element.createElement(BlockEdit, props),
wp.element.createElement(
InspectorControls,
null,
wp.element.createElement(
PanelBody,
{ title: 'Пользовательские атрибуты', initialOpen: true },
wp.element.createElement(TextControl, {
label: 'Data Delay',
value: props.attributes.dataDelay,
onChange: function(newVal) {
props.setAttributes({ dataDelay: String(newVal) });
},
}),
wp.element.createElement(TextControl, {
label: 'Data Duration',
value: props.attributes.dataDuration,
onChange: function(newVal) {
props.setAttributes({ dataDuration: String(newVal) });
},
})
)
)
);
}
return wp.element.createElement(BlockEdit, props);
};
}, 'withCustomControls');
// Добавьте атрибуты к HTML-оберткам блока
const addCustomProps = (saveElementProps, blockType, attributes) => {
if (attributes.dataDelay) {
saveElementProps['data-delay'] = attributes.dataDelay;
}
if (attributes.dataDuration) {
saveElementProps['data-duration'] = attributes.dataDuration;
}
return saveElementProps;
};
// Примените фильтры Gutenberg
addFilter('blocks.registerBlockType', 'luxuryconcept/add-custom-attributes', addCustomAttributes);
addFilter('editor.BlockEdit', 'luxuryconcept/with-custom-controls', withCustomControls);
addFilter('blocks.getSaveContent.extraProps', 'luxuryconcept/add-custom-props', addCustomProps);
})(window.wp);
и PHP код в functions.php:
function my_custom_gutenberg_extension() {
wp_enqueue_script(
'block-extension',
get_template_directory_uri() . '/assets/js/block-extension.js',
array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-compose', 'wp-hooks'),
filemtime(get_template_directory() . '/assets/js/block-extension.js'),
true
);
}
add_action('enqueue_block_editor_assets', 'my_custom_gutenberg_extension');
Я получил это для всех блоков:
Но когда я добавляю блок в редактор Гутенберга, я получаю эти JS ошибки для каждого блока:
Я думаю, что причина в том, что оригинальное содержание отличается от того, у которого добавлены два атрибута data, но я не знаю, как с этим справиться.
Спасибо
–ИЗМЕНЕНИЕ–
Итак, мне нужно удалить
addFilter('blocks.getSaveContent.extraProps', 'luxuryconcept/add-custom-props', addCustomProps);
и добавить этот PHP код, чтобы получить атрибуты:
function theme_custom_add_custom_attributes($block_content, $block) {
// Проверьте, установлен ли атрибут и не пуст ли он
$data_delay = get_field('data-delay', $block['id']);
$data_duration = get_field('data-duration', $block['id']);
// Добавьте атрибуты к блоку только если они установлены
if ($data_delay && !empty($data_delay)) {
$block_content = str_replace('<div', '<div data-delay="' . esc_attr($data_delay) . '"', $block_content);
}
if ($data_duration && !empty($data_duration)) {
$block_content = str_replace('<div', '<div data-duration="' . esc_attr($data_duration) . '"', $block_content);
}
return $block_content;
}
add_filter('render_block', 'theme_custom_add_custom_attributes', 10, 2);
Но я не знаю, как сохранить их в PHP.
Я нашел решение:
- Я убрал
addFilter('blocks.getSaveContent.extraProps', 'luxuryconcept/add-custom-props', addCustomProps);
, как и рекомендовал @TomJNowell. - Я добавил
add_filter('render_block', 'theme_custom_add_custom_attributes', 10, 2);
PHP код в functions.php:
Итак, вот весь рабочий код:
JS:
/**
*
* Расширяет функциональность основных блоков Гутенберга
*
* @description Добавляет атрибуты data-delay и data-duration ко всем основным блокам Гутенберга
* @package luxuryconcept
* @author Stefano Fattori <[email protected]>
* @copyright Stefano Fattori ©2024
* @url www.stefanofattori.it
*
*/
(function(wp) {
const { addFilter } = wp.hooks;
const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, TextControl } = wp.components;
// Добавьте новые атрибуты к блокам
const addCustomAttributes = (settings, name) => {
if (typeof settings.attributes !== 'undefined') {
settings.attributes = Object.assign({}, settings.attributes, {
dataDelay: {
type: 'string',
default: '0',
},
dataDuration: {
type: 'string',
default: '0',
},
});
}
return settings;
};
// Добавьте элементы управления для новых атрибутов
const withCustomControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
if (props.isSelected) {
return wp.element.createElement(
Fragment,
null,
wp.element.createElement(BlockEdit, props),
wp.element.createElement(
InspectorControls,
null,
wp.element.createElement(
PanelBody,
{ title: 'Пользовательские атрибуты', initialOpen: true },
wp.element.createElement(TextControl, {
label: 'Data Delay',
value: props.attributes.dataDelay,
onChange: function(newVal) {
props.setAttributes({ dataDelay: String(newVal) });
},
}),
wp.element.createElement(TextControl, {
label: 'Data Duration',
value: props.attributes.dataDuration,
onChange: function(newVal) {
props.setAttributes({ dataDuration: String(newVal) });
},
})
)
)
);
}
return wp.element.createElement(BlockEdit, props);
};
}, 'withCustomControls');
// Примените фильтры Gutenberg
addFilter('blocks.registerBlockType', 'luxuryconcept/add-custom-attributes', addCustomAttributes);
addFilter('editor.BlockEdit', 'luxuryconcept/with-custom-controls', withCustomControls);
})(window.wp);
PHP:
/**
* Добавляет пользовательские атрибуты к основным блокам Гутенберга (Frontend)
*
* @see /assets/js/block-extension.js
*
* @param mixed $block_content
* @param mixed $block
* @return mixed
*/
function theme_custom_add_custom_attributes($block_content, $block) {
// Проверьте, есть ли пользовательские атрибуты 'dataDelay' и 'dataDuration'
if ( isset($block['attrs']['dataDelay']) && !empty($block['attrs']['dataDelay']) ) {
$block_content = add_custom_attribute($block_content, 'data-delay', $block['attrs']['dataDelay']);
}
if ( isset($block['attrs']['dataDuration']) && !empty($block['attrs']['dataDuration']) ) {
$block_content = add_custom_attribute($block_content, 'data-duration', $block['attrs']['dataDuration']);
}
return $block_content;
}
/**
* Функция для добавления атрибутов данных к HTML блокам
*
* @param mixed $block_content
* @param mixed $attribute_name
* @param mixed $attribute_value
* @return mixed
*
* @since 1.5.5
*/
function add_custom_attribute($block_content, $attribute_name, $attribute_value) {
// Найдите первый HTML-тег в содержимом блока
$pos = strpos($block_content, '>');
if ($pos !== false) {
// Вставьте пользовательский атрибут после первого HTML-тега
$block_content = substr_replace($block_content, ' ' . $attribute_name . '="' . esc_attr($attribute_value) . '"', $pos, 0);
}
return $block_content;
}
add_filter('render_block', 'theme_custom_add_custom_attributes', 10, 2);
Спасибо!
Это прекрасно сработало с моей стороны. Спасибо @stefano !!!
Ответ или решение
Чтобы добавить пользовательские атрибуты data-delay
и data-duration
ко всем основным блокам Gutenberg и избежать ошибок JavaScript, связанных с несовпадением оригинального содержимого блока, вы можете следовать приведенному ниже решению. Это решение включает модификацию JavaScript и PHP кода.
JavaScript код (block-extension.js
)
/**
*
* Расширяет функциональность основных блоков Gutenberg
*
* @description Добавляет атрибуты data-delay и data-duration ко всем основным блокам Gutenberg
* @package luxuryconcept
* @author Stefano Fattori
*/
(function(wp) {
const { addFilter } = wp.hooks;
const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, TextControl } = wp.components;
// Добавляем новые атрибуты к блокам
const addCustomAttributes = (settings, name) => {
if (typeof settings.attributes !== 'undefined') {
settings.attributes = Object.assign({}, settings.attributes, {
dataDelay: {
type: 'string',
default: '0',
},
dataDuration: {
type: 'string',
default: '0',
},
});
}
return settings;
};
// Добавляем управляющие элементы для новых атрибутов
const withCustomControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
if (props.isSelected) {
return wp.element.createElement(
Fragment,
null,
wp.element.createElement(BlockEdit, props),
wp.element.createElement(
InspectorControls,
null,
wp.element.createElement(
PanelBody,
{ title: 'Custom Attributes', initialOpen: true },
wp.element.createElement(TextControl, {
label: 'Data Delay',
value: props.attributes.dataDelay,
onChange: function(newVal) {
props.setAttributes({ dataDelay: String(newVal) });
},
}),
wp.element.createElement(TextControl, {
label: 'Data Duration',
value: props.attributes.dataDuration,
onChange: function(newVal) {
props.setAttributes({ dataDuration: String(newVal) });
},
})
)
)
);
}
return wp.element.createElement(BlockEdit, props);
};
}, 'withCustomControls');
// Применяем фильтры Gutenberg
addFilter('blocks.registerBlockType', 'luxuryconcept/add-custom-attributes', addCustomAttributes);
addFilter('editor.BlockEdit', 'luxuryconcept/with-custom-controls', withCustomControls);
})(window.wp);
PHP код (functions.php
)
/**
* Добавляет пользовательские атрибуты к блоку Gutenberg (FrontEnd)
*
* @param mixed $block_content
* @param mixed $block
* @return mixed
*/
function theme_custom_add_custom_attributes($block_content, $block) {
// Проверяем наличие пользовательских атрибутов 'dataDelay' и 'dataDuration'
if ( isset($block['attrs']['dataDelay']) && !empty($block['attrs']['dataDelay']) ) {
$block_content = add_custom_attribute($block_content, 'data-delay', $block['attrs']['dataDelay']);
}
if ( isset($block['attrs']['dataDuration']) && !empty($block['attrs']['dataDuration']) ) {
$block_content = add_custom_attribute($block_content, 'data-duration', $block['attrs']['dataDuration']);
}
return $block_content;
}
/**
* Функция для добавления пользовательских атрибутов к HTML блокам
*
* @param mixed $block_content
* @param mixed $attribute_name
* @param mixed $attribute_value
* @return mixed
*/
function add_custom_attribute($block_content, $attribute_name, $attribute_value) {
// Находим первое HTML тег в содержимом блока
$pos = strpos($block_content, '>');
if ($pos !== false) {
// Вставляем пользовательский атрибут после первого HTML тега
$block_content = substr_replace($block_content, ' ' . esc_attr($attribute_name) . '="' . esc_attr($attribute_value) . '"', $pos, 0);
}
return $block_content;
}
add_filter('render_block', 'theme_custom_add_custom_attributes', 10, 2);
Объяснение изменений:
-
Удаление лишних фильтров: Убедитесь, что не используете
addFilter('blocks.getSaveContent.extraProps', ...)
, чтобы избежать конфликтов с оригинальным содержимым блока. -
Добавление атрибутов на серверной стороне: Определяем атрибуты
data-delay
иdata-duration
с помощью фильтраrender_block
, который позволяет изменять HTML-код блока перед его выводом на экран. -
Функция для добавления атрибутов: Функция
add_custom_attribute
ищет первое HTML-тег в содержимом блока и добавляет к нему пользовательские атрибуты.
Заключение
С помощью приведенного выше решения вы сможете добавить кастомные данные атрибуты к основным блокам Gutenberg без возникновения ошибок JavaScript. Теперь ваш код будет работать корректно и вы сможете управлять анимацией через указанные атрибуты.