Create content blocks programatically in Drupal 8

This article was originally posted at Medium

Drupal 8 comes with a concept named content blocks (also referred as custom blocks in the blocks library). These are block types that you can adjust to your needs and then create blocks based on those types. Every block is an entity. It's (almost) very useful if you want to create a block to place it somewhere on your site since you can do it totally through the Drupal interface. However; if you want (and probably you should) to keep everything in code; using this kind of blocks maybe is not the easiest solution. Gratefully; there's a workaround for this. For our example; let's create a block of type basic (the one included with standard profile) and place it in a page using page manager + panels. When you do that and export the configuration; you get in a file named like page_manager.page_variant.about_me-panels-variant-0.yml a piece of yml like this:

content:
 — 'block_content:basic:63b2b79d-97b6–482e-bb19-e4df520cde13'

and somewhere else in the same file; another piece of code like this:

variant_settings:
  blocks:
    5cd2a331-a468–45f6-b0be-c97737a68698:
      id: 'block_content:63b2b79d-97b6–482e-bb19-e4df520cde13'
      label: 'About Me Block'
      provider: block_content
      label_display: '0' 
      status: true
      info: ''
      view_mode: full
      region: middle
      weight: 0
      uuid: 5cd2a331-a468–45f6-b0be-c97737a68698
      context_mapping: { }

The important pieces here are the block bundle (basic), the block uuid ( 63b2b79d-97b6–482e-bb19-e4df520cde13) and the block id (block_content:basic:63b2b79d-97b6–482e-bb19-e4df520cde13); so; in order to create a block programatically that fits in that space; we should do something like this:

// Get entity manager.
 $block_entity_manager = \Drupal::service('entity.manager')->getStorage('block_content');
 // About Me Block.
 $block = $block_entity_manager->create(array(
 'type' => 'basic',
 'id' => 'block_content:basic:63b2b79d-97b6–482e-bb19-e4df520cde13',
 'label' => 'About Me Block',
 'uuid' => '63b2b79d-97b6–482e-bb19-e4df520cde13',
 )); 
 $block->info = 'About Me Block';
 $block->body->format = 'basic_html';
 $block->body->value = 'Some lorem ipsum text here';
 $block->save();

That piece of code could be added to a hook_install or hook_update_N and the block will be created and automatically placed where it should be according to the exported configuration. Be sure to remove the manually created block before testing this code; otherwise, Drupal will complain for a duplicated id.

With this way to do this; you create the block programatically and ensure it's there when you enable/update the module and also you could edit it through Drupal interface without overriding nothing in the configuration.

I hope this to be useful,

Submitted by kporras07 on