Drupal 8: Fields reborn
-
Upload
pablo-lopez -
Category
Technology
-
view
1.310 -
download
6
Transcript of Drupal 8: Fields reborn
![Page 1: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/1.jpg)
D8: Fields reborn
Pablo López - @plopesc
DrupalCamp SpainValencia, May 2014
![Page 2: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/2.jpg)
Let's do it with Drupal 8
Rubén Teijeiro
Was earlier today :)
Migrate in core
Christian López Espínola
Saturday 1pm
El universo javascript en Drupal 8
Ramón Vilar
Saturday 5pm
Modes and formatters
Jesús Sánchez Balsera
Sunday 10am
Related sessions
![Page 3: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/3.jpg)
Credits: @yched & @swentel
Broken record
![Page 4: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/4.jpg)
Amazing changes• More power for site builders
• Fields & instances moved to config entities
• Formatters, Widgets and Field types are plugins
• Formatters & Widgets work on all fields
• Moved from field to entity storage
Field & Entity API are now one happy big family
![Page 5: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/5.jpg)
![Page 6: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/6.jpg)
![Page 7: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/7.jpg)
![Page 8: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/8.jpg)
... for the 3rd time
![Page 9: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/9.jpg)
yched, amateescu, swentel
fago, Berdir, plach,
effulgentsia, andypost...
![Page 10: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/10.jpg)
Site building
features
![Page 11: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/11.jpg)
New field types• More power for site builders out of the box
• Not always full ports of the corresponding D7 modules
• Sometimes they are not even modules anymore (email, number, more to
come)
![Page 12: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/12.jpg)
Entity reference
Fairly complete port of D7 entity_reference.module
Taxonomy, file, image fields: still separate field types
![Page 13: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/13.jpg)
Date / Datetime
The "repeat" features from D7 stays in contrib
![Page 14: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/14.jpg)
Link
Basic version (URL, text)
No support for internal paths (e.g. node/1)
Now supports internal paths (https://drupal.org/node/2054011)
![Page 15: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/15.jpg)
Email• Input validation
• No anti-spam support out of the box
Phone• HTML5 "tel" input
• Basic display (optional "tel:" link)
![Page 16: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/16.jpg)
In Place Editing
![Page 17: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/17.jpg)
Fieldable blocks
aka Beans in core
![Page 18: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/18.jpg)
Form modes• Similar to "view modes", on the form side
• Build several form variants for your entities:
• User registration / user edit
• Creation / edit forms
• Fields can now be hidden in forms
Beware of required fields with no default values...
![Page 19: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/19.jpg)
Form modes UI
![Page 20: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/20.jpg)
Field Overview UI
![Page 21: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/21.jpg)
Fields are tied to an entity typeA field cannot be "shared" across entity types,
only across bundles of a given entity type
Consequences:
• No need to clutter the field name ('comment_body')
node 'body' != comment 'body'
• A $field_name alone is not enough:
$field = FieldConfig::loadByName($entity_type, $field_name);
<div class="field-name-body field-node--body">
![Page 22: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/22.jpg)
![Page 23: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/23.jpg)
There will be code
APIs !!!
![Page 24: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/24.jpg)
Disclaimer: still in flux...
Data structures
![Page 25: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/25.jpg)
Data model recap• Field value: list of multiple items
• Each item: list of properties depending on the field type
• Fields can be translatable
![Page 26: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/26.jpg)
Data model - D7
![Page 27: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/27.jpg)
Data model - D7
![Page 28: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/28.jpg)
D8 Entity translation• Entity level, not field level
$entity->getTranslation($langcode)
• Implements EntityInterface:
$entity->getTranslation($langcode)->field_foo
• Facets of the same entity
$entity is always loaded/saved as a whole
![Page 29: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/29.jpg)
Data model - D8
![Page 30: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/30.jpg)
Data model - D8
![Page 31: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/31.jpg)
Data model - D8
![Page 32: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/32.jpg)
Data model - D8
![Page 33: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/33.jpg)
Data model - D8
![Page 34: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/34.jpg)
Data model - D8
![Page 35: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/35.jpg)
Data model - D8
![Page 36: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/36.jpg)
Data model - D8
![Page 37: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/37.jpg)
In a nutshell• $entity, $entity->getTranslation('fr') Entity
• $entity->field_foo FieldItemList
• $entity->field_foo[$delta] FieldItem
• $entity->field_foo[$delta]->property
• $entity->field_foo->property for delta 0
![Page 38: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/38.jpg)
Navigating
Field items are "smart":
$items->getEntity() $items->getLangcode()
$items->getFieldDefinition()
$instances = field_info_instances($entity_type, $bundle);foreach ($instances as $field_name => $instance) { $items = $entity[$field_name][$langcode]; do_something($items, $entity, $langcode, $instance);} D7
foreach ($entity as $field_name => $items) { $items->doSomething(); // or $object->doSomething($items);} D8
![Page 39: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/39.jpg)
Everything is a field
![Page 40: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/40.jpg)
Everything
![Page 41: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/41.jpg)
Everything in a ContentEntity is a field• $node->title FieldItemListInterface
• $node->body FieldItemListInterface
• $node->field_custom FieldItemListInterface
Drawback: $node->title->value;
Mitigation: $node->getTitle();
![Page 42: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/42.jpg)
Unified APIs and features• field translation
• field access
• constraints / validation
• output in REST
• widgets / formatters
• In Place Editing
• EntityQuery (EFQ in D7)
• field cache (= entity cache!)
![Page 43: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/43.jpg)
Naming is hard...
![Page 44: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/44.jpg)
Different kinds of fields...• Base fields (former "entity properties")
• defined in code: MyEntityType::baseFieldDefinitions()
• Bundle fields (variations of base fields per bundle)
• defined in code: MyEntityType::bundleFieldDefinitions()
• e.g. node title
• Configurable fields (former "fields") - field.module
• defined in config through an admin UI
Properties: what you find inside a FieldItem ('value', 'format', 'target_id'...)
![Page 45: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/45.jpg)
Code architecture• /core/lib/Drupal/Core/Field
The Field system, widgets, formatters...
baked in the lifecycle of (Content)Entities
• /core/modules/field.module
Configurable fields
![Page 46: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/46.jpg)
Unified FieldStorageDefinitionInterfaceField definition: name, type, label, cardinality, settings, description...
• D7: $field / $instance arrays
$field['type'], $instance['settings']['max']
• D8: FieldStorageDefinitionInterface
$definition->getType(), $definition->getSetting('max')...
• Autocompletion, documentation...
• $field / $instance are mostly abstracted away
![Page 47: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/47.jpg)
Unified FieldStorageDefinitionInterface
Implementations:
• configurable fields: FieldConfig, FieldInstanceConfig
• base fields: FieldDefinition
interface FieldStorageDefinitionInterface { public function getName(); public function getType(); public function getSettings(); public function getSetting($setting_name); public function isTranslatable(); public function getDescription(); public function getCardinality(); public function isMultiple(); // Some others...
![Page 48: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/48.jpg)
Grabbing field definitionsfield_info_fields()field_info_field($field_name)field_info_instances($entity_type, $bundle)field_info_instances($entity_type, $bundle, $field_name) D7
$entity_manager->getFieldDefinitions($entity_type, $bundle)
// On an entity:$entity->getFieldDefinitions()$entity->getFieldDefinition($field_name)$entity->hasField($field_name)
// On items:$item->getFieldDefinition(), $items->getFieldDefinition() D8D8D8
![Page 49: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/49.jpg)
Field storage• D7: pluggable "field storage engines", field per field
• D8: job of the EntityStorageController
• Entities are stored as a whole
• Easier to swap an alternate storage (Mongo...)
• Base class for "generic SQL field storage"
• Per-field tables (same as D7)
• Handles revisions, translations, multi values, multi properties
• ... only for configurable fields
![Page 50: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/50.jpg)
Field storage (@todo, fingers crossed)
Problem:
• Supporting translatable base fields is hard
• 3rd party code can only add fields through config
Plan:
• Let base fields control how they are stored:
• Optimized storage in the entity base tables
• Generic storage, free translation support
• Custom storage somewhere else...
![Page 51: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/51.jpg)
CMI
![Page 52: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/52.jpg)
CMI• Configuration in YML files
• Deployable between environments
• Can be shipped in modules
• ConfigEntities
![Page 53: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/53.jpg)
Field definition structures• $field : "a data bucket"
(name, type, cardinality, entity type, ...)
• $instance : "a field attached to a specific [entity_type, bundle]"
(label, description, required, ...)
D7:
• deep arrays of hell
• {field_config}, {field_config_instance} db tables
![Page 54: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/54.jpg)
![Page 55: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/55.jpg)
D8: Field structures as ConfigEntities• $field :
• FieldConfig (entity type: 'field_config')
• field.field.[entity_type].[field_name].yml
• $instance :
• FieldInstanceConfig (entity type: 'field_instance_config')
• field.instance.[entity_type].[bundle].[field_name].yml
![Page 56: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/56.jpg)
field.field.node.body.ymlid: node.bodyuuid: d9a197db-89e1-4b8b-b50c-122083aeacb1status: truelangcode: enname: bodyentity_type: nodetype: text_with_summarysettings: { }module: textlocked: falsecardinality: 1translatable: falseindexes: { }dependencies: module: - node - text
123456789101112131415161718
![Page 57: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/57.jpg)
field.instance.node.article.body.ymlid: node.article.bodyuuid: a378b8b5-39ac-44da-bc07-7ad0a2479a6astatus: truelangcode: enfield_uuid: d9a197db-89e1-4b8b-b50c-122083aeacb1field_name: bodyentity_type: nodebundle: articlelabel: Bodydescription: ''required: falsedefault_value: { }default_value_function: ''settings: display_summary: true text_processing: truedependencies: entity: - field.field.node.body - node.type.articlefield_type: text_with_summary
12345678910111213141516171819202122
![Page 58: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/58.jpg)
CRUD API - D7Dedicated functions:
+ associated hooks...
field_create_field(array());field_update_field(array());field_delete_field($field_name);............_instance(array()); D7
![Page 59: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/59.jpg)
CRUD API - D8Regular Entity CRUD API:
+ regular hook_entity_[ENTITY_TYPE]_[OP]() hooks
$field = entity_create('field_config', array( 'name' => 'body', 'entity_type' => 'node', 'type' => 'text_with_summary',);$field->save();
$field->cardinality = 2;$field->save();
$field->delete(); D8
![Page 60: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/60.jpg)
EntityDisplay
![Page 61: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/61.jpg)
Display settings in D7Scattered around:
• $instance['display'][$view_mode]
• 'field_bundle_settings_[entity_type]_[bundle]' variable (ew...)
• 3rd party (Display suite, Field groups): in their own tables...
Each with separate "alter" hooks
Loads needless stuff in memory
![Page 62: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/62.jpg)
EntityViewDisplay (ConfigEntity)• "Full recipe" for displaying an entity in a given view mode
• Lists "components", with order and settings
entity_view($entity, $view_mode) :
• Loads the relevant display
• Alters it as a whole
• Injects it into all the callstack
hook_entity_view_display_alter(EntityViewDisplay $display);
EntityViewBuilder::buildContent(array $entities, array $displays);hook_entity_view(EntityInterface $entity, EntityViewDisplay $display);
![Page 63: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/63.jpg)
entity.display.node.article.teaser.ymlid: node.article.teaseruuid: ad345f0f-ff44-4210-8900-b8bdfcd8e671targetEntityType: nodebundle: articlemode: teasercontent: field_image: label: hidden type: image settings: image_style: medium image_link: content weight: -1 body: label: hidden type: text_summary_or_trimmed weight: 0 settings: trim_length: 600 field_tags: type: taxonomy_term_reference_link weight: 10 label: above settings: { }
123456789101112131415161718192021222324
![Page 64: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/64.jpg)
EntityViewDisplay API$display = entity_get_display('node', 'article', 'teaser');
$display->setComponent('body', array( 'type' => 'text_trimmed', 'settings' => array('trim_length' => '600'))->removeComponent('image')->save();
$options = $display->getComponent('body');// array(// 'type' => 'text_default'// 'weight' => 0,// 'settings' => array(),// 'label' => 'hidden',// )// or NULL if 'body' is hidden
![Page 65: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/65.jpg)
EntityFormDisplay• Same thing for forms :-)
• Allows "form modes"
![Page 66: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/66.jpg)
Field types
![Page 67: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/67.jpg)
D7: field type "hooks"function hook_field_info() { }function hook_field_schema($field) { }function hook_field_settings_form($field, $instnce, $has_data) { }function hook_field_instance_settings_form($field, $instance) { }
function hook_field_load($entity_type, $entities, $field, $instances, $langcodefunction hook_field_validate($entity_type, $entity, $field, $instance, $langcodefunction hook_field_presave($entity_type, $entity, $field, $instance, $langcodefunction hook_field_insert($entity_type, $entity, $field, $instance, $langcodefunction hook_field_update($entity_type, $entity, $field, $instance, $langcodefunction hook_field_delete($entity_type, $entity, $field, $instance, $langcodefunction hook_field_delete_revision($entity_type, $entity, $field, $instance,
function hook_field_is_empty($item, $field) { }function hook_field_prepare_view($entity_type, $entities, $field, $instances, function hook_field_prepare_translation($entity_type, $entity, $field, $instance
![Page 68: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/68.jpg)
FieldType plugin type• Discovery folder: Plugin/Field/FieldType
• Annotation: FieldType
• Interface: FieldItemInterface
![Page 69: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/69.jpg)
FieldItemInterface Now in 8.x !
interface FieldItemInterface { public static function schema(FieldDefinitionInterface $field_definition); public static function propertyDefinitions(); public function getConstraints(); public function isEmpty();
public static function defaultSettings(); public static function defaultInstanceSettings();
public function settingsForm(array $form, array &$form_state, $has_data); public function instanceSettingsForm(array $form, array &$form_state);
public function prepareCache(); public function preSave(); public function insert(); public function update(); public function delete();
![Page 70: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/70.jpg)
/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.phpnamespace Drupal\link\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase;use Drupal\Core\Field\FieldStorageDefinitionInterface;use Drupal\Core\TypedData\DataDefinition;use Drupal\Core\TypedData\MapDataDefinition;use Drupal\link\LinkItemInterface;
/** * Plugin implementation of the 'link' field type. * * @FieldType( * id = "link", * label = @Translation("Link"), * description = @Translation("Stores a URL string, optional varchar link text, and optional blob of attributes to assemble a link."), * default_widget = "link_default", * default_formatter = "link", * constraints = {"LinkType" = {}} * ) */class LinkItem extends FieldItemBase implements LinkItemInterface {
/**
1234567891011121314151617181920212223
![Page 71: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/71.jpg)
Formatters
![Page 72: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/72.jpg)
D7: "hooks" (well, magic callbacks)
• Lost within the 50 other functions in your file
• switch dance when you implement several formatters
function mymodule_field_formatter_info() { }
function mymodule_field_formatter_settings_form($field, $instance, $view_mode,function mymodule_field_formatter_settings_summary($field, $instance, $view_mode
function mymodule_field_formatter_prepare_view($entity_type, $entities, $fieldfunction mymodule_field_formatter_view($entity_type, $entity, $field, $instance
![Page 73: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/73.jpg)
D8: FieldFormatter plugins
• All logic nicely self contained.
• OO! Classes! ( = Inheritance!)
• FormatterBase class provides stubs and helpers
namespace Drupal\Core\Field;
interface FormatterInterface extends PluginSettingsInterface { public static function defaultSettings() public function settingsForm(array $form, array &$form_state); public function settingsSummary(); public function prepareView(array $entities_items); public function view(FieldItemListInterface $items); public function viewElements(FieldItemListInterface $items);}
![Page 74: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/74.jpg)
D8: FieldFormatter plugin type• No more _info() hook
• Expose your class as a "Field formatter" plugin
• Discovery folder: Plugin/Field/FieldFormatter
• Annotation: FieldFormatter
![Page 75: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/75.jpg)
Inheritance example
![Page 76: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/76.jpg)
Working in formatters• Access the configuration of the formatter:
$this->getSetting('foo'), $this->getSettings()
• Access the definition of the field:
$this->fieldDefinition->getType()
$this->getFieldSetting('foo'), $this->getFieldSettings()
• Manipulate the FieldItemList and FieldItem objects:
$items->getEntity(), $items->getLangcode()
You really want to extend FormatterBase...
![Page 77: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/77.jpg)
Widgets
![Page 78: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/78.jpg)
FieldWidget plugin type• Discovery folder: Plugin/Field/FieldWidget
• Annotation: FieldWidget
• WidgetBase class
interface WidgetInterface extends WidgetBaseInterface { public static function defaultSettings() public function settingsForm(array $form, array &$form_state); public function settingsSummary(); public function formElement(FieldItemListInterface $items, $delta, array $element public function errorElement(array $element, ConstraintViolationInterface $violation public function massageFormValues(array $values, array $form, array &$form_state}
![Page 79: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/79.jpg)
Working in widgets• Same as formatters...
• New in D8: massageFormValues()
Values produced by the FAPI structure → proper field values
• FAPI / render #callbacks:
$form['#process'] = '_my_process_helper';
$form['#process'] = array($this, 'myProcessHelper');
Please use static methods instead, (avoids serializing $this):
$form['#process'] = array(get_class($this), 'myProcessHelper');
![Page 80: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/80.jpg)
Widgets / formatters on base fields• Powerful flexibility
• Free support for "In Place Editing"
• Hey, EntityDisplays let us store the settings!
![Page 81: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/81.jpg)
/core/modules/node/lib/Drupal/node/Entity/Node.php public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['title'] = FieldDefinition::create('string') ->setLabel(t('Title')) ->setDescription(t('The title of this node, always treated as non-markup plain text.')) // ... ->setSettings(array( // Array settings... )) ->setDisplayOptions('view', array( // Array options... )) ->setDisplayOptions('form', array( // Array options... )) ->setDisplayConfigurable('form', TRUE); //.... } public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $node_type = node_type_load($bundle); $fields = array(); if (isset($node_type->title_label)) { $fields['title'] = clone $base_field_definitions['title']; $fields['title']->setLabel($node_type->title_label); } return $fields; }
1234567891011121314151617181920212223
![Page 82: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/82.jpg)
API changes / beta targets coming up• Content translation sync settings to own storage
• A unified repository of field definitions
• Remove field_info_*() (Patch submitted)
• Apply formatters and widgets to * fields (Partially)
• Make delete fields work with config synchronization
![Page 83: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/83.jpg)
Get involved• [META] Complete the Entity Field API
http://drupal.org/node/2095603
• http://entity.worldempire.ch/
• Weekly IRC meetings: #drupal-entity - Thursday, 18:00 CET
![Page 84: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/84.jpg)
Thanks!
![Page 85: Drupal 8: Fields reborn](https://reader033.fdocuments.net/reader033/viewer/2022051314/554bdebdb4c905706a8b578c/html5/thumbnails/85.jpg)
Questions?