SlideShare a Scribd company logo
1 of 85
Download to read offline
D8: Fields reborn
Pablo López - @plopesc
DrupalCamp Spain
Valencia, May 2014
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
Credits: @yched & @swentel
Broken record
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
... for the 3rd time
yched, amateescu, swentel
fago, Berdir, plach,
effulgentsia, andypost...
Site building
features
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)
Entity reference
Fairly complete port of D7 entity_reference.module
Taxonomy, file, image fields: still separate field types
Date / Datetime
The "repeat" features from D7 stays in contrib
Link
Basic version (URL, text)
No support for internal paths (e.g. node/1)
Now supports internal paths (https://drupal.org/node/2054011)
Email
• Input validation
• No anti-spam support out of the box
Phone
• HTML5 "tel" input
• Basic display (optional "tel:" link)
In Place Editing
Fieldable blocks
aka Beans in core
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...
Form modes UI
Field Overview UI
Fields are tied to an entity type
A 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">
There will be code
APIs !!!
Disclaimer: still in flux...
Data structures
Data model recap
• Field value: list of multiple items
• Each item: list of properties depending on the field type
• Fields can be translatable
Data model - D7
Data model - D7
D8 Entity translation
• Entity level, not field level
$entity->getTranslation($langcode)
• Implements EntityInterface:
$entity->getTranslation($langcode)->field_foo
• Facets of the same entity
$entityis always loaded/saved as a whole
Data model - D8
Data model - D8
Data model - D8
Data model - D8
Data model - D8
Data model - D8
Data model - D8
Data model - D8
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->propertyfor delta 0
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
Everything is a field
Everything
Everything in a ContentEntity is a field
• $node->title FieldItemListInterface
• $node->body FieldItemListInterface
• $node->field_custom FieldItemListInterface
Drawback: $node->title->value;
Mitigation: $node->getTitle();
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!)
Naming is hard...
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'...)
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
Unified FieldStorageDefinitionInterface
Field 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
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...
Grabbing field definitions
field_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
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
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...
CMI
CMI
• Configuration in YML files
• Deployable between environments
• Can be shipped in modules
• ConfigEntities
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
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
field.field.node.body.yml
id: node.body
uuid: d9a197db-89e1-4b8b-b50c-122083aeacb1
status: true
langcode: en
name: body
entity_type: node
type: text_with_summary
settings: { }
module: text
locked: false
cardinality: 1
translatable: false
indexes: { }
dependencies:
module:
- node
- text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
field.instance.node.article.body.yml
id: node.article.body
uuid: a378b8b5-39ac-44da-bc07-7ad0a2479a6a
status: true
langcode: en
field_uuid: d9a197db-89e1-4b8b-b50c-122083aeacb1
field_name: body
entity_type: node
bundle: article
label: Body
description: ''
required: false
default_value: { }
default_value_function: ''
settings:
display_summary: true
text_processing: true
dependencies:
entity:
- field.field.node.body
- node.type.article
field_type: text_with_summary
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CRUD API - D7
Dedicated functions:
+ associated hooks...
field_create_field(array());
field_update_field(array());
field_delete_field($field_name);
............_instance(array()); D7
CRUD API - D8
Regular 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
EntityDisplay
Display settings in D7
Scattered 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
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);
entity.display.node.article.teaser.yml
id: node.article.teaser
uuid: ad345f0f-ff44-4210-8900-b8bdfcd8e671
targetEntityType: node
bundle: article
mode: teaser
content:
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
EntityFormDisplay
• Same thing for forms :-)
• Allows "form modes"
Field types
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, $langcode
function hook_field_validate($entity_type, $entity, $field, $instance, $langcode
function hook_field_presave($entity_type, $entity, $field, $instance, $langcode
function hook_field_insert($entity_type, $entity, $field, $instance, $langcode
function hook_field_update($entity_type, $entity, $field, $instance, $langcode
function hook_field_delete($entity_type, $entity, $field, $instance, $langcode
function 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
FieldType plugin type
• Discovery folder: Plugin/Field/FieldType
• Annotation: FieldType
• Interface: FieldItemInterface
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();
/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
namespace DrupallinkPluginFieldFieldType;
use DrupalCoreFieldFieldItemBase;
use DrupalCoreFieldFieldStorageDefinitionInterface;
use DrupalCoreTypedDataDataDefinition;
use DrupalCoreTypedDataMapDataDefinition;
use DrupallinkLinkItemInterface;
/**
* 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 bl
* default_widget = "link_default",
* default_formatter = "link",
* constraints = {"LinkType" = {}}
* )
*/
class LinkItem extends FieldItemBase implements LinkItemInterface {
/**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Formatters
D7: "hooks" (well, magic callbacks)
• Lost within the 50 other functions in your file
• switchdance 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, $field
function mymodule_field_formatter_view($entity_type, $entity, $field, $instance
D8: FieldFormatter plugins
• All logic nicely self contained.
• OO! Classes! ( = Inheritance!)
• FormatterBase class provides stubs and helpers
namespace DrupalCoreField;
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);
}
D8: FieldFormatter plugin type
• No more _info() hook
• Expose your class as a "Field formatter" plugin
• Discovery folder: Plugin/Field/FieldFormatter
• Annotation: FieldFormatter
Inheritance example
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...
Widgets
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
}
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');
Widgets / formatters on base fields
• Powerful flexibility
• Free support for "In Place Editing"
• Hey, EntityDisplays let us store the settings!
/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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
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
Thanks!
Questions?

More Related Content

What's hot

iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative versionWO Community
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceIvan Chepurnyi
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDAleix Vergés
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
 
Drupal Field API. Practical usage
Drupal Field API. Practical usageDrupal Field API. Practical usage
Drupal Field API. Practical usagePavel Makhrinsky
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.jsBert Wijnants
 
In-depth changes to Drupal 8 javascript
In-depth changes to Drupal 8 javascriptIn-depth changes to Drupal 8 javascript
In-depth changes to Drupal 8 javascriptThéodore Biadala
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii명철 강
 
Backbone.js Simple Tutorial
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial추근 문
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of LithiumNate Abele
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceParashuram N
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 

What's hot (20)

iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative version
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
 
Not your Grandma's XQuery
Not your Grandma's XQueryNot your Grandma's XQuery
Not your Grandma's XQuery
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
Drupal 8 Services
Drupal 8 ServicesDrupal 8 Services
Drupal 8 Services
 
Fatc
FatcFatc
Fatc
 
Drupal Field API. Practical usage
Drupal Field API. Practical usageDrupal Field API. Practical usage
Drupal Field API. Practical usage
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.js
 
In-depth changes to Drupal 8 javascript
In-depth changes to Drupal 8 javascriptIn-depth changes to Drupal 8 javascript
In-depth changes to Drupal 8 javascript
 
XQuery Rocks
XQuery RocksXQuery Rocks
XQuery Rocks
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii
 
Backbone.js Simple Tutorial
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 

Similar to Drupal 8: Fields reborn

Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your CodeDrupalDay
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comJD Leonard
 
D7 entities fields
D7 entities fieldsD7 entities fields
D7 entities fieldscyberswat
 
Synapse india reviews on drupal 7 entities (stanford)
Synapse india reviews on drupal 7 entities (stanford)Synapse india reviews on drupal 7 entities (stanford)
Synapse india reviews on drupal 7 entities (stanford)Tarunsingh198
 
Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!Herman Peeren
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami
 
Entity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsEntity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsRichie Rump
 
Drupal 7 Entity & Entity API
Drupal 7 Entity & Entity APIDrupal 7 Entity & Entity API
Drupal 7 Entity & Entity API均民 戴
 
Drupalcon cph
Drupalcon cphDrupalcon cph
Drupalcon cphcyberswat
 
How and Where in GLORP
How and Where in GLORPHow and Where in GLORP
How and Where in GLORPESUG
 
Tutorial Expert How-To - Custom properties
Tutorial Expert How-To - Custom propertiesTutorial Expert How-To - Custom properties
Tutorial Expert How-To - Custom propertiesPascalDesmarets1
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemyInada Naoki
 
Fields in Core: How to create a custom field
Fields in Core: How to create a custom fieldFields in Core: How to create a custom field
Fields in Core: How to create a custom fieldIvan Zugec
 
Java Persistence API 2.0: An Overview
Java Persistence API 2.0: An OverviewJava Persistence API 2.0: An Overview
Java Persistence API 2.0: An OverviewSanjeeb Sahoo
 
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...SPTechCon
 
Drupal Camp Porto - Developing with Drupal: First Steps
Drupal Camp Porto - Developing with Drupal: First StepsDrupal Camp Porto - Developing with Drupal: First Steps
Drupal Camp Porto - Developing with Drupal: First StepsLuís Carneiro
 
Glorp Tutorial Guide
Glorp Tutorial GuideGlorp Tutorial Guide
Glorp Tutorial GuideESUG
 
Web2py tutorial to create db driven application.
Web2py tutorial to create db driven application.Web2py tutorial to create db driven application.
Web2py tutorial to create db driven application.fRui Apps
 

Similar to Drupal 8: Fields reborn (20)

Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.com
 
D7 entities fields
D7 entities fieldsD7 entities fields
D7 entities fields
 
Synapse india reviews on drupal 7 entities (stanford)
Synapse india reviews on drupal 7 entities (stanford)Synapse india reviews on drupal 7 entities (stanford)
Synapse india reviews on drupal 7 entities (stanford)
 
Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!Jooctrine - Doctrine ORM in Joomla!
Jooctrine - Doctrine ORM in Joomla!
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
 
Migrate
MigrateMigrate
Migrate
 
Entity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsEntity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic Unicorns
 
Field api.From d7 to d8
Field api.From d7 to d8Field api.From d7 to d8
Field api.From d7 to d8
 
Drupal 7 Entity & Entity API
Drupal 7 Entity & Entity APIDrupal 7 Entity & Entity API
Drupal 7 Entity & Entity API
 
Drupalcon cph
Drupalcon cphDrupalcon cph
Drupalcon cph
 
How and Where in GLORP
How and Where in GLORPHow and Where in GLORP
How and Where in GLORP
 
Tutorial Expert How-To - Custom properties
Tutorial Expert How-To - Custom propertiesTutorial Expert How-To - Custom properties
Tutorial Expert How-To - Custom properties
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
 
Fields in Core: How to create a custom field
Fields in Core: How to create a custom fieldFields in Core: How to create a custom field
Fields in Core: How to create a custom field
 
Java Persistence API 2.0: An Overview
Java Persistence API 2.0: An OverviewJava Persistence API 2.0: An Overview
Java Persistence API 2.0: An Overview
 
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
 
Drupal Camp Porto - Developing with Drupal: First Steps
Drupal Camp Porto - Developing with Drupal: First StepsDrupal Camp Porto - Developing with Drupal: First Steps
Drupal Camp Porto - Developing with Drupal: First Steps
 
Glorp Tutorial Guide
Glorp Tutorial GuideGlorp Tutorial Guide
Glorp Tutorial Guide
 
Web2py tutorial to create db driven application.
Web2py tutorial to create db driven application.Web2py tutorial to create db driven application.
Web2py tutorial to create db driven application.
 

More from Pablo López Escobés

MADs about Drupal: Programación de entities para D7
MADs about Drupal: Programación de entities para D7MADs about Drupal: Programación de entities para D7
MADs about Drupal: Programación de entities para D7Pablo López Escobés
 
Integración de APIs políglotas de mapas en Google Web Toolkit: IDELabMapstrac...
Integración de APIs políglotas de mapas en Google Web Toolkit: IDELabMapstrac...Integración de APIs políglotas de mapas en Google Web Toolkit: IDELabMapstrac...
Integración de APIs políglotas de mapas en Google Web Toolkit: IDELabMapstrac...Pablo López Escobés
 
Definición e implementación de soluciones basadas en APIs universales para la...
Definición e implementación de soluciones basadas en APIs universales para la...Definición e implementación de soluciones basadas en APIs universales para la...
Definición e implementación de soluciones basadas en APIs universales para la...Pablo López Escobés
 
Geohabilitación de gestores contenidos: CMSMap
Geohabilitación de gestores contenidos: CMSMapGeohabilitación de gestores contenidos: CMSMap
Geohabilitación de gestores contenidos: CMSMapPablo López Escobés
 
IDELab MapstractionInteractive: API Universal y Políglota
IDELab MapstractionInteractive: API Universal y PolíglotaIDELab MapstractionInteractive: API Universal y Políglota
IDELab MapstractionInteractive: API Universal y PolíglotaPablo López Escobés
 
Drupal & GIS: Convirtiendo Drupal en un GeoCMS
Drupal & GIS: Convirtiendo Drupal en un GeoCMSDrupal & GIS: Convirtiendo Drupal en un GeoCMS
Drupal & GIS: Convirtiendo Drupal en un GeoCMSPablo López Escobés
 

More from Pablo López Escobés (11)

When Drupal met CARTO
When Drupal met CARTOWhen Drupal met CARTO
When Drupal met CARTO
 
D7 as D8
D7 as D8D7 as D8
D7 as D8
 
Get on with Field API
Get on with Field APIGet on with Field API
Get on with Field API
 
API como SaaS
API como SaaSAPI como SaaS
API como SaaS
 
MADs about Drupal: Programación de entities para D7
MADs about Drupal: Programación de entities para D7MADs about Drupal: Programación de entities para D7
MADs about Drupal: Programación de entities para D7
 
Poniendo a drupal en el mapa
Poniendo a drupal en el mapaPoniendo a drupal en el mapa
Poniendo a drupal en el mapa
 
Integración de APIs políglotas de mapas en Google Web Toolkit: IDELabMapstrac...
Integración de APIs políglotas de mapas en Google Web Toolkit: IDELabMapstrac...Integración de APIs políglotas de mapas en Google Web Toolkit: IDELabMapstrac...
Integración de APIs políglotas de mapas en Google Web Toolkit: IDELabMapstrac...
 
Definición e implementación de soluciones basadas en APIs universales para la...
Definición e implementación de soluciones basadas en APIs universales para la...Definición e implementación de soluciones basadas en APIs universales para la...
Definición e implementación de soluciones basadas en APIs universales para la...
 
Geohabilitación de gestores contenidos: CMSMap
Geohabilitación de gestores contenidos: CMSMapGeohabilitación de gestores contenidos: CMSMap
Geohabilitación de gestores contenidos: CMSMap
 
IDELab MapstractionInteractive: API Universal y Políglota
IDELab MapstractionInteractive: API Universal y PolíglotaIDELab MapstractionInteractive: API Universal y Políglota
IDELab MapstractionInteractive: API Universal y Políglota
 
Drupal & GIS: Convirtiendo Drupal en un GeoCMS
Drupal & GIS: Convirtiendo Drupal en un GeoCMSDrupal & GIS: Convirtiendo Drupal en un GeoCMS
Drupal & GIS: Convirtiendo Drupal en un GeoCMS
 

Recently uploaded

Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 

Recently uploaded (20)

Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 

Drupal 8: Fields reborn

  • 1. D8: Fields reborn Pablo López - @plopesc DrupalCamp Spain Valencia, May 2014
  • 2. 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
  • 3. Credits: @yched & @swentel Broken record
  • 4. 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
  • 5.
  • 6.
  • 7.
  • 8. ... for the 3rd time
  • 9. yched, amateescu, swentel fago, Berdir, plach, effulgentsia, andypost...
  • 11. 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)
  • 12. Entity reference Fairly complete port of D7 entity_reference.module Taxonomy, file, image fields: still separate field types
  • 13. Date / Datetime The "repeat" features from D7 stays in contrib
  • 14. Link Basic version (URL, text) No support for internal paths (e.g. node/1) Now supports internal paths (https://drupal.org/node/2054011)
  • 15. Email • Input validation • No anti-spam support out of the box Phone • HTML5 "tel" input • Basic display (optional "tel:" link)
  • 18. 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...
  • 21. Fields are tied to an entity type A 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">
  • 22.
  • 23. There will be code APIs !!!
  • 24. Disclaimer: still in flux... Data structures
  • 25. Data model recap • Field value: list of multiple items • Each item: list of properties depending on the field type • Fields can be translatable
  • 28. D8 Entity translation • Entity level, not field level $entity->getTranslation($langcode) • Implements EntityInterface: $entity->getTranslation($langcode)->field_foo • Facets of the same entity $entityis always loaded/saved as a whole
  • 37. 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->propertyfor delta 0
  • 38. 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
  • 41. Everything in a ContentEntity is a field • $node->title FieldItemListInterface • $node->body FieldItemListInterface • $node->field_custom FieldItemListInterface Drawback: $node->title->value; Mitigation: $node->getTitle();
  • 42. 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!)
  • 44. 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'...)
  • 45. 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
  • 46. Unified FieldStorageDefinitionInterface Field 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
  • 47. 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...
  • 48. Grabbing field definitions field_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
  • 49. 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
  • 50. 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...
  • 51. CMI
  • 52. CMI • Configuration in YML files • Deployable between environments • Can be shipped in modules • ConfigEntities
  • 53. 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
  • 54.
  • 55. 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
  • 56. field.field.node.body.yml id: node.body uuid: d9a197db-89e1-4b8b-b50c-122083aeacb1 status: true langcode: en name: body entity_type: node type: text_with_summary settings: { } module: text locked: false cardinality: 1 translatable: false indexes: { } dependencies: module: - node - text 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  • 57. field.instance.node.article.body.yml id: node.article.body uuid: a378b8b5-39ac-44da-bc07-7ad0a2479a6a status: true langcode: en field_uuid: d9a197db-89e1-4b8b-b50c-122083aeacb1 field_name: body entity_type: node bundle: article label: Body description: '' required: false default_value: { } default_value_function: '' settings: display_summary: true text_processing: true dependencies: entity: - field.field.node.body - node.type.article field_type: text_with_summary 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
  • 58. CRUD API - D7 Dedicated functions: + associated hooks... field_create_field(array()); field_update_field(array()); field_delete_field($field_name); ............_instance(array()); D7
  • 59. CRUD API - D8 Regular 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
  • 61. Display settings in D7 Scattered 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
  • 62. 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);
  • 63. entity.display.node.article.teaser.yml id: node.article.teaser uuid: ad345f0f-ff44-4210-8900-b8bdfcd8e671 targetEntityType: node bundle: article mode: teaser content: 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 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
  • 64. 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
  • 65. EntityFormDisplay • Same thing for forms :-) • Allows "form modes"
  • 67. 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, $langcode function hook_field_validate($entity_type, $entity, $field, $instance, $langcode function hook_field_presave($entity_type, $entity, $field, $instance, $langcode function hook_field_insert($entity_type, $entity, $field, $instance, $langcode function hook_field_update($entity_type, $entity, $field, $instance, $langcode function hook_field_delete($entity_type, $entity, $field, $instance, $langcode function 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
  • 68. FieldType plugin type • Discovery folder: Plugin/Field/FieldType • Annotation: FieldType • Interface: FieldItemInterface
  • 69. 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();
  • 70. /core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php namespace DrupallinkPluginFieldFieldType; use DrupalCoreFieldFieldItemBase; use DrupalCoreFieldFieldStorageDefinitionInterface; use DrupalCoreTypedDataDataDefinition; use DrupalCoreTypedDataMapDataDefinition; use DrupallinkLinkItemInterface; /** * 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 bl * default_widget = "link_default", * default_formatter = "link", * constraints = {"LinkType" = {}} * ) */ class LinkItem extends FieldItemBase implements LinkItemInterface { /** 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
  • 72. D7: "hooks" (well, magic callbacks) • Lost within the 50 other functions in your file • switchdance 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, $field function mymodule_field_formatter_view($entity_type, $entity, $field, $instance
  • 73. D8: FieldFormatter plugins • All logic nicely self contained. • OO! Classes! ( = Inheritance!) • FormatterBase class provides stubs and helpers namespace DrupalCoreField; 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); }
  • 74. D8: FieldFormatter plugin type • No more _info() hook • Expose your class as a "Field formatter" plugin • Discovery folder: Plugin/Field/FieldFormatter • Annotation: FieldFormatter
  • 76. 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...
  • 78. 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 }
  • 79. 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');
  • 80. Widgets / formatters on base fields • Powerful flexibility • Free support for "In Place Editing" • Hey, EntityDisplays let us store the settings!
  • 81. /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; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
  • 82. 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
  • 83. 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