3

I'm attempting to render a custom content block programmatically (created through the Custom Block Library UI) and I would like the block to render using block.html.twig as it would if I were to place it in a theme region. I have the block placed in a disabled region and I can get the block body field to render programmatically, but it is not wrapped in the usual block template and does not include the block title. I'm using the code to render a "content block" from the accepted answer here: How can I programmatically display a block?

$bid = ??? // Get the block id through config, SQL or some other means
$block = \Drupal\block_content\Entity\BlockContent::load($bid);
$render = \Drupal::entityTypeManager()->
getViewBuilder('block_content')->view($block);
return $render;

As I understand it, I need to render the instance of the custom block that I have placed inside the disabled region, so I would expect that I have to use the machine name of that instance. I've done a lot of searching and come up with nothing. It's strange that nobody else seems to want to render the block with the title in the block.html.twig template.

2
  • What template would the block right now be rendered with?
    – leymannx
    Aug 8, 2018 at 5:56
  • It renders using field--text-with-summary.html.twig. Aug 8, 2018 at 18:02

2 Answers 2

8

BlockContent is the only entity in Drupal not having a template of its own. So you have to wrap it in a template yourself:

$block = \Drupal\block_content\Entity\BlockContent::load($bid);
if ($block) {
  $content = \Drupal::entityTypeManager()->getViewBuilder('block_content')->view($block);
  $build = [
    '#theme' => 'block',
    '#attributes' => [],
    '#configuration' => ['label' => 'My Block', 'label_display' => 'visible'],
    '#base_plugin_id' => 'block_content',
    '#plugin_id' => 'block_content:' . $block->uuid(),
    '#derivative_plugin_id' => $block->uuid(),
    '#id' => $block->id(),
    'content' => $content,
  ];
  return $build;
}
4
  • Thank you. This does render the block in the block.html.twig template. It doesn't however use the block title/label configured in the instance of the block I placed in the disabled region. I'm certain there must be a way to do this because it seems like a simple task. Somehow Drupal core is doing the same thing when it renders a custom block inside of a region. Aug 8, 2018 at 18:01
  • Since you've asked a code only question I've responded with the code you need to fulfill the task "render a custom block using block html twig template". When Drupal renders a block you've placed in the block layout it does the same, Twig Tweak probably as well. This is the basic usage of twig templates, they are invoked by building a render array with #theme. And when you want a block template you have to use '#theme' => 'block', directly in your own code or via other code you've found in contrib. You can fill #configuration with the settings of a configured block if you want.
    – 4uk4
    Aug 9, 2018 at 9:17
  • Thank you for the response! That's fair, I didn't mention the desire to render the configured title in the question title so as not to make too lengthy. Aug 9, 2018 at 18:18
  • Yes, and your assumption "As I understand it, I need to render the instance of the custom block that I have placed inside the disabled region", is not the case, you don't need to do this only to store the label to retrieve it later to put it in the block template. A configured block is mainly used to place a block in a theme and region.
    – 4uk4
    Aug 9, 2018 at 18:23
3

Ok, I was hoping for an answer that didn't involve installing a module because this seems like a simple task, but after some point you just have to give in. The Twig Tweak module can do what I'm asking very easily. After installing, in a template where you want to render the block, add this:

{{ drupal_entity('block', 'BLOCK_CONFIG_MACHINE_NAME') }}

where BLOCK_CONFIG_MACHINE_NAME is the machine name of the block you have configured at /admin/structure/block/

This will render the block using block.html.twig and will render the title you have configured.

Documentation: https://www.drupal.org/docs/8/modules/twig-tweak/rendering-blocks-with-twig-tweak

4
  • 2
    Twig Tweak probably isn't the worst. Can even imagine it in core some day.
    – leymannx
    Aug 8, 2018 at 18:20
  • 1
    I ended up running into this issue again and found my own thread here. I also found that there is actually an open core issue about this on Drupal.org: drupal.org/project/drupal/issues/2704331 Dec 13, 2019 at 18:55
  • 1
    I would consider making twig_tweak a standard tool in you site configuration. My opinion is that twig_tweak is one of the most useful contrib modules available for Drupal 8.
    – Beau
    Jan 27, 2020 at 18:19
  • I agree with you both that Twig Tweak is great. However I'm doubtful it will ever become part of core. Drupal 9 is deprecating functions that are wrappers around object oriented code. It seems to me that because a contrib module like Twig Tweak introduces wrapper functions which make our lives easier, it will never become part of core. I'm all for object oriented, but we shouldn't need to write 5+ lines of code to render a block with the proper template unless we choose to do it that way. Oh well. Jan 27, 2020 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.