Хотя это не является фактическим ответом на ваш вопрос «Как я могу программно принудительно сохранить макет узла?», я хотел указать вам на Конструктор макетов IPE модуль, который я создал для решения задачи, аналогичной вашей: предоставить возможности редактирования непосредственно со страницы просмотра узла.
Если это не вариант для вас, то программное решение, вероятно, развивается вокруг:
- подключение к форме submit
- добавление вашего пользовательского обработчика отправки
- возьми конфиг блока как-нибудь
- обновить OverridesSectionStorage для узла
- сохранить узел
- удалить временное хранилище для построителя компоновки этого узла
По крайней мере, это то, что я помню. Работая над IPE Layout Builder, я обнаружил, что вся эта структура немного сложна, если честно, что было основной причиной, по которой я попытался сделать это один раз более общим способом.
Обновлять
Еще некоторые детали, которые я искал, которые могут помочь с этим:
Чтобы получить разделы для узла с включенным компоновщиком, вы можете использовать LayoutEntityHelperTrait::getSectionStorageForEntity, например:
$section_storage = $this->getSectionStorageForEntity($node);
$sections = $section_storage->getSections();
Этот $ разделы
переменная представляет собой массив разделов, каждый раздел содержит компоненты раздела. Вы можете перебирать их, пока не найдете искомый блок, и сделать то, что вам нужно сделать, чтобы обновить конфигурацию (непроверенный код):
foreach ($sections как $delta => $section) {
foreach ($section->getComponents() как $component) {
// Каждый компонент является объектом типа \Drupal\layout_builder\SectionComponent.
// Чтобы идентифицировать блок, вы можете использовать идентификатор плагина (или UUID, если
// существует несколько блоков одного типа).
$plugin_id = $component->getPluginId();
если ($plugin_id == 'BLOCK_PLUGIN_ID') {
$configuration = $component->get('configuration');
// Обновите конфигурацию, а затем обновите компонент.
$component->setConfiguration($configuration);
}
}
}
После внесения необходимых изменений разделы можно сохранить обратно в узел, используя это:
$node->get(OverridesSectionStorage::FIELD_NAME)->setValue($sections);
И чтобы очистить временное хранилище, должно работать что-то вроде этого, хотя это, очевидно, должно использовать DI:
\Drupal::service('layout_builder.tempstore_repository')->delete($section_storage);