I created and placed some blocks in my local Drupal 8 Dev site. I exported the full configuration. After I import the configuration into my Staging site I get this error:

This block is broken or missing. You may be missing content or you might need to enable the original module

What do I have to do? And what are best practices for exporting blocks from Dev to Staging and keep Configuration management synced and without errors?

Content blocks are content. Unfortunately, there is currently no mechanism in Drupal core to deploy them.

You'd need something like https://www.drupal.org/project/deploy for that, but that's a pretty big project with a lot of dependencies.

  • So (without using that module) what is best way to do it? On Dev create the blocks, place them and style them? But on Stage and Prod, do I have to make them again? And how do I avoid getting that error? What is the simplest and best way handling content from Dev to Stage in combination with CMI in Drupal 8? This sulation, what does he mean exactly, I don't understand. – meez Apr 23 '16 at 5:05

Another approach for synchronizing content that is added as part of development to test and live environments is to use the Default Content module to export the content. It is built for the content to be exported to an installation profile's 'content' folder, and then the module, if enabled, automatically brings the content in when the site is installed. It is also possible to import the content one item at a time, such as in an update hook, with the below code in your example.install or example.profile:

<?php
/**
* Import a piece of content exported by default content module.
*/
function example_import_default_content($path_to_content_json) {
  list($entity_type_id, $filename) = explode('/', $path_to_content_json);
  $p = drupal_get_path('profile', 'guts');
  $encoded_content = file_get_contents($p . '/content/' . $path_to_content_json);
  $serializer = \Drupal::service('serializer');
  $content = $serializer->decode($encoded_content, 'hal_json');
  global $base_url;
  $url = $base_url . base_path();
  $content['_links']['type']['href'] = str_replace('http://drupal.org/', $url, $content['_links']['type']['href']);
  $contents = $serializer->encode($content, 'hal_json');
  $class = 'Drupal\\' . $entity_type_id . '\Entity\\' . str_replace(' ', '', ucwords(str_replace('_', ' ', $entity_type_id)));
  $entity = $serializer->deserialize($contents, $class, 'hal_json', array('request_method' => 'POST'));
  $entity->enforceIsNew(TRUE);
  $entity->save();
}

Export a custom block with an ID of 8:

drush dcer block_content 8

(If you don't set your profile path in Drush settings you'll have to specify it above.)

And use the resultant export in your example.install file like this:

<?php
/**
* Add the footer block content.
*
* Implements hook_update_N().
*/
function example_update_8001() {
  example_import_default_content('block_content/136efd63-021e-42ea-8202-8b97305cc07f.json');
}

See easily add default content with update hooks for more.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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