I was recently looking to modify the form for a content block entity that's placed as an inline block via Layout Builder.
This turns out to be quite difficult:
- The outer most form is either \Drupal\layout_builder\Form\AddBlockForm or \Drupal\layout_builder\Form\UpdateBlockForm, so that's what needs to be form_altered()
- Layout Builder's block form works similarly to core's \Drupal\block\BlockForm, in that it embeds configuration form for the block plugin inside of it. I guess this is called a "subform".
- For inline blocks in layout builder, there's a block plugin class \Drupal\layout_builder\Plugin\Block\InlineBlock. The configuration form for this block plugin is created by building an entity form display for the content block entity that you're trying to create. It does this in a #process callback
Because the actual block content entity form is rendered in a #process callback, a developer that implements a form_alter for layout builder will have a bad time, since the form elements for the block content entity are not actually built yet. Here's what the form array looks like in the form_alter:

Instead, I believe the developer must alter the form to add their own #process callback. And it cannot be added to the outer form array because it's still too early there. It needs to be added to the block_form, after the processBlockForm callback is done.
I wonder if there's a way to improve the developer experience here.
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | 3028391-layout-builder-inline-block-form-alter.patch | 885 bytes | dave reid |
| Screen Shot 2019-01-25 at 9.22.10 AM.png | 67.58 KB | bkosborne |
Issue fork drupal-3028391
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3028391-its-very-difficult
changes, plain diff MR !1726
Comments
Comment #2
bkosborneComment #3
ismail cherri commentedHi,
I have the same issue here. I want to alter some values in the block form and I'm unable due to the reasons mentioned above.
Comment #4
johnwebdev commented#3 It is possible, but as bkosborne mentioned you need to add a callback to #process to the layout_builder_update_block or/and layout_builder_add_block.
Here's a simple example:
Comment #6
tim.plunkettComment #7
chris burge commentedAgreed it should be easier.
Another issue is that if a developer wants to alter a block form rendered by Layout Builder, the developer probably also wants to alter the same block form when it's rendered by Block Content. This means duplicate code or extra work for a workaround.
Take a look at Block Form Alter. It provides a
hook_block_type_form_alter()function that modifies block forms rendered by both Block Content and Layout Builder. It also provides ahook_block_plugin_form_alter(), which allows a developer to target block forms by plugin.Comment #8
dave reidI just ran into this today. Agreed it's currently challenging to alter those forms.
Comment #9
chris burge commentedI moved my original sandbox project to Block Form Alter and updated my comment in #7. That said, I would love to deprecate the module in favor of a sane core solution.
Comment #10
philosurfer commented@chris-burge you are a savior ;^)
Comment #11
dave reidHere's a patch which adds hook_layout_builder_inline_block_alter() and hook_layout_builder_inline_block_TYPE_alter(). It needs documentation and tests still.
Comment #12
chris burge commentedIs there any appetite to tackle the larger issue described by #7? I think #11 is a step in the right direction, but it only gets us so far.
Comment #14
maskedjellybeanI'm sorry for asking for help here but since there has already been some discussion of work arounds... Is there any chance anyone could tell me how to add a new field(s) to this form, save the value of the field(s) on submit and then access the field value within the
hook_preprocess_block()? I'm including what I have so far below. My new fields are appearing in the form when configuring a block via Layout Builder. Within_oh_grid_layout_builder_block_submit()I see the correct chosen values being reflected within $form and $form_state.However after submitting the form and configuring the block again, I see the fields are set to their default values, not the ones I've chosen.
Additionally, I cannot access the fields within
hook_preprocess_block(). The new fields are missing from$vars['elements']['#configuration']where I can find the values of the default fields.Thank you for any help.
Comment #15
maskedjellybeanAfter digging into this further I think what I'm trying to do isn't possible yet. Even contrib modules such as Block Class have not found a way to add fields to the block configuration form in Layout Builder based on https://www.drupal.org/project/block_class/issues/2998114 and https://www.drupal.org/project/drupal/issues/3015152 . They're using
hook_form_alter()as well. I notice they're using$form['third_party_settings']instead of trying to add fields to$form['settings']which is the piece of the puzzle I was missing. Regardless this does not yet work in Layout Builder at least not without the patch to core I linked.The fields for the block configuration form are defined in
BlockBase::buildConfigurationForm(). In order to modify the configuration form for all blocks without usinghook_form_alter()the only way I can think would be to override this class entirely, which is maybe not possible and probably not a great idea.Comment #16
tim.plunkettNW for tests
Comment #17
randalv commentedHello there,
I've run into this issue as well. I've applied the solution provided in #4, but this turns the issue into a whole different one sadly.
While running the code below, if we try to add/remove media (or basically interact with the media object at all), it bugs and gives us the following ajax error.
I'm not quite sure where we're going wrong, any help is appreciated!
Our situation:
- Layoutbuilder block with a media reference
- Hide a certain field on the form
- Using hook_event_dispatcher and catching the event via class based EventListeners.
Our code:
Comment #18
maskedjellybeanIf you are trying to add a field and not alter an existing field:
I was able to figure this out but there's way too much code involved to paste here. I would just say to look at the two links I posted here: https://www.drupal.org/project/drupal/issues/3028391#comment-13445067
One is a patch to core. Apply that. Enable the block_class module and then try to replicate what they did to make their CSS Classes field appear on the configuration form in Layout Builder. When you're done you can disable and uninstall block_class, it's just for reference. It's way more difficult than it should be but it is possible. I was able to create a field that allows me to hide and show blocks at certain breakpoints.
Comment #19
randalv commentedHi Maskedjellybean,
Thanks for the reply! Sadly this was not our use case.
We needed to remove a certain field from displaying on the form, but only when this block was used through layoutbuilder.
So it had to be done via a form alter.
Whilst this seemed easy enough at first, our media library completely broke and spew out the error in my comment above.
Comment #22
bradallenfisher commentedis there a way to simply expose the form display when adding the inline-block to the layout builder? I can see it similar to choosing a view mode for how the block should be rendered.
Comment #23
komalk commentedI have run a test case for 9.2.x in #11
Comment #24
himerus commentedJust running into this issue today, and having issues with what should be incredibly simple Form API tasks:
I'll have a workaround today I believe based on the above noted solutions, but when using a block type, 'canvas' in my current case, form modifications should apply the same if it is being added as an inline block_content block, or added as a reusable block at block/add/BUNDLE.
Comment #26
phjouI just had to do the same tweak. Using #process is working pretty well, but I wanted to add a #validate and it seems not possible to do that inside a #process. So I am not really sure how to solve that issue.
Comment #27
claudiu.cristeaThe problem, I think, is that there's no way to alter the plugin form before it's injected as sub-form. That would guarantee that any form embedding the sub-form would receive the same altered sub-form. For instance, if you alter the block settings in this way
hook_form_block_form_alter(), only BlockForm will benefit for alterations. A block placed with Layout Builder will have to duplicate the code in its own alter callback, and so on.There must be a way to alter the plugin config form itself. And this is not a Layout Builder, or Block modules issue. It's not even a block plugin issue. I think this should be fixed at
PluginFormInterfacelevel.Comment #28
sundarcreosen commentedI have a requirement for coming up with a Video block by topic functionality.
As a content editor,
I need to place a block on any page, listing videos that are tagged with a certain topic.
And, I need to be able to choose a different topic each time I place a block.
And I need the ability to place multiple of these blocks on the same page.
When a content editor is logged on and on a landing page node, he should be able to click "Layout" and click "Add block" in the desired section. And select the Video Gallery by topic. And select a topic and click "Add block". And click Save Layout. Now, the listing should be available in page/videos url.
Here the topic indicates a taxonomy term. The primary requirement is ability to select a topic at the time of block placement. And, only links are links to the video nodes.
I tried the above functionality with Layout builder module with hook form alter custom code. But it shows different form id each time the block is added. So, I tried with "Block form alter" contributed module and in this approach form id is default. I tried with following hooks: hook_block_plugin_form_alter(), hook_block_type_form_alter().
Got an idea to override the form with the hook provided by the contributed module. But when I try to add the form id which i got after enabling the module, it doesn’t allow to select the block. And, I am not able to add the blocks further. Anybody tried similar feature or functionality. Any help is much appreciated.
Comment #32
alt.dev commentedPatch #11 works great to me so I created the MR with this patch and also added hooks declarations to the layout_builder.api.php file.
Comment #33
anybody@maskedjellybean as of your comments #7, #11, #12, #16 and #27 I'd suggest the following:
What do the others think?
Comment #35
grevil commentedJust ran into this at #3117170: Make fences available for all block types in layout builder and agree with @Anybody at #33 that this needs a plan, presumably by a core expert / maintainer to tell us how / what to do.
This is an important decision and the missing functionality is a blocker for third-party, making such alterations a lot more complex than it's typical for Drupal!
Comment #38
guardiola86 commentedI tried using Block Class module and didn't work for me. My issue was that I couldn't use the same validate and submit functions that were working in the block edit page, but not when using layout builder. I ended up using something like this:
Comment #39
apotek commentedIncredibly, Dave's now six years old patch from comment #11 still applies cleanly to 11.2.4 and continues to fix the issue.
Comment #41
igorgoncalves commented+1 to say that #11 still works well for Drupal 11.2.10
i will left below an example of what works for me, just in case someone else falls here and maybe take this as a shortcut instead of read this long thread ;)
after apply the #11 patch
my_module/src/Hook/Hooks.phpIn my case i had a block type hero, with a "hero_items" paragraph (with ulimited number of values), and another paragraph inside called "manual_hero".
our goal it was to handle manual_hero fields as: make the field_image required, and hide field_icon and field_body only for certain cases when user was editing by LB