Entidades en Drupal 8Luis Ortiz Ramos@luisortizramos
● Somos expertos en Drupal● Somos Siddharta, Oriol, Robert, David,
Patricia, Ignacio, Javier y Luis.● Trabajamos para Estrella Damm, Dexeus,
Médicos Sin Fronteras, Infojobs, Greenpeace, Chupa Chups, Ayuntamiento de Barcelona, Torres, la CUP…
● Estamos en Barcelona● Puedes contactar con nosotros en
Dos tipos de entidades
Configuration entities:● Forma parte de CMI● Views, Blocks, Image styles, Menus, Rols…
Content entities
Historia
● Drupal 3 y anteriores: solo nodos● Drupal 4: flexinode● Drupal 5: nodos con campos con Content
Construction Kit● Drupal 6: “nodificamos” todo con módulos
contrib y añadimos campos con Content Construction Kit
● Drupal 7: entidades limitadas en core● Drupal 8: ¡entidades completas en core!
¿Qué es una entidad?
“Entities, in Drupal, are objects that are used for persistent storage of content and configuration information.”
Entity API
“Loadable thingy, that can optionally be fieldable”
Frando http://dgo.to/460320
Así que… ¿qué es una entidad?
A thingy …
Una “unidad” de información estructurada:● Un artículo o entrada en un blog● Un usuario● Un término de un vocabulario● Otra estructura de datos que creemos
… loadable …
Dispone de un conjunto de funciones para gestionar la información:● Funciones comunes para crear, leer,
actualizar y borrar entidades● Propiedades comunes● Integración con Views y otros servicios
… and optionally fieldable
Cada tipo de entidad tiene un conjunto de propiedades.
Cada tipo de entidad puede tener “subtipos” llamados bundles. Podemos adjuntar un conjunto de campos diferenciados a cada uno.
En Drupal 8: ● “contenido” es un tipo de entidad● “artículo” es un tipo de contenido (un bundle) ● “Integración Continua y trabajo en equipo en
Pantheon” es una entidad
Entidades en el núcleo de Drupal 8
Contenidos:● Para contenido!● Cada entidad de este tipo:
○ tiene una página node/ID○ revisiones
Usuarios:● Gestión de cuentas● Cada entidad tiene una página user/ID
Bloques personalizados:● Para contenido secundario
Términos:● Para organizar otras entidades● Cada entidad de este tipo tiene una página
taxonomy/term/ID
Comentarios:● Para adjuntar información estructurada a
otra entidad en el tiempo
Archivos:● Guarda metainformación sobre los archivos
Trabajando con entidades
Acceso a entidades
$manager = \Drupal::entityTypeManager();$entity = $manager ->getStorage('comment') ->load($id);
$entity = Comment::load($id);
$user = User::create(array('name' => 'me'));
$entity->getEntityTypeId();$entity->label();$entity->id();
Acceso a campos
echo $entity->subject->value;$term_id = $entity ->field_tags[2] ->target_id;
$entity->hasField($field_name); $entity = $field_item->getEntity();
$entity->title->value = 'new Title';$entity->save();
if ($node->isPromoted()) { $title = $node->getTitle();} elseif ($node->isPublished()) { $node->setTitle( $node->getAuthor() ->getUsername() );}
Acceso a traducciones
echo $entity ->getTranslation('de') ->title->value;
$translation = $entity->getTranslation('de');$translation->language()->id == 'de';$translation->title->value = 'German title';
$translation = $manager ->getTranslationFromContext($entity);echo $translation->label();
$entity = $translation->getUntranslated();
Acceso a definiciones
$entity_type = $entity_manager ->getDefinition('node');
$entity_type->id() == 'node'
$entity_type ->getClass()$entity_type ->hasKey('label')$entity_type ->isSubclassOf('ContentEntityInterface')
$field_definition = $entity-> getFieldDefinition($field_name);
$field_definition->getName();$field_definition->getPropertyDefinitions();
$entity_manager ->getFieldDefinitions('node', 'article');
Tipos de entidad personalizados
Son plugins:● Deben estar en Drupal/module/Entity● Deben cumplir la anotación
@ContentEntityType● Deben implementar ContentEntityBase
/** * Defines the comment entity class. * * @ContentEntityType( * id = "comment", * label = @Translation("Comment"), * bundle_label = @Translation("Comment type"), * handlers = { * "storage" = "Drupal\comment\CommentStorage", * "storage_schema" = "Drupal\comment\CommentStorageSchema", * "access" = "Drupal\comment\CommentAccessControlHandler", * "list_builder" = "Drupal\Core\Entity\EntityListBuilder", * "view_builder" = "Drupal\comment\CommentViewBuilder", * "views_data" = "Drupal\comment\CommentViewsData", * "form" = { * "default" = "Drupal\comment\CommentForm", * "delete" = "Drupal\comment\Form\DeleteForm" * }, * "translation" = “Drupal\comment\CommentTranslationHandler" * },...
... * base_table = "comment", * data_table = "comment_field_data", * uri_callback = "comment_uri", * translatable = TRUE, * entity_keys = { * "id" = "cid", * "bundle" = "comment_type", * "label" = "subject", * "langcode" = "langcode", * "uuid" = "uuid" * }, * links = { * "canonical" = "/comment/{comment}", * "delete-form" = "/comment/{comment}/delete", * "edit-form" = "/comment/{comment}/edit", * }, * bundle_entity_type = "comment_type", * field_ui_base_route = "entity.comment_type.edit_form", * constraints = { * "CommentName" = {} * } * ) */
Definen sus campos base:● Implementan la función baseFieldDefinitions● Usan BaseFieldDefinition::create para añadir
campos:○ Tipo de campo○ Propiedades○ Formateadores
class Comment extends ContentEntityBase implements CommentInterface {
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
/** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */$fields = parent::baseFieldDefinitions($entity_type);
$fields['subject'] = BaseFieldDefinition::create('string')
->setLabel(t('Subject'))->setTranslatable(TRUE)->setSetting('max_length', 64)->setDisplayOptions('form', array(
'type' => 'string_textfield',// Default comment body field has weight 20.'weight' => 10,
))->setDisplayConfigurable('form', TRUE);
return $fields;}
}
$fields['title'] = FieldDefinition::create('string')->setLabel(t('Title'))...->setDisplayOptions('view', array(
'label' => 'hidden','type' => 'string','weight' => -5,
))->setDisplayOptions('form', array(
'type' => 'string','weight' => -5,
))->setDisplayConfigurable('form', TRUE);
Los handlers:● son clases independientes del tipo de
entidad● definen:
○ Storage○ Access○ List and view builder○ Views data○ Forms
... * handlers = { * "storage" = "Drupal\comment\CommentStorage", * "storage_schema" = "Drupal\comment\CommentStorageSchema", * "access" = "Drupal\comment\CommentAccessControlHandler", * "list_builder" = "Drupal\Core\Entity\EntityListBuilder", * "view_builder" = "Drupal\comment\CommentViewBuilder", * "views_data" = "Drupal\comment\CommentViewsData", * "form" = { * "default" = "Drupal\comment\CommentForm", * "delete" = "Drupal\comment\Form\DeleteForm" * }, * "translation" = “Drupal\comment\CommentTranslationHandler" * },...
Storage:● Se utiliza para gestionar la persistencia de la
entidad.● Implementa EntityStorageInterface● Implementaciones base:
○ SqlContentEntityStorage○ ContentEntityNullStorage
class CommentStorage extends SqlContentEntityStorage implements CommentStorageInterface {
... public function loadThread(...) {
...}...
}
Entity keys:● Definen las claves que se usarán para cargar
las entidades● ContentEntityBase::baseFieldDefinitions crea
campos para ellas automáticamente
... * entity_keys = { * "id" = "cid", * "bundle" = "comment_type", * "label" = "subject", * "langcode" = "langcode", * "uuid" = "uuid" * },...
Links● Define la forma de los enlaces:
○ canonical○ add-form○ edit-form○ delete-form○ ...
... * links = { * "canonical" = "/comment/{comment}", * "delete-form" = "/comment/{comment}/delete", * "edit-form" = "/comment/{comment}/edit", * },...
Routing● Es posible definir las rutas en el archivo *.
routing.yml● Es mejor usar un handler route_provider
como DefaultHtmlRouteProvider
¿Por qué?
● Cuando necesitas un tipo de entidad específico: propiedades, métodos, acceso, almacenamiento…
● Cuando no quieres usar un tipo existente: puedes clonar uno y los demás módulos no sabrán de él
● Cuando necesitas control total sobre él: los campos base no pueden modificarse usando la interfaz
● Cuando el modelo de datos es muy complicado: como pasa con Commerce o Paragraphs
¡Gracias!¿Preguntas?
Top Related