By rashidkhan


2015-09-01 01:01:41 8 Comments

I'm developing a site using Drupal 8 beta-14. I've created a view block of different terms and now I want to display it using code. How can I display it programatically? I used to do it in Drupal 7 using this code but I'm confused about Drupal 8.

$block = module_invoke('block', 'block_view', '4');
$text_block = render($block['content']);

9 comments

@Wasim Khan 2019-03-04 06:45:43

Basically, there are two types of renders.

  1. When there is an existing instance of the block in the layout. the block can be rendered in twig using preprocess as

    $block = Block::load('BLOCK_ID'); $variables['social_links'] = \Drupal::entityTypeManager() ->getViewBuilder('block') ->view($block);

  2. There is no instance or configurations for the block. Then in the preprocessor, we need to create the instance, build the block and then render it

    $block_manager = \Drupal::service('plugin.manager.block'); $config = []; $plugin_block = $block_manager->createInstance('farmjournal_social_sharing', $config); $render = $plugin_block->build(); $variables['farmjournal_social_sharing'] = render($render);

@Taggart Jensen 2018-06-13 04:36:13

Seems this works for plugin blocks ..

$block = \Drupal\block\Entity\Block::load('some_block_id_3');
  $pluin = $block->getPlugin();
  $build = $pluin->build();
  $build['#weight'] = 4;
  $form['block'] = $build;

@Adeel Nawaz 2015-09-01 10:25:36

// You need a block_id! to get it just click configure in the desire block and you'll get url like this /admin/structure/block/manage/bartik_search   the last part of the parameter is the block id
$block = \Drupal\block\Entity\Block::load('bartik_search');
$block_content = \Drupal::entityManager()
  ->getViewBuilder('block')
  ->view($block);

return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));

@googletorp 2016-01-30 10:59:00

If possible, you should avoid using drupal_render or the render service. drupal_render is depricated but returing a render a array with the rendered content is pretty bad, you should return $block_content instead, the render array can be altered before the actual render and you should let Drupal do the rendering as much as posisble instead or doing it your self.

@hugronaphor 2017-09-09 14:41:32

This is going to work only if the block is already placed on the page through block layout.

@woprrr 2015-09-01 09:17:49

For display only your block in your templates with preprocess the best way is

$block = \Drupal\block\Entity\Block::load('my_block_id');
$variables['My_region'] = \Drupal::entityManager()
          ->getViewBuilder('block')
          ->view($block);

And in your page.html.twig or node.html.twig or xxx.html.twig use your variable My_region like this :

{% if page.My_region %}
    {{ page.My_region }}
{% endif %}

And in renderable array (custom module) by example into an controller custom in content() :

public function content() {
    $block = \Drupal\block\Entity\Block::load('my_block_id');
    $block_content = \Drupal::entityManager()
      ->getViewBuilder('block')
      ->view($block);

          return array(
        '#type' => 'container',
        '#attributes' => array(
          'class' => array("Myclass"),
        ),
        "element-content" => $block_content,
        '#weight' => 0,
      );
}

Using drupal_render is not useful as Drupal already assume the render in D8 and this is deprecated. You should use \Drupal::service('renderer')->renderRoot() instead.

It's a bit heavy, it is better to use the maximum area system and does not add load block from the preprocess. In the case of using a controller in your modules this seems a justified use.

@Mrweiner 2018-05-24 00:46:25

This controller implementation is exactly what I was looking for. Thanks!

@Eria 2018-06-18 09:52:56

I'm interested in this controller implementation for a similar use case I'm dealing with. But I can't find any documentation about element-content property in a render array. Do you know where it's documented ?

@Arthur Attout 2018-10-08 14:18:43

I don't know why, but \Drupal\block\Entity\Block::load does not return a block all the time. It only returns something if the block I load is placed within the view in block layout. If it's not placed, it returns null.

@Ryan Hartman 2019-08-09 15:08:59

This answer should be updated to use \Drupal::entityTypeManager()->getViewBuilder('block')->view(‌​$block);

@Leolando Tan 2015-09-01 03:46:58

Based on my research, you could base the code from How to render a block programmatically in drupal 8. You could also change

return array('#markup' => \Drupal::service('renderer')->renderRoot($block_content));

into something as simple as:

$output .= \Drupal::service('renderer')->renderRoot($block_content);

to attach it for example into a page's return variable.

@googletorp 2016-01-30 10:59:27

If possible, you should avoid using drupal_render or the render service. drupal_render is depricated but returing a render a array with the rendered content is pretty bad, you should return $block_content instead, the render array can be altered before the actual render and you should let Drupal do the rendering as much as posisble instead or doing it your self.

@Leolando Tan 2016-01-30 21:09:03

You're right. This isn't the recommended and most flexible solution.

@sea26.2 2019-02-09 21:50:46

Your link is dead "How to render a block..."

@googletorp 2015-09-01 08:56:48

There are two types of blocks, and the method for rendering the two is a bit different:

Content Blocks

Content blocks are blocks that you create in the interface. They are much like nodes configurable data structures, with fields etc. If you want to render one of these, you can do what you would normally do with entities, load them and render them with the view builder:

$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;

Plugin blocks

Blocks can also be plugin, defined in various modules. An example could be the breadcrumb block. If you want to render these, you will need to use the block plugin manager.

$block_manager = \Drupal::service('plugin.manager.block');
// You can hard code configuration or you load from settings.
$config = [];
$plugin_block = $block_manager->createInstance('system_breadcrumb_block', $config);
// Some blocks might implement access check.
$access_result = $plugin_block->access(\Drupal::currentUser());
// Return empty render array if user doesn't have access.
// $access_result can be boolean or an AccessResult class
if (is_object($access_result) && $access_result->isForbidden() || is_bool($access_result) && !$access_result) {
  // You might need to add some cache tags/contexts.
  return [];
}
$render = $plugin_block->build();
// In some cases, you need to add the cache tags/context depending on
// the block implemention. As it's possible to add the cache tags and
// contexts in the render method and in ::getCacheTags and 
// ::getCacheContexts methods.
return $render;

Config entities

Shared for the two types are blocks, are that once you insert them into a region, you will create a config entity that has all of the settings for the block. In some cases it will be more useful handling config entities. Since the same block can be place in multiple regions with and with different configuration, it can get more tricky using the block config entities. The nice thing is that you might want to render a block with specific configuration, the bad thing is that config ids can change by messing with the interface, so the code might end up not working after letting users use the block interface.

$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);
return $render;

@Berdir 2015-09-05 12:52:47

The question doesn't specify if it is about rendering a block config entity ( a pre-configured block placement) or a block plugin with hardcoded configuration. Which makes sense because that difference doesn't exist in 7.x. This is more flexible because the other actually a requires a specific block that needs to be placed in a given theme and region. However, you should never create them by hand. Use the block plugin manager's createInstance() method for that with the plugin ID, where you can also provide a $configuration array...

@Berdir 2015-09-05 12:53:02

Also, you might want to consider calling the access() method first in case block access is restricted to e.g. a certain permission by that block. Can you improve your answer a bit on that? Can become a useful resource then :)

@googletorp 2016-01-30 10:55:12

@Berdir It's been a while, but I finally got around to improving the answer. With all the various caching going on, using the plugin directly is probably only useful in limited situations.

@joachim 2016-04-26 08:21:04

The downside with using the block plugin manager createInstance() is that the resulting render array isn't run through block theming, so you can't use the block--blockname.twig.html, for instance. The alternative is to create a block for your theme, but leave it disabled, and then in your code do: ``` $block = \Drupal\block\Entity\Block::load('myblock'); $build = \Drupal::entityManager()->getViewBuilder('block')->view($blo‌​ck); ```

@sea26.2 2019-02-09 21:47:39

Nope - Another rabbit hole. The code for the content block white screens (with the infamous "The website encountered an unexpected error. Please try again later.") The second gets closer - But displays a cryptic message about the block being missing or something... (which isn't true because I'm attempting a system block - the powered by drupal thing).

@Eugene 2016-04-03 12:38:49

I needed to get the HTML of a custom block and got it using:

$con = \Drupal\block\BlockViewBuilder::lazyBuilder('bartik_search', 'full');
$d   = \Drupal::service('renderer')->renderPlain($con);

print $d->__toString();

@leymannx 2016-11-15 12:32:51

I needed to add it to a render array and there it worked without __toString().

@leymannx 2016-12-21 09:07:21

Important to mention that a block at least needs to be placed in "Disabled blocks" region. Or any other active region.

@CliveCleaves 2017-01-10 12:28:57

In addition to the top answer... If you want to render a block from a view, you may have to do things a little differently.

$view = views_embed_view('my_view_name', 'my_display_name');

(display name eg -> block_1)

Since we're going to pass it to twig, we don't need to render (using render service).

So you can just pass it as a variable to twig (for this example, its the return of a Controller):

return [
  ['description' => [
    '#theme' => 'your_theme_hook',
    '#your_variable => $view
  ]
]

in your module you need a hook_theme() for your variable:

function hook_theme($existing, $type, $theme, $path) {
  return array(
    'your_theme_hook' => array(
      'variables' => [
        'your_variable' => NULL,
      ]
    )
  )
}

And finally in your twig template:

{{ your_variable }}

@olegiv 2016-01-29 12:36:32

You get block output:

$block = \Drupal\block\Entity\Block::load ('my_bock_id');
$block_content = \Drupal::entityManager ()->
  getViewBuilder ('block')->
  view ($block);

And then you may return output in different ways:

return array (
    '#type' => 'container',
    'element-content' => $block_content
);

or:

return ['#markup' => \Drupal::service ('renderer')->render ($block_content)];

@olegiv 2016-01-29 14:17:46

\Drupal::service ('renderer')->render ($block_content) may be done as drupal_render ($block_content) However the latter is deprecated in Drupal 8.

@googletorp 2016-01-30 11:01:32

If possible, you should avoid using drupal_render or the render service. drupal_render is depricated but returing a render a array with the rendered content is pretty bad, you should return $block_content instead, the render array can be altered before the actual render and you should let Drupal do the rendering as much as posisble instead or doing it your self. What you returns needs to be rendered again, which makes the actual rendering pointless

Related Questions

Sponsored Content

2 Answered Questions

[SOLVED] How to show webform as block

  • 2018-02-01 05:54:20
  • Alireza Tabatabaeian
  • 5836 View
  • 4 Score
  • 2 Answer
  • Tags:   8 blocks webforms

1 Answered Questions

Taxonomy-term based block display

1 Answered Questions

[SOLVED] How to change bean's block view mode programmatically?

  • 2015-03-18 14:35:43
  • Ahmad
  • 406 View
  • 0 Score
  • 1 Answer
  • Tags:   7 blocks

2 Answered Questions

[SOLVED] Programmatically change block content on page render only

  • 2018-08-09 17:16:31
  • user1359
  • 876 View
  • 0 Score
  • 2 Answer
  • Tags:   8 blocks

2 Answered Questions

[SOLVED] How can I display the block only to the content types and a specific page?

  • 2018-01-12 18:01:13
  • learn4ever
  • 553 View
  • 2 Score
  • 2 Answer
  • Tags:   7 blocks

2 Answered Questions

[SOLVED] Add block with taxonomy terms in intergrated View Taxonomy term

1 Answered Questions

[SOLVED] how to insert a block within a cck input form in Drupal 7?

  • 2012-04-25 20:02:50
  • Drupal Developer
  • 625 View
  • 0 Score
  • 1 Answer
  • Tags:   7 entities blocks

2 Answered Questions

[SOLVED] How can I set variables only once per block?

  • 2011-10-28 03:38:09
  • George
  • 290 View
  • 1 Score
  • 2 Answer
  • Tags:   7 blocks

Sponsored Content