To be honest, not sure of a good title for this. This is the issue:
I am using the TOC API to create a block. This API requires parsing the node content to determine the heading structure (H2s, H3s, etc). The module does not include a block for this as it is just an API module. I wrote a custom block to use the API to create this block. This works fine.
I now have a use case where I need to put multiple versions of this block on the page, but I am only able to render one of them. This has nothing to do with the TOC API but how the node content is rendered in the block code. I have simplified the code to remove all the API parts:
public function build() {
// Required to break block - render page - insert block - render page, etc, etc.
$rendered = &drupal_static('toc_block_rendered');
if (isset($rendered) && in_array($this->configuration['toc_type'], $rendered)) return [];
else $rendered[] = $this->configuration['toc_type'];
$build = [];
// Get TOC Type configured for this Block.
$toc_type_id = $this->configuration['toc_type'];
$node = \Drupal::routeMatch()->getParameter('node');
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
$full_content = $view_builder->view($node, 'full');
$content = (string) \Drupal::service('renderer')->render($full_content);
return ['#markup' => $this->configuration['toc_type']];
}
$this->configuration['toc_type'] is a configuration value set for the block instance and is set differently for each of the 2 blocks I have placed on the page.
The static var code at the top is required to break the recursive loop caused due to trying to render the page which has the block which tries to render the page which has the block.. and so on and so on.
This simplified block just renders the block's config value. Although 2 of them are added to the node layout; only one gets shown. If I comment out the $view_builder->view($node, 'full') line; then both are displayed correctly.
I have tried multiple approaches such as static and even session vars for the rendered content; but with no luck. I also tried cloning or createDuplicate() of the node but this also does not help.
Can anyone explain why this is being broken by running this code for a 2nd instance of the block and if there is a better way to do this?
NOTE: the session var idea does work but the code I had for this isn't properly seeded the first time through. The 2nd refresh of the page shows both blocks. I would need a way to set for the first time and then also to clear these in a later hook (hook_node_view). But ugly approach.