Mặc dù đây không phải là câu trả lời thực sự cho câu hỏi của bạn "Làm cách nào tôi có thể buộc lưu bố cục của nút theo chương trình?", Tôi muốn chỉ cho bạn Trình tạo bố cục IPE mô-đun mà tôi đã tạo để giải quyết trường hợp sử dụng tương tự như của bạn: Cung cấp khả năng chỉnh sửa trực tiếp từ trang xem của một nút.
Nếu đây không phải là một tùy chọn dành cho bạn, thì giải pháp có lập trình có thể phát triển xung quanh:
- nối vào biểu mẫu gửi
- thêm trình xử lý gửi tùy chỉnh của bạn
- lấy cấu hình khối bằng cách nào đó
- cập nhật OverridesSectionStorage cho nút
- lưu nút
- xóa bộ lưu trữ tạm thời cho trình tạo bố cục của nút đó
Ít nhất đó là những gì tôi nhớ lại. Khi làm việc trên IPE của Trình tạo bố cục, thành thật mà nói, tôi thấy rằng toàn bộ cấu trúc hơi phức tạp, đó là lý do chính để thử và hoàn thành việc này một lần theo cách chung chung hơn.
Cập nhật
Một số chi tiết khác tôi đã tra cứu có thể giúp ích cho việc này:
Để có được các phần cho nút kích hoạt trình tạo bố cục, bạn có thể sử dụng LayoutEntityHelperTrait::getSectionStorageForEntity, ví dụ.:
$section_storage = $this->getSectionStorageForEntity($node);
$sections = $section_storage->getSections();
Cái này $phần
biến là một mảng các phần, mỗi phần chứa các thành phần của phần. Bạn có thể lặp lại chúng cho đến khi tìm thấy khối mà bạn đang tìm kiếm và làm những gì bạn cần làm để cập nhật cấu hình (mã chưa được kiểm tra):
foreach ($sections as $delta => $section) {
foreach ($section->getComponents() dưới dạng $component) {
// Mỗi thành phần là một đối tượng kiểu \Drupal\layout_builder\SectionComponent.
// Để xác định khối, bạn có thể sử dụng plugin id (hoặc UUID nếu
// tồn tại nhiều khối cùng loại).
$plugin_id = $component->getPluginId();
nếu ($plugin_id == 'BLOCK_PLUGIN_ID') {
$configuration = $component->get('configuration');
// Cập nhật cấu hình, sau đó cập nhật thành phần.
$component->setConfiguration($configuration);
}
}
}
Khi các thay đổi cần thiết đã được thực hiện, các phần có thể được lưu lại vào nút bằng cách sử dụng:
$node->get(OverridesSectionStorage::FIELD_NAME)->setValue($sections);
Và để xóa tempstore, một cái gì đó như thế này sẽ hoạt động, mặc dù điều này rõ ràng nên sử dụng DI:
\Drupal::service('layout_builder.tempstore_repository')->delete($section_storage);