From d418da3968bd5959bece259103822fbd6d16bfac Mon Sep 17 00:00:00 2001 From: Lauri Eskola <lauri.eskola@acquia.com> Date: Thu, 24 Aug 2023 14:21:50 +0300 Subject: [PATCH] Issue #3372092 by srishtiiee, lauriii, larowlan, tim.plunkett, kunal.sachdev, Wim Leers: Allow field_type_categories.yml entries to define asset libraries --- .../Core/Field/FallbackFieldTypeCategory.php | 7 ++- .../Drupal/Core/Field/FieldTypeCategory.php | 7 +++ .../Core/Field/FieldTypeCategoryInterface.php | 8 +++ .../Core/Field/FieldTypeCategoryManager.php | 4 ++ core/modules/comment/comment.module | 11 +++- .../datetime_range/datetime_range.module | 11 +++- ...eld_plugins_test.field_type_categories.yml | 2 + .../Kernel/FieldTypeCategoryDiscoveryTest.php | 2 + .../field_ui/src/Form/FieldStorageAddForm.php | 7 ++- .../FieldTypeCategoriesIntegrationTest.php | 60 +++++++++++++++++++ .../file/file.field_type_categories.yml | 2 + core/modules/file/file.module | 7 --- core/modules/link/link.module | 11 +++- core/modules/media/media.module | 10 +++- .../options/options.field_type_categories.yml | 2 + core/modules/options/options.module | 7 --- core/modules/telephone/telephone.module | 11 +++- .../text/text.field_type_categories.yml | 2 + core/modules/text/text.module | 7 --- 19 files changed, 138 insertions(+), 40 deletions(-) create mode 100644 core/modules/field_ui/tests/src/Functional/FieldTypeCategoriesIntegrationTest.php diff --git a/core/lib/Drupal/Core/Field/FallbackFieldTypeCategory.php b/core/lib/Drupal/Core/Field/FallbackFieldTypeCategory.php index 1a83aa073740..d8319d28d501 100644 --- a/core/lib/Drupal/Core/Field/FallbackFieldTypeCategory.php +++ b/core/lib/Drupal/Core/Field/FallbackFieldTypeCategory.php @@ -10,13 +10,14 @@ class FallbackFieldTypeCategory extends FieldTypeCategory { /** * {@inheritdoc} */ - public function __construct(array $configuration) { + public function __construct(array $configuration, string $plugin_id, array $plugin_definition) { + $plugin_id = $configuration['unique_identifier']; $plugin_definition = [ 'label' => $configuration['label'] ?? '', 'description' => $configuration['description'] ?? '', 'weight' => $configuration['weight'] ?? 0, - ]; - parent::__construct($configuration, $configuration['unique_identifier'], $plugin_definition); + ] + $plugin_definition; + parent::__construct($configuration, $plugin_id, $plugin_definition); } } diff --git a/core/lib/Drupal/Core/Field/FieldTypeCategory.php b/core/lib/Drupal/Core/Field/FieldTypeCategory.php index ac04b5124947..168616102e1b 100644 --- a/core/lib/Drupal/Core/Field/FieldTypeCategory.php +++ b/core/lib/Drupal/Core/Field/FieldTypeCategory.php @@ -33,4 +33,11 @@ public function getWeight(): int { return $this->pluginDefinition['weight']; } + /** + * {@inheritdoc} + */ + public function getLibraries(): array { + return $this->pluginDefinition['libraries'] ?? []; + } + } diff --git a/core/lib/Drupal/Core/Field/FieldTypeCategoryInterface.php b/core/lib/Drupal/Core/Field/FieldTypeCategoryInterface.php index e9a1a0d21a85..3727df1bb778 100644 --- a/core/lib/Drupal/Core/Field/FieldTypeCategoryInterface.php +++ b/core/lib/Drupal/Core/Field/FieldTypeCategoryInterface.php @@ -33,4 +33,12 @@ public function getDescription(): TranslatableMarkup; */ public function getWeight(): int; + /** + * Returns asset libraries for the field group. + * + * @return array + * The asset libraries to attach. + */ + public function getLibraries(): array; + } diff --git a/core/lib/Drupal/Core/Field/FieldTypeCategoryManager.php b/core/lib/Drupal/Core/Field/FieldTypeCategoryManager.php index 29efa654063d..7155545030b4 100644 --- a/core/lib/Drupal/Core/Field/FieldTypeCategoryManager.php +++ b/core/lib/Drupal/Core/Field/FieldTypeCategoryManager.php @@ -19,6 +19,8 @@ * label: STRING * description: STRING * weight: INTEGER + * libraries: + * - STRING * @endcode * For example: * @code @@ -26,6 +28,8 @@ * label: Text * description: Text fields. * weight: 2 + * libraries: + * - module_name/library_name * @endcode * * @see \Drupal\Core\Field\FieldTypeCategoryInterface diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 8caa332efca4..934f0bdbe2ff 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -16,6 +16,7 @@ use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\Core\Entity\Entity\EntityViewMode; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Field\FieldTypeCategoryManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; @@ -785,8 +786,12 @@ function comment_entity_view_display_presave(EntityViewDisplayInterface $display } /** - * Implements hook_preprocess_form_element__new_storage_type(). + * Implements hook_field_type_category_info_alter(). */ -function comment_preprocess_form_element__new_storage_type(&$variables) { - $variables['#attached']['library'][] = 'comment/drupal.comment-icon'; +function comment_field_type_category_info_alter(&$definitions) { + // TRICKY: the `comment` field type belongs in the `general` category, so the + // libraries need to be attached using an alter hook. + if (array_key_exists(FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY, $definitions)) { + $definitions[FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY]['libraries'][] = 'comment/drupal.comment-icon'; + } } diff --git a/core/modules/datetime_range/datetime_range.module b/core/modules/datetime_range/datetime_range.module index 65a9e692dff9..37283d67a208 100644 --- a/core/modules/datetime_range/datetime_range.module +++ b/core/modules/datetime_range/datetime_range.module @@ -5,6 +5,7 @@ * Field hooks to implement a datetime field that stores a start and end date. */ +use Drupal\Core\Field\FieldTypeCategoryManagerInterface; use Drupal\Core\Url; use Drupal\Core\Routing\RouteMatchInterface; @@ -29,8 +30,12 @@ function datetime_range_help($route_name, RouteMatchInterface $route_match) { } /** - * Implements hook_preprocess_form_element__new_storage_type(). + * Implements hook_field_type_category_info_alter(). */ -function datetime_range_preprocess_form_element__new_storage_type(&$variables) { - $variables['#attached']['library'][] = 'datetime_range/drupal.datetime_range-icon'; +function datetime_range_field_type_category_info_alter(&$definitions) { + // TRICKY: the `datetime_range` field type belongs in the `general` category, + // so the libraries need to be attached using an alter hook. + if (array_key_exists(FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY, $definitions)) { + $definitions[FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY]['libraries'][] = 'datetime_range/drupal.datetime_range-icon'; + } } diff --git a/core/modules/field/tests/modules/field_plugins_test/field_plugins_test.field_type_categories.yml b/core/modules/field/tests/modules/field_plugins_test/field_plugins_test.field_type_categories.yml index 35b725c68630..fe3b94f826fe 100644 --- a/core/modules/field/tests/modules/field_plugins_test/field_plugins_test.field_type_categories.yml +++ b/core/modules/field/tests/modules/field_plugins_test/field_plugins_test.field_type_categories.yml @@ -2,3 +2,5 @@ test_category: label: 'Test category' description: 'This is a test field type category.' weight: -10 + libraries: + - field_plugins_test/test_library diff --git a/core/modules/field/tests/src/Kernel/FieldTypeCategoryDiscoveryTest.php b/core/modules/field/tests/src/Kernel/FieldTypeCategoryDiscoveryTest.php index 0dbf670fdcbe..22fa2ef738c2 100644 --- a/core/modules/field/tests/src/Kernel/FieldTypeCategoryDiscoveryTest.php +++ b/core/modules/field/tests/src/Kernel/FieldTypeCategoryDiscoveryTest.php @@ -29,12 +29,14 @@ public function testFieldTypeCategories() { 'Test category', 'This is a test field type category.', -10, + ['field_plugins_test/test_library'], ]; $this->assertSame($expected, [ (string) $category->getLabel(), (string) $category->getDescription(), $category->getWeight(), + $category->getLibraries(), ]); } diff --git a/core/modules/field_ui/src/Form/FieldStorageAddForm.php b/core/modules/field_ui/src/Form/FieldStorageAddForm.php index ed591d3ae03e..097af8b1111e 100644 --- a/core/modules/field_ui/src/Form/FieldStorageAddForm.php +++ b/core/modules/field_ui/src/Form/FieldStorageAddForm.php @@ -157,12 +157,13 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $field_type_options = $unique_definitions = []; $grouped_definitions = $this->fieldTypePluginManager->getGroupedDefinitions($this->fieldTypePluginManager->getUiDefinitions(), 'label', 'id'); + $category_definitions = $this->fieldTypeCategoryManager->getDefinitions(); // Invoke a hook to get category properties. foreach ($grouped_definitions as $category => $field_types) { foreach ($field_types as $name => $field_type) { $unique_definitions[$category][$name] = ['unique_identifier' => $name] + $field_type; if ($this->fieldTypeCategoryManager->hasDefinition($category)) { - $category_plugin = $this->fieldTypeCategoryManager->createInstance($category, $unique_definitions[$category][$name]); + $category_plugin = $this->fieldTypeCategoryManager->createInstance($category, $unique_definitions[$category][$name], $category_definitions[$category]); $field_type_options[$category_plugin->getPluginId()] = ['unique_identifier' => $name] + $field_type; } else { @@ -243,6 +244,10 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#variant' => 'field-option', ], ]; + + if ($libraries = $category_info->getLibraries()) { + $field_type_options_radios[$id]['#attached']['library'] = $libraries; + } } uasort($field_type_options_radios, [SortArray::class, 'sortByWeightProperty']); $form['add']['new_storage_type'] = $field_type_options_radios; diff --git a/core/modules/field_ui/tests/src/Functional/FieldTypeCategoriesIntegrationTest.php b/core/modules/field_ui/tests/src/Functional/FieldTypeCategoriesIntegrationTest.php new file mode 100644 index 000000000000..1490c2e8410b --- /dev/null +++ b/core/modules/field_ui/tests/src/Functional/FieldTypeCategoriesIntegrationTest.php @@ -0,0 +1,60 @@ +<?php + +namespace Drupal\Tests\field_ui\Functional; + +use Drupal\Tests\BrowserTestBase; + +/** + * Tests field UI integration with field type categories for loading libraries. + * + * @group field_ui + */ +class FieldTypeCategoriesIntegrationTest extends BrowserTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'node', + 'file', + 'field_ui', + 'options', + 'comment', + 'link', + ]; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + // Create a test user. + $admin_user = $this->drupalCreateUser(['administer node fields']); + $this->drupalLogin($admin_user); + } + + /** + * Tests if the libraries are loaded on FieldStorageAddForm. + */ + public function testLibrariesLoaded() { + $this->drupalGet('admin/structure/types/manage/' . $this->drupalCreateContentType()->id() . '/fields/add-field'); + $page_content = $this->getSession()->getPage()->getContent(); + $css_libraries = [ + 'drupal.file-icon', + 'drupal.text-icon', + 'drupal.options-icon', + 'drupal.comment-icon', + 'drupal.link-icon', + ]; + foreach ($css_libraries as $css_library) { + // Check if the library asset is present in the rendered HTML. + $this->assertStringContainsString($css_library, $page_content); + } + } + +} diff --git a/core/modules/file/file.field_type_categories.yml b/core/modules/file/file.field_type_categories.yml index efb40e7eeb03..8f96134e8f4e 100644 --- a/core/modules/file/file.field_type_categories.yml +++ b/core/modules/file/file.field_type_categories.yml @@ -2,3 +2,5 @@ file_upload: label: 'File upload' description: 'Field to upload any type of files.' weight: -15 + libraries: + - file/drupal.file-icon diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 220ec88bc47e..34b00de5c680 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -1552,10 +1552,3 @@ function file_field_find_file_reference_column(FieldDefinitionInterface $field) } return FALSE; } - -/** - * Implements hook_preprocess_form_element__new_storage_type(). - */ -function file_preprocess_form_element__new_storage_type(&$variables) { - $variables['#attached']['library'][] = 'file/drupal.file-icon'; -} diff --git a/core/modules/link/link.module b/core/modules/link/link.module index 590c01cc91c4..f05fe1c23817 100644 --- a/core/modules/link/link.module +++ b/core/modules/link/link.module @@ -5,6 +5,7 @@ * Defines simple link field types. */ +use Drupal\Core\Field\FieldTypeCategoryManagerInterface; use Drupal\Core\Link; use Drupal\Core\Url; use Drupal\Core\Routing\RouteMatchInterface; @@ -67,8 +68,12 @@ function template_preprocess_link_formatter_link_separate(&$variables) { } /** - * Implements hook_preprocess_form_element__new_storage_type(). + * Implements hook_field_type_category_info_alter(). */ -function link_preprocess_form_element__new_storage_type(&$variables) { - $variables['#attached']['library'][] = 'link/drupal.link-icon'; +function link_field_type_category_info_alter(&$definitions) { + // TRICKY: the `link` field type belongs in the `general` category, so the + // libraries need to be attached using an alter hook. + if (array_key_exists(FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY, $definitions)) { + $definitions[FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY]['libraries'][] = 'link/drupal.link-icon'; + } } diff --git a/core/modules/media/media.module b/core/modules/media/media.module index 962925315898..f297c3e28581 100644 --- a/core/modules/media/media.module +++ b/core/modules/media/media.module @@ -534,8 +534,12 @@ function media_views_query_substitutions(ViewExecutable $view) { } /** - * Implements hook_preprocess_form_element__new_storage_type(). + * Implements hook_field_type_category_info_alter(). */ -function media_preprocess_form_element__new_storage_type(&$variables) { - $variables['#attached']['library'][] = 'media/drupal.media-icon'; +function media_field_type_category_info_alter(&$definitions) { + // TRICKY: the `media` field type belongs in the `general` category, so the + // libraries need to be attached using an alter hook. + if (array_key_exists(FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY, $definitions)) { + $definitions[FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY]['libraries'][] = 'media/drupal.media-icon'; + } } diff --git a/core/modules/options/options.field_type_categories.yml b/core/modules/options/options.field_type_categories.yml index 9c23ff067057..339cc386c823 100644 --- a/core/modules/options/options.field_type_categories.yml +++ b/core/modules/options/options.field_type_categories.yml @@ -2,3 +2,5 @@ selection_list: label: 'Selection list' description: 'Field to select from predefined options.' weight: -15 + libraries: + - options/drupal.options-icon diff --git a/core/modules/options/options.module b/core/modules/options/options.module index 2feed0daf806..608f4bcc6586 100644 --- a/core/modules/options/options.module +++ b/core/modules/options/options.module @@ -155,10 +155,3 @@ function options_form_field_storage_config_edit_form_alter(&$form, FormStateInte $form['#attached']['library'][] = 'field_ui/drupal.field_ui'; $table['#attributes']['class'][] = 'allowed-values-table'; } - -/** - * Implements hook_preprocess_form_element__new_storage_type(). - */ -function options_preprocess_form_element__new_storage_type(&$variables) { - $variables['#attached']['library'][] = 'options/drupal.options-icon'; -} diff --git a/core/modules/telephone/telephone.module b/core/modules/telephone/telephone.module index c89d8bd83fd9..34899b47283b 100644 --- a/core/modules/telephone/telephone.module +++ b/core/modules/telephone/telephone.module @@ -5,6 +5,7 @@ * Defines a simple telephone number field type. */ +use Drupal\Core\Field\FieldTypeCategoryManagerInterface; use Drupal\Core\Url; use Drupal\Core\Routing\RouteMatchInterface; @@ -36,8 +37,12 @@ function telephone_field_formatter_info_alter(&$info) { } /** - * Implements hook_preprocess_form_element__new_storage_type(). + * Implements hook_field_type_category_info_alter(). */ -function telephone_preprocess_form_element__new_storage_type(&$variables) { - $variables['#attached']['library'][] = 'telephone/drupal.telephone-icon'; +function telephone_field_type_category_info_alter(&$definitions) { + // TRICKY: the `telephone` field type belongs in the `general` category, so + // the libraries need to be attached using an alter hook. + if (array_key_exists(FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY, $definitions)) { + $definitions[FieldTypeCategoryManagerInterface::FALLBACK_CATEGORY]['libraries'][] = 'telephone/drupal.telephone-icon'; + } } diff --git a/core/modules/text/text.field_type_categories.yml b/core/modules/text/text.field_type_categories.yml index 787cfc979572..c819e4b83bc1 100644 --- a/core/modules/text/text.field_type_categories.yml +++ b/core/modules/text/text.field_type_categories.yml @@ -2,3 +2,5 @@ formatted_text: label: 'Formatted text' description: 'Text field with markup support and optional editor.' weight: -45 + libraries: + - text/drupal.text-icon diff --git a/core/modules/text/text.module b/core/modules/text/text.module index 54f513281d4f..c0a03c62f978 100644 --- a/core/modules/text/text.module +++ b/core/modules/text/text.module @@ -164,10 +164,3 @@ function text_summary($text, $format = NULL, $size = NULL) { return $summary; } - -/** - * Implements hook_preprocess_form_element__new_storage_type(). - */ -function text_preprocess_form_element__new_storage_type(&$variables) { - $variables['#attached']['library'][] = 'text/drupal.text-icon'; -} -- GitLab