- Вопрос или проблема
- Ответ или решение
- Шаги для реализации
- 1. Изменение схемы для элементов <td> и <th>
- 2. Переопределение трансформаций блока
- 3. Поддержка для атрибутов colspan и rowspan
- 4. Обеспечение сохранения атрибутов при сохранении
- 5. Тестирование
- Почему атрибуты для <span> работали?
- Дополнительные замечания
Вопрос или проблема
Я пытаюсь позволить пользователям вставлять (относительно) простые таблицы в Gutenberg. Редактор корректно преобразует сырой HTML, но удаляет любые атрибуты/классы. В основном это хорошо – я хочу убедиться, что разметка чистая – но он также удаляет атрибуты colspan
и rowspan
.
Изучая блок таблицы в репозитории Gutenberg на GitHub и фильтры блоков в руководстве Gutenberg на wordpress.org, я составил следующее:
const { getPhrasingContentSchema } = wp.blocks;
// Частично определяет, что разрешено в таблице при вставке.
// Скопировано из файла основного блока таблицы в репозитории Gutenberg.
const tableContentPasteSchema = {
tr: {
children: {
th: {
children: getPhrasingContentSchema(),
},
td: {
children: getPhrasingContentSchema(),
// Это единственная новая часть в схеме
attributes: [ 'colspan', 'rowspan'],
},
},
},
};
// Частично определяет, что разрешено в таблице при вставке.
// Скопировано из файла основного блока таблицы в репозитории Gutenberg.
const tablePasteSchema = {
table: {
children: {
thead: {
children: tableContentPasteSchema,
},
tfoot: {
children: tableContentPasteSchema,
},
tbody: {
children: tableContentPasteSchema,
},
},
},
};
// Изменяет настройки трансформаций блока таблицы
function addTableBlockSpanAttributes( settings, name ) {
if ( name !== 'core/table' ) {
return settings;
}
return lodash.assign({}, settings, {
transforms: {
from: [
{
type: 'raw',
selector: 'table',
schema: tableSchema,
},
],
},
});
}
wp.hooks.addFilter(
'blocks.registerBlockType',
'my-plugin/transforms/table-block',
addTableBlockSpanAttributes
);
(Код основан на примере здесь: https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#blocks-registerblocktype)
Все это кажется правильным, насколько я могу судить, но любые colspan/rowspan удаляются при вставке. Кроме того, вручную редактируя блок в HTML поста, возникает ошибка блока, которую можно устранить только удалением атрибута colspan/rowspan.
Стоит отметить, что если я использую тот же код, но позволяю colspan
на <span>
внутри <td>
, это работает абсолютно нормально (несмотря на то, что <span colspan="2">
не является корректным HTML).
Что я делаю не так? Есть ли другой способ перегрузить разрешенные атрибуты блока core/table
? Есть ли что-то еще в ядре, что запрещает атрибуты <td>
?
Проблема возникает из-за того, что блок таблицы Gutenberg обеспечивает строгую проверку схемы. Даже если вы измените схему для вставки HTML, сохраненные атрибуты для элементов <td>
или <th>
(такие как colspan
и rowspan
) также проверяются в соответствии с логикой сохранения и редактирования блока. Если атрибуты не разрешены в явном виде при регистрации блока, Gutenberg удаляет их, что приводит к ошибкам.
Чтобы решить эту проблему и разрешить атрибуты colspan
и rowspan
на ячейках таблицы, вам необходимо изменить схему и убедиться, что атрибуты сохраняются во время процессов сохранения и редактирования блока. Вот как вы можете это исправить:
Решение: Измените основной блок таблицы
Это решение предполагает расширение поведения основного блока table
для включения поддержки colspan
и rowspan
.
- Измените схему для элементов
td
иth
Настройте схему так, чтобы colspan
и rowspan
были разрешены для td
и th
.
const { assign } = lodash;
const { getPhrasingContentSchema } = wp.blocks;
const tableContentSchema = {
tr: {
children: {
th: {
children: getPhrasingContentSchema(),
attributes: [ 'colspan', 'rowspan' ], // Разрешить colspan и rowspan на <th>
},
td: {
children: getPhrasingContentSchema(),
attributes: [ 'colspan', 'rowspan' ], // Разрешить colspan и rowspan на <td>
},
},
},
};
const tableSchema = {
table: {
children: {
thead: {
children: tableContentSchema,
},
tfoot: {
children: tableContentSchema,
},
tbody: {
children: tableContentSchema,
},
},
},
};
- Переопределите
transforms
блока таблицы для использования вашей схемы
Подключитесь к процессу регистрации блока и замените логику transforms.from
на вашу схему.
function addTableBlockSpanAttributes( settings, name ) {
if ( name !== 'core/table' ) {
return settings;
}
return assign({}, settings, {
transforms: {
from: [
{
type: 'raw',
selector: 'table',
schema: tableSchema,
},
],
},
});
}
wp.hooks.addFilter(
'blocks.registerBlockType',
'my-plugin/transforms/table-block',
addTableBlockSpanAttributes
);
- Добавить поддержку атрибутов для
colspan
иrowspan
Расширьте блок core/table
, чтобы сохранить и распознать эти атрибуты.
wp.hooks.addFilter(
'blocks.getSaveContent.extraProps',
'my-plugin/table-cell-attributes',
( extraProps, blockType, attributes ) => {
if ( blockType.name === 'core/table' ) {
// Убедитесь, что colspan и rowspan сохраняются
if ( attributes.colspan ) {
extraProps.colspan = attributes.colspan;
}
if ( attributes.rowspan ) {
extraProps.rowspan = attributes.rowspan;
}
}
return extraProps;
}
);
- Сохраняйте атрибуты во время сохранения
Обновите логику save
блока таблицы, чтобы убедиться, что атрибуты colspan
и rowspan
сохраняются корректно. Вы можете достичь этого, расширив логику рендеринга ячеек таблицы.
-
Тестируйте ваши изменения
-
Вставьте таблицу:
- Вставьте HTML с
<td colspan="2">
или<th rowspan="3">
в редактор блока. - Подтвердите, что атрибуты не удаляются.
- Вставьте HTML с
-
Редактировать HTML:
- Отредактируйте блок в HTML-редакторе и вручную добавьте
colspan
илиrowspan
. - Подтвердите, что ошибка блока не появляется.
- Отредактируйте блок в HTML-редакторе и вручную добавьте
Почему <span>
сработал?
Gutenberg менее строг к встроенным элементам, таким как <span>
, потому что они не являются частью схемы блока table
по умолчанию. Изменив схему таблицы в явном виде, ту же гибкость можно применить к <td>
и <th>
.
Дополнительные примечания
- Обновления ядра: Следите за будущими обновлениями Gutenberg. Если поддержка
colspan
иrowspan
будет добавлена нативно, эта пользовательская логика может больше не понадобиться. - Пользовательские блоки: Если изменение основного блока оказывается слишком ограничительным или хрупким, подумайте о создании пользовательского блока таблицы, который включает полную поддержку этих атрибутов.
Ответ или решение
Чтобы расширить функциональность блока таблицы в Gutenberg и разрешить использование атрибутов colspan
и rowspan
при вставке HTML-кода, необходимо внести ряд изменений в схему и логику работы блока. Важно помнить, что Gutenberg применяет строгую проверку схемы, что может приводить к удалению неразрешённых атрибутов при вставке.
Шаги для реализации
1. Изменение схемы для элементов <td>
и <th>
Первый шаг заключается в настройки схемы, которая позволит использовать атрибуты colspan
и rowspan
для ячеек таблицы.
const { assign } = lodash;
const { getPhrasingContentSchema } = wp.blocks;
const tableContentSchema = {
tr: {
children: {
th: {
children: getPhrasingContentSchema(),
attributes: ['colspan', 'rowspan'], // Разрешаем colspan и rowspan для <th>
},
td: {
children: getPhrasingContentSchema(),
attributes: ['colspan', 'rowspan'], // Разрешаем colspan и rowspan для <td>
},
},
},
};
const tableSchema = {
table: {
children: {
thead: {
children: tableContentSchema,
},
tfoot: {
children: tableContentSchema,
},
tbody: {
children: tableContentSchema,
},
},
},
};
2. Переопределение трансформаций блока
Следующий шаг включает в себя изменение логики преобразования блока. Вам нужен фильтр, который заменит существующие настройки блока таблицы на ваши изменения в схеме.
function addTableBlockSpanAttributes(settings, name) {
if (name !== 'core/table') {
return settings;
}
return assign({}, settings, {
transforms: {
from: [
{
type: 'raw',
selector: 'table',
schema: tableSchema,
},
],
},
});
}
wp.hooks.addFilter(
'blocks.registerBlockType',
'my-plugin/transforms/table-block',
addTableBlockSpanAttributes
);
3. Поддержка для атрибутов colspan
и rowspan
Чтобы упростить работу с атрибутами, необходимо добавить поддержку этих атрибутов при сохранении и редактировании блока.
wp.hooks.addFilter(
'blocks.getSaveContent.extraProps',
'my-plugin/table-cell-attributes',
(extraProps, blockType, attributes) => {
if (blockType.name === 'core/table') {
// Сохраняем colspan и rowspan
if (attributes.colspan) {
extraProps.colspan = attributes.colspan;
}
if (attributes.rowspan) {
extraProps.rowspan = attributes.rowspan;
}
}
return extraProps;
}
);
4. Обеспечение сохранения атрибутов при сохранении
Вам также потребуется внести изменения в логику сохранения блока, чтобы атрибуты colspan
и rowspan
корректно сохранялись.
5. Тестирование
После внесения всех изменений проведите тестирование, чтобы убедиться, что:
- Таблицы с атрибутами
colspan
иrowspan
могут быть вставлены без их удаления. - Редактирование HTML-кода блоков не вызывает проблем.
Почему атрибуты для <span>
работали?
Атрибуты для <span>
работали, потому что Gutenberg менее строгий по отношению к строчным элементам, поскольку они не входят в состав схемы блока по умолчанию. Ваша задача заключается в том, чтобы явно изменить схему таблицы, обеспечив аналогичную гибкость для элементов <td>
и <th>
.
Дополнительные замечания
- Мониторинг обновлений ядра: Следите за будущими обновлениями Gutenberg. Если поддержка атрибутов
colspan
иrowspan
будет внедрена нативно, вам может не понадобиться данное решение. - Создание пользовательских блоков: Если внесение изменений в ядро блока окажется слишком сложным или ненадежным, рассмотрите возможность создания кастомного блока таблицы с полной поддержкой этих атрибутов.
Таким образом, эти шаги помогут вам расширить возможности работы с блоками таблиц в Gutenberg, позволив пользователям без проблем вставлять и редактировать таблицы с атрибутами colspan
и rowspan
.