Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 298840

Allow attribute-based plugins to discover supplemental attributes to set additional properties

$
0
0

Problem/Motivation

Currently, the set of properties for a particular plugin type is only defined in one place - previously the plugin type's annotation class, and now the plugin type's attribute class.

This leads to some problems, such as:

- The long-standing problem where the EntityType annotation/attribute defines a 'field_ui_base_route' which is actually for field_ui, an optional module
- The long-standing feature needed for Views, where we'd like to add a property to FieldType plugins for Views, which is, again, an optional module -- #2337515: Allow @FieldType to customize views data

Proposed resolution

Provide a PluginProperty attribute class that can be used to add property data to plugin class definitions parsed from Plugin attributes. The PluginProperty class includes these properties:

  • key: The property key/name within the plugin definition to set the value for. If key is an array, then it is treated as a set of nested array keys, with the outer keys coming first. When plugin definitions are arrays, NestedArray::set() is used to set the value at key
  • value: The property value to set
  • allowedPluginClasses: A list of plugin attribute classes the plugin property can modify the definition for. This is really only useful for subclasses of PluginProperty

Because of the way plugin attributed-based discovery is cached, it is difficult to read data from PHP attributes that exist only when certain modules are installed. As a result, subclasses of the PluginProperty are not allowed outside of Drupal\Core and Drupal\Component. In order to allow module-specific properties to be added to plugin definitions, the PluginProperty class also has these properties:

  • moduleDependencies: Machine names of modules that need to be installed in order for the property to be set, if any
  • addToDefinitionCallback: If the PluginProperty attribute is being used with a plugin type definition that is not a an array, and there doesn't exist a core PluginProperty subclass that works with the plugin type, then custom/contrib developers can pass in a callable to PluginProperty that sets the property value on the definition object

Once we have something like PluginProperty, we can also create subclasses in core that allow us to set properties on entity type definitions, in order to split up the large entity type attribute definition into multiple attributes, as suggested in #18:

#[ContentEntityType(
  id: 'node',
  label: new TranslatableMarkup('Content'),
...
)]
#[Handler('storage', NodeStorage::class)]
// Or maybe even more specific subclasses for common handlers
#[StorageHandler(NodeStorage::class)]
#[Link('canonical', '/node/{node}']

With an EntityTypeProperty subclass, we can define the field_ui_base_route on entity type definitions to be added only when Field UI is installed as such:

#[ContentEntityType(
  id: 'node',
  label: new TranslatableMarkup('Content'),
...
)]
#[EntityTypeProperty(
  key: 'field_ui_base_route',
  value: 'entity.node_type.edit_form',
  moduleDependencies: ['field_ui'],
)]

Other entity type definition subclasses such as Handler, StorageHandler, Link will be added in follow up #3488054: Make it possible to define entity types with multiple smaller attributes. EntityTypeProperty is added in MR 10218 here, as well as the Field UI example change in Node.

Note: field_ui_base_route is used as the base route for local tasks on entity bundle admin paths: https://git.drupalcode.org/project/drupal/-/blob/11.x/core/modules/user/.... Changing it so that it is only defined when Field UI is installed might have some unexpected UI changes.

Remaining tasks

User interface changes

None.

API changes

Plugin classes can use PluginProperty attributes to add supplemental properties to their definitions.

Data model changes

Release notes snippet


Viewing all articles
Browse latest Browse all 298840

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>