Make Block View Lazy Building Optional

Created on 20 July 2016, about 8 years ago
Updated 30 August 2023, about 1 year ago

Problem/Motivation

When creating a block, that block is required to have a presence in the database when creating a view (short of two notable exceptions, which I'll come back to) due to the way lazy building operates.

My use case is this: I'm extending the Insert Block module β†’ to create short codes the will render block_content entities as blocks inline. To do this I need to actually generate a block (so that I get all of the lovely templating hooked in) which can easily be done in memory using something like $block = \Drupal::service('entity.manager')->getStorage('block')->create($config);

From there I move to generate the view of the block using $block_view = \Drupal::service('entity.manager')->getViewBuilder('block')->view($block);. Provided my $config variable had all the relevant settings correct, I get a renderable array.

Unfortunately the array does not render. The BlockViewBuilder::viewMultiple() function by default adds a lazyBuilder instead of a renderable array of content. The lazyBuilder then tries to load the content using entity_load(), which of course comes up empty because the block only exists in memory. The only two exceptions are blocks of the plugin MainContentBlockPluginInterface and TitleBlockPluginInterface which are immediately given pre-renderable blocks.

This issue is compounded by the fact that BlockViewBuilder::buildPreRenderableBlock(), the function that creates the renderable block array, is protected in the class. It is certainly possible to generate this renderable array outside of the function, but it's additional code that may not stay up to date with changes in how blocks are rendered.

Proposed resolution

I suggest that lazyBuildability should not be determined by the class of the block plugin. Instead I suggest there be more than one way to prevent a block being lazyBuilt:

  • Entire classes that need to skip the process such as those already in use should be able to set a lazyBuild property, defined (and override-able) from BlockBase. This makes new block definitions able to allow themselves to opt out of lazyBuilding if needed and makes the whole situation that much more extensible.
  • Block entities should be able to pass properties allowing them to opt out of lazyBuilding.
  • I don't like the additional DB request overhead of that so I don't think it's a viable option (defeats most of the purpose of lazyBuilding), but if there is genuine interest in being able to build blocks stored only in memory, then this may be a good choice.

Remaining tasks

Code needs review and perhaps discussion.

API changes

This does introduce a skip_lazy_build block entity property that goes largely undocumented. Unsure if this needs to be introduced into the block entity model properly or even stored in the configuration.

✨ Feature request
Status

Postponed: needs info

Version

11.0 πŸ”₯

Component
BlockΒ  β†’

Last updated 3 days ago

Created by

πŸ‡ΊπŸ‡ΈUnited States dhansen

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024