Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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']);

share|improve this question

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

$block = 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 rendable array (custom module) by exemple into an controller custom in content() :

public function content() {
    $block = 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,
      );
}

drupal_render is not usefull drupal already assume the render in D8 and this is deprecated (https://api.drupal.org/api/drupal/core!includes!common.inc/function/drupal_render/8)

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.

share|improve this answer

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::entityManager()->
  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 = $block_plugin->access(\Drupal::currentUser());
// Return empty render array if user doesn't have access.
if ($access_result->isForbidden()) {
  // 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::entityManager()
  ->getViewBuilder('block')
  ->view($block);
return $render;
share|improve this answer
    
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 Sep 5 '15 at 12:52
    
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 :) – Berdir Sep 5 '15 at 12:53
    
@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. – googletorp Jan 30 at 10:55
// 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_render($block_content));
share|improve this answer
    
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. – googletorp Jan 30 at 10:59

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_render($block_content));

into something as simple as $output .= drupal_render($block_content); to attach it for example into a page's return variable.

share|improve this answer
    
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. – googletorp Jan 30 at 10:59
    
You're right. This isn't the recommended and most flexible solution. – Leolando Tan Jan 30 at 21:09

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)];
share|improve this answer
    
\Drupal::service ('renderer')->render ($block_content) may be done as drupal_render ($block_content) However the latter is deprecated in Drupal 8. – olegiv Jan 29 at 14:17
    
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 – googletorp Jan 30 at 11:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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