Creating content blocks programmatically in Drupal 8

Let's picture this: you've created a custom content block type (let's say, Ad block) in your shiny new Drupal 8 installation and you want to automaticaly create a fresh new block of that type each time you create a taxonomy term (Ad group), so that every ad group has a corresponding ad block.

How do I do that? Simple! Follow the white rabbit me:

  1. We add the entity_insert hook and catch our taxonomy term insert event:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    1. <?php
    2. /**
    3. * Implements hook_entity_insert().
    4. */
    5. function pabc_ads_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
    6. // Catching a term that belongs to the ad_group vocabulary.
    7. if ($entity->getEntityTypeId() == 'taxonomy_term' && $entity->bundle() == 'ad_groups') {
    8. }
    9. }
  2. Next we create our block via EntityManager Drupal service:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    1. <?php
    2. // Grab a block entity manager from EntityManager service
    3. $blockEntityManager = \Drupal::service('entity.manager')
    4. ->getStorage('block_content');
    5. // Tell block entity manager to create a block of type "ad_block"
    6. $block = $blockEntityManager->create(array(
    7. 'type' => 'ad_block'
    8. ));
    9. // Every block should have a description, but strangely it's property
    10. // is not 'description' but 'info'
    11. // in my case, I want it to be equal to my ad_group's term name.
    12. $block->info = $entity->name->value;
    13. // This is optional part, my ad_block has a field field_ad_group
    14. // which is a taxonomy reference to the ad_group taxonomy,
    15. // that way I link ad_group and ad_block together.
    16. $block->field_ad_group = $entity;
    17. // In the end, save our new block.
    18. $block->save();
  3. So in the end you code snippet should look like this:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    1. <?php
    2. /**
    3. * Implements hook_entity_insert().
    4. */
    5. function pabc_ads_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
    6. // Catching a term that belongs to the ad_group vocabulary.
    7. if ($entity->getEntityTypeId() == 'taxonomy_term' && $entity->bundle() == 'ad_groups') {
    8. // Grab a block entity manager from EntityManager service
    9. $blockEntityManager = \Drupal::service('entity.manager')
    10. ->getStorage('block_content');
    11. // Tell block entity manager to create a block of type "ad_block"
    12. $block = $blockEntityManager->create(array(
    13. 'type' => 'ad_block'
    14. ));
    15. // Every block should have a description, but strangely it's property
    16. // is not 'description' but 'info'
    17. // in my case, I want it to be equal to my ad_group's term name.
    18. $block->info = $entity->name->value;
    19. // This is optional part, my ad_block has a field field_ad_group
    20. // which is a taxonomy reference to the ad_group taxonomy,
    21. // that way I link ad_group and ad_block together.
    22. $block->field_ad_group = $entity;
    23. // In the end, save our new block.
    24. $block->save();
    25. }
    26. }

As you see, creating content blocks in Drupal 8 is pretty similar to creating any other type of entity (node or taxonomy), you just need to figure out a correct service to do that and check what fields should be filled in.