The Block Example has Example: empty block which is not rendered when placed into a region. Would be it useful to demonstrate how to fill it with the content in the block_example_block_view_alter().

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

drugan created an issue. See original summary.

drugan’s picture

drugan’s picture

Status: Active » Needs review
FileSize
2.75 KB

Another method of extending/adding content to any block. No additional pre_render callbacks, no need to individually extend each of the block definition class. All the magic happens in a HOOK_block_view_alter().

Status: Needs review » Needs work

The last submitted patch, 3: block_example-2893964-3.patch, failed testing. View results

drugan’s picture

Status: Needs work » Needs review
FileSize
4.05 KB

Test file is updated.

Status: Needs review » Needs work

The last submitted patch, 5: block_example-2893964-4.patch, failed testing. View results

drugan’s picture

Status: Needs work » Needs review
FileSize
3.88 KB

One more attempt.

Mile23’s picture

Title: Programmatically add content to the example empty block » Programmatically add content to the example block
Status: Needs review » Needs work

Thanks!

This is a fake-out of BlockViewBuilder::preRender(), and not the block API. Specifically this line of code:

$content = $build['#block']->getPlugin()->build();

Unfortunately BlockViewBuilder::preRender() doesn't have @param documentation, so we can't even rely on that.

So therefore this technique is rather brittle, because all it would take is a minor refactoring with param type hinting to break it. I bet that if the render system didn't need BlockViewBuilder::preRender() to be public, it wouldn't be.

From https://drupal.stackexchange.com/a/241608/4894 it seems like the main advantage to this technique is that you can change the block title. So if you don't need to change the title this is too brittle and you should just use hook_block_view_alter() without the extra class.

If you do need to change the title, then OverrideAnyBlockContent would need to implement Drupal\block\BlockInterface, with stub methods, and also act as a façade for the content being altered in the hook.

Also:

+++ b/block_example/block_example.module
@@ -46,6 +51,22 @@ function block_example_block_view_alter(array &$build, BlockPluginInterface $blo
+    // Uncomment the line below if you need to merge new render array with the
+    // original one.
+    // $render_array += $build['#block']->getPlugin()->build();
+
+    // Now block will be pre-rendered using new render array. No additional
+    // '#pre_render' callback is required.
+    // @see Drupal\block\BlockViewBuilder::preRender()
+    $build['#block'] = new OverrideAnyBlockContent($render_array);

I really don't like that we'd have an 'uncomment this line' type functionality. Since we're making a class, we can have it do all the things we need, like maybe an appendRenderArray() method.

Anyway, regardless of how it's implemented, I'd rather separate it out into another block type that's empty, but will be altered in the hook. That way we have both examples.

vaibhavjain’s picture

@Mile23 Attaching a patch with another approach, where we have another block to depict that the block has been altered. Also, we have implemented hook_block_view_BASE_BLOCK_ID_alter, which would act as another example, rather than adding code in hook_block_view_alter which already existed.
As the approach is a lot different, not adding any interdiff.

vaibhavjain’s picture

Status: Needs work » Needs review

Updating the status.