I have a custom content type. Upon creating a new node for that content type, I'd like to create a new vocabulary with a custom taxonomy reference field. I have created the code below which does it all, except the field is never shown in the UI form when adding new terms into the newly-created taxonomy. Otherwise, everything seems to be in order - the field is created, it has the correct type, name and everything else.
I tried to manually create a field of the same type and it does indeed show in the term adding form. I also tried to clear caches and reposition this field in the UI manually and save it - nothing works.
function mymodule_entity_insert(\Drupal\Core\Entity\EntityInterface $entity) {
// create top and bottom menu vocabularies if we have
if ( $entity->bundle() == "section" ) {
/***
* Top menu vocabulary
*/
$vocabulary_id = $entity->id() . '_top_menu';
$vocabulary_name = t( '@entity_name Top Menu', [ '@entity_name' => $entity->label() ] );
Vocabulary::create([
'vid' => $vocabulary_id,
'name' => $vocabulary_name,
])->save();
// Define the field name and settings
$field_name = 'field_parent_entity_reference';
$entity_type = 'taxonomy_term';
$bundle = $vocabulary_id;
// Check if the field storage exists
if (!$field_storage = FieldStorageConfig::loadByName($entity_type, $field_name)) {
// Create the field storage definition
$field_storage = FieldStorageConfig::create([
'field_name' => $field_name,
'entity_type' => $entity_type,
'type' => 'entity_reference',
'settings' => [
'target_type' => 'node',
],
'cardinality' => 1, // Set to -1 for unlimited.
'provider' => 'field_create',
]);
$field_storage->save();
}
// Check if the field configuration exists
if (!FieldConfig::loadByName($entity_type, $bundle, $field_name)) {
// Create the field instance for the vocabulary bundle
FieldConfig::create([
'field_name' => $field_name,
'entity_type' => $entity_type,
'field_storage' => $field_storage,
'bundle' => $bundle,
'label' => t('Content to show'),
'settings' => [
'handler' => 'default',
'handler_settings' => [
'target_bundles' => [
// Limit to specific content types
'announcement' => 'announcement',
'section' => 'section',
'page' => 'page',
'event' => 'event',
'article' => 'article',
],
],
],
])->save();
}
// Load the form display for the vocabulary
$form_display = EntityFormDisplay::load('taxonomy_term.' . $bundle . '.default');
if (!$form_display) {
$form_display = EntityFormDisplay::create([
'targetEntityType' => 'taxonomy_term',
'bundle' => $bundle,
'mode' => 'default',
]);
}
// Add the field to the form display
$form_display->setComponent($field_name, [
'type' => 'entity_reference_autocomplete', // Field widget type
'weight' => 50,
])->save();
// Load the view display for the vocabulary
$view_display = EntityViewDisplay::load('taxonomy_term.' . $bundle . '.default');
if (!$view_display) {
$view_display = EntityViewDisplay::create([
'targetEntityType' => 'taxonomy_term',
'bundle' => $bundle,
'mode' => 'default',
]);
}
// Add the field to the view display
$view_display->setComponent($field_name, [
'label' => 'above', // Show the label above the field
'type' => 'entity_reference_label', // Field formatter
'weight' => 50,
])->save();
\Drupal::logger('activit')->info('Form display updated for field: @field', ['@field' => $field_name]);
\Drupal::service('cache.entity')->invalidateAll();
drupal_flush_all_caches();
$vocabulary = Vocabulary::load($vocabulary_id);
$field = FieldConfig::loadByName('taxonomy_term', $bundle, $field_name);
\Drupal::logger('activit')->info('Vocabulary: @vocab, Field: @field', [
'@vocab' => $vocabulary ? $vocabulary->id() : 'Not Found',
'@field' => $field ? $field->id() : 'Not Found',
]);
$term = \Drupal\taxonomy\Entity\Term::create([
'vid' => $vocabulary_id,
'name' => 'Test Term',
]);
$term->save();
$loaded_term = \Drupal\taxonomy\Entity\Term::load($term->id());
\Drupal::logger('custom_module')->info('Field Value: @value', [
'@value' => $loaded_term->get($field_name)->value ?? 'Empty',
]);
}
}
I was missing status part in the EntityFormDisplay::create
function. Here is the corrected code part:
// Load the form display for the vocabulary
$form_display = EntityFormDisplay::load('taxonomy_term.' . $bundle . '.default');
if (!$form_display) {
$form_display = EntityFormDisplay::create([
'targetEntityType' => 'taxonomy_term',
'bundle' => $bundle,
'mode' => 'default',
'status' => TRUE,
]);
}