I had the same issue and I hope I have resolved it.
Your algorithm is next:
- Create your own module
- Create file <your_module>.install
- There must be at least one hook
hook_install
(I have used two: hook_install
and hook_uninstall
)
- Inside install hook:
- create a new block type
- create fieldStorageConfig
- create fieldConfig
- set component for form and view display
My code:
<?php
use Drupal\block_content\Entity\BlockContentType;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
function <your_module_name>_install() {
$newBlockType = BlockContentType::create([
'id' => <your_id>,
'label' => 'Custom block type',
'description' => "A custom block type",
]);
$newBlockType->save();
$blockId = $newBlockType->id();
block_content_add_field($blockId, 'Icon', 'custom_block_icon', 'image', 'image', 'image_image');
block_content_add_field($blockId, 'Count', 'custom_block_count', 'integer', 'number_integer', 'number');
block_content_add_field($blockId, 'Description', 'custom_block_description', 'text', 'text_default', 'text_textfield');
}
function block_content_add_field(
$blockTypeId,
$label,
$componentName,
$fieldStorageType,
$viewDisplayType = 'text_default',
$formDisplayType = 'text_textarea_with_summary') {
// Add or remove the body field, as needed.
$field = FieldConfig::loadByName('block_content', $blockTypeId, $componentName);
if (empty($field)) {
$fieldStorage = FieldStorageConfig::loadByName('block_content', $componentName);
if (empty($fieldStorage)) {
$fieldStorage = FieldStorageConfig::create([
'field_name' => $componentName,
'entity_type' => 'block_content',
'type' => $fieldStorageType,
]);
$fieldStorage->save();
}
$field = FieldConfig::create([
'field_storage' => $fieldStorage,
'bundle' => $blockTypeId,
'label' => $label,
'settings' => ['display_summary' => FALSE],
]);
$field->save();
/** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
$display_repository = \Drupal::service('entity_display.repository');
// Assign widget settings for the default form mode.
$display_repository->getFormDisplay('block_content', $blockTypeId)
->setComponent($componentName, [
'type' => $formDisplayType,
])
->save();
// Assign display settings for default view mode.
$display_repository->getViewDisplay('block_content', $blockTypeId)
->setComponent($componentName, [
'label' => 'hidden',
'type' => $viewDisplayType,
])
->save();
}
return $field;
}
Result: the new custom block type with 3 fields.
Block
plugin. There are a ton of guides how to do that, here's one. valuebound.com/resources/blog/…