En el artículo anterior creamos la estructura básica de nuestra tienda:
Home Shop
│
├── Used Product
│ └── Used Variation
│
├── Imported Product
│ └── Imported Variation
│
└── Cake
└── Cake VariationAhora debemos convertir estas estructuras vacías en modelos de producto realmente útiles.
Para ello utilizaremos cuatro herramientas fundamentales de Drupal:
- Fields
- Taxonomy
- Media
- Commerce Product Attributes
El objetivo de este artículo no es simplemente añadir campos.
Queremos aprender a decidir qué tipo de estructura corresponde a cada dato.
1. El problema que queremos resolver
Nuestra tienda familiar necesita representar productos muy diferentes.
Por ejemplo:
USED PRODUCT
Canon Camera usada
Category:
Photography
Condition:
Good
Visible defects:
Small scratches
Images:
3 photos
Price:
250 USDTambién:
IMPORTED PRODUCT
USB-C Hub
Brand:
Baseus
Category:
Electronics
Country of origin:
China
Price:
35 USDY:
CAKE
Chocolate Cake
Ingredients:
Chocolate, flour, eggs...
Allergens:
Eggs, milk, gluten
Sizes:
Small
Medium
LargeAunque toda esta información describe productos, no toda debería representarse mediante el mismo mecanismo.
2. Nuestra matriz de decisión
Antes de crear un field podemos utilizar esta guía:
¿Es simplemente un dato?
↓
Field
¿Es un concepto reutilizable
que clasifica productos?
↓
Taxonomy
¿Es un recurso multimedia
que puede reutilizarse?
↓
Media
¿Es una opción que selecciona
el comprador para determinar
qué Variation compra?
↓
Product AttributeEsta matriz será nuestra referencia durante toda la configuración.
3. Fields
Un Field almacena información estructurada dentro de una entidad.
Por ejemplo:
Visible defects
Purchase year
Country of origin
Ingredients
Allergen informationDrupal permite añadir fields prácticamente a cualquier entidad fieldable.
En Commerce podemos añadirlos, entre otras, a:
Product
Product Variation
Order
Order Item
Product Attribute ValuePor eso la pregunta no es solamente:
¿Qué field necesito?
Sino también:
¿En qué entidad debe vivir?
4. Taxonomy
Taxonomy sirve para representar conceptos reutilizables y administrables.
Por ejemplo:
Product Category
├── Electronics
├── Photography
├── Furniture
├── Books
├── Food
└── CakesUn mismo término puede utilizarse en muchos productos.
Además podremos posteriormente:
- Filtrar por categoría
- Crear páginas de categoría
- Construir navegación
- Usar Facets
- Añadir metadata al término
Esto es muy diferente de guardar simplemente:
Category = "Photography"en un text field.
5. Media
Drupal dispone de entidades Media para gestionar recursos reutilizables como imágenes, documentos, vídeos y otros archivos.
Para nuestro catálogo utilizaremos Media para las imágenes.
Conceptualmente:
Product
│
└── Images
↓
Media
↓
ImageEsto ofrece ventajas frente a un simple Image field cuando queremos reutilizar recursos, añadir metadata o aprovechar Media Library. Drupal Core permite que los Media Types tengan sus propios fields y que un media reference field referencie uno o varios tipos de Media.
6. Product Attributes
Los Product Attributes tienen una responsabilidad mucho más específica.
Representan características utilizadas para diferenciar Product Variations.
Por ejemplo:
Cake Size
├── Small
├── Medium
└── LargeEl comprador selecciona:
Size:
Mediumy Commerce determina:
Product Variation
Chocolate Cake - Medium
SKU:
CAKE-CHO-M
Price:
25 USDEste es el motivo por el que Size será un Commerce Product Attribute y no una Taxonomy.
7. Crear Product Category
Empezaremos con nuestras taxonomías.
Vamos a:
Structure
→ Taxonomy
→ Add vocabularyCreamos:
Name:
Product Category
Machine name:
product_categoryDespués añadimos algunos términos:
Electronics
Photography
Furniture
Books
Food
Cakes8. Podemos utilizar jerarquía
A medida que el catálogo crezca podemos evolucionar hacia:
Product Category
Electronics
├── Computers
├── Phones
├── Accessories
└── Photography
Home
├── Furniture
└── Kitchen
Food
└── CakesNo necesitamos construir una taxonomía enorme desde el primer día.
Podemos empezar con los términos realmente necesarios.
9. Product Category será compartida
No crearemos:
Used Product Category
Imported Product Category
Cake Categorysi todos pertenecen al mismo sistema de clasificación.
Utilizaremos:
Product Categorycomo vocabulario compartido.
Por ejemplo:
Canon Camera usada
→ Photography
USB-C Hub
→ Electronics
Chocolate Cake
→ Cakes10. Crear Product Condition
Los productos usados necesitan representar su estado.
Creamos:
Vocabulary:
Product Condition
Machine name:
product_conditionValores iniciales:
Like New
Very Good
Good
Fair
For PartsEsto nos dará una lista consistente y reutilizable.
11. ¿Por qué Condition es Taxonomy?
Podríamos haber utilizado un List field.
Por ejemplo:
Condition
like_new | Like New
very_good | Very Good
good | Good
fair | FairTambién sería una solución válida.
Para nuestro ejercicio utilizaremos Taxonomy porque queremos practicar:
- Reutilización
- Filtrado
- Administración de términos
- Posible metadata futura
Esta decisión no significa que Taxonomy sea siempre superior a un List field.
La elección depende de cuánto comportamiento necesitemos alrededor del concepto.
12. Crear Product Origin
También crearemos:
Vocabulary:
Product Origin
Machine name:
product_originCon:
Used
Imported
Local ProductionEsto nos permitirá clasificar:
Canon Camera
→ Used
USB-C Hub
→ Imported
Chocolate Cake
→ Local Production13. Product Origin nos ayudará a revisar nuestra arquitectura
Recordemos que actualmente tenemos:
Used Product
Imported Productcomo Product Types separados.
Pero ahora también tenemos:
Product OriginEsto plantea una pregunta interesante:
¿Estamos duplicando una distinción que podría resolverse solamente mediante Taxonomy?
Aún no responderemos definitivamente.
Queremos observar primero qué fields necesita cada Product Type.
Si terminan teniendo prácticamente la misma estructura, podríamos simplificarlos posteriormente.
14. Añadir Category a Used Product
Vamos a:
Commerce
→ Configuration
→ Products
→ Product types
→ Used Product
→ Manage fieldsAñadimos un field:
Label:
Category
Machine name:
field_category
Field type:
Entity reference
Reference type:
Taxonomy term
Vocabulary:
Product CategoryNormalmente permitiremos un término principal inicialmente.
Más adelante podemos decidir si un producto puede pertenecer a múltiples categorías.
15. Reutilizar field storage cuando tenga sentido
Queremos que Imported Product y Cake utilicen también Product Category.
Drupal permite reutilizar un field existente cuando:
- El tipo de field es compatible
- La semántica es realmente la misma
Conceptualmente queremos:
field_category
Used Product
Imported Product
Cakeen lugar de crear:
field_used_category
field_imported_category
field_cake_categorysin ninguna necesidad.
16. Añadir Condition a Used Product
Ahora añadimos:
Label:
Condition
Machine name:
field_condition
Type:
Taxonomy term reference
Vocabulary:
Product ConditionEste field será obligatorio para los productos usados.
Por ejemplo:
Canon Camera usada
Condition:
Good17. Añadir Product Origin
Podemos añadir también:
Origin
→ Product Origin taxonomySin embargo aquí debemos pensar antes de configurar.
Para un Product Type llamado:
Used Productel valor siempre será:
UsedEntonces almacenar:
Origin = Useden cada producto puede ser redundante.
Por ahora no añadiremos Origin a Used Product.
El Product Type ya expresa esa distinción.
18. Esta decisión nos enseña algo importante
No debemos crear un field simplemente porque tenemos un vocabulario disponible.
Preguntamos:
¿Este dato aporta información que no conocemos ya por la estructura?
Si:
Product Type = Used Productentonces:
Origin = Usedpuede ser duplicación.
Esto refuerza la necesidad de revisar más adelante si realmente queremos Product Types separados por origen.
19. Añadir Visible Defects
Para Used Product necesitamos información específica del artículo.
Añadimos:
Label:
Visible Defects
Machine name:
field_visible_defects
Field type:
Text (long)Por ejemplo:
Small scratches on the body.
Lens cap has minor wear.Este dato no necesita Taxonomy.
Cada producto puede tener una descripción diferente.
20. Añadir Purchase Year
Podemos querer registrar aproximadamente cuándo se adquirió originalmente.
Podríamos crear:
Label:
Purchase Year
Machine name:
field_purchase_yearPara una implementación sencilla podemos utilizar un Integer field.
Ejemplo:
2021No necesitamos una Taxonomy:
2020
2021
2022
2023
...porque estamos almacenando un valor, no un concepto reutilizable.
21. Imágenes del producto
Ahora necesitamos fotografías.
Podríamos utilizar directamente un Image field.
Pero para nuestra tienda utilizaremos Media.
Queremos:
Product
Images
↓
Media referencesEsto nos permitirá utilizar Media Library y reutilizar imágenes si alguna vez lo necesitamos.
22. Revisar el Media Type Image
Una instalación Drupal normalmente dispone de un Media Type:
ImagePodemos revisarlo en:
Structure
→ Media types
→ ImageConceptualmente contiene:
Media
│
├── Name
├── Image file
└── MetadataDrupal Core permite añadir además fields personalizados a Media Types.
23. Añadir Images a Used Product
En Manage fields añadimos:
Label:
Images
Machine name:
field_images
Field type:
Media reference
Allowed media type:
Image
Cardinality:
UnlimitedQueremos poder tener:
Canon Camera usada
Images
├── front
├── back
├── side
└── defect detail24. Configurar Media Library
En:
Manage form displaypodemos seleccionar el widget:
Media LibraryEsto proporciona una mejor experiencia editorial:
Add media
↓
Select existing image
or
Upload new imageEn lugar de tratar cada archivo como un simple upload aislado.
25. Añadir Images a otros Product Types
Queremos reutilizar el mismo concepto:
field_imagesen:
Used Product
Imported Product
CakeTodos representan:
Imágenes generales del producto.
Por tanto tiene sentido compartir la misma estructura.
26. Modelo actual de Used Product
Hasta ahora tenemos:
USED PRODUCT
Product
├── Title
├── Description
├── Category
├── Condition
├── Images
├── Visible Defects
└── Purchase Year
Variation
├── SKU
└── PriceEste modelo ya nos permite crear un artículo usado bastante completo.
27. Configurar Imported Product
Ahora vamos a:
Imported Product
→ Manage fieldsReutilizamos:
Category
ImagesY añadiremos algunos fields específicos.
28. Brand
Un producto importado puede tener:
Brand:
BaseusPodríamos utilizar:
Text fieldpero si queremos construir un catálogo serio probablemente Brand es un concepto reutilizable.
Por ejemplo:
Brand
├── Anker
├── Baseus
├── Xiaomi
├── Ugreen
└── GenericPor tanto crearemos una nueva Taxonomy.
29. Crear Product Brand
Creamos:
Vocabulary:
Product Brand
Machine name:
product_brandY algunos términos:
Anker
Baseus
Xiaomi
Ugreen
GenericDespués añadimos a Imported Product:
Brand
→ Taxonomy term reference
→ Product Brand30. Brand como Taxonomy nos permitirá evolucionar
Más adelante podemos añadir fields al término Brand.
Por ejemplo:
Brand
Baseus
├── Logo
├── Website
├── Description
└── CountryEntonces una página de marca podría mostrar:
Baseus
Logo
Description
Products from this brandEste es un buen ejemplo de cuándo Taxonomy aporta más valor que un simple text field.
31. Country of Origin
Queremos almacenar:
Country of Origin:
ChinaAquí tenemos varias opciones.
Podríamos usar:
- Text
- List
- Country field
- Taxonomy
Para un país, deberíamos preferir un tipo de dato estructurado antes que texto libre cuando esté disponible.
No queremos terminar con:
China
PR China
People's Republic of China
CNrepresentando el mismo país.
32. Supplier
Podríamos querer registrar quién nos suministra el producto.
Por ejemplo:
Supplier:
Example Imports Inc.Sin embargo, Supplier es información administrativa interna.
No necesariamente queremos mostrarla públicamente.
Podemos crear:
field_suppliermás adelante cuando tengamos claro si será:
- Texto
- Taxonomy
- Custom Entity
- Referencia a otro sistema
Por ahora no la añadiremos.
No modelaremos datos sin necesidad concreta.
33. Modelo actual de Imported Product
IMPORTED PRODUCT
Product
├── Title
├── Description
├── Category
├── Brand
├── Images
└── Country of Origin
Variation
├── SKU
└── PriceMás adelante Variation puede incorporar:
Stock
Weight
Dimensions
Attributescuando estudiemos Inventory y Shipping.
34. Configurar Cake
Ahora llegamos al Product Type más interesante.
Queremos:
Chocolate Cake
Description
Images
Ingredients
Allergens
Variations:
Small
Medium
LargeEmpezaremos con los fields del Product.
35. Category
Reutilizamos:
field_categoryy seleccionaremos:
CakesEsto permitirá integrar Cakes dentro del catálogo general.
36. Images
Reutilizamos:
field_imagescon Media Library.
Por ejemplo:
Chocolate Cake
Images:
├── whole cake
├── slice
└── decoration detail37. Ingredients
Para nuestro ejemplo inicial crearemos:
Label:
Ingredients
Machine name:
field_ingredients
Type:
Text (long)Por ejemplo:
Flour, cocoa, eggs, sugar,
butter and chocolate.Más adelante podríamos descubrir que necesitamos estructurar los ingredientes de una forma mucho más avanzada.
Pero todavía no existe ese requisito.
38. Allergens
Podríamos escribir:
Contains eggs, milk and gluten.como texto.
Pero Allergens tienen potencial de ser conceptos reutilizables y filtrables.
Por ejemplo:
Allergens
├── Gluten
├── Milk
├── Eggs
├── Nuts
├── Peanuts
└── SoyEsto sugiere utilizar Taxonomy.
39. Crear Allergen
Creamos:
Vocabulary:
Allergen
Machine name:
allergenValores iniciales:
Gluten
Milk
Eggs
Nuts
Peanuts
SoyDespués añadimos al Cake:
Allergens
→ Taxonomy reference
→ Multiple valuesPor ejemplo:
Chocolate Cake
Allergens:
Gluten
Milk
Eggs40. Ingredients y Allergens muestran dos modelos diferentes
Tenemos:
Ingredients
↓
Text
Allergens
↓
Taxonomy¿Por qué?
Porque en nuestra implementación:
Ingredients
= descripción específica
Allergens
= conjunto controlado
de conceptos reutilizablesSi en el futuro necesitamos gestionar nutrición, recetas o inventario de ingredientes, probablemente deberíamos revisar este modelo.
41. Ahora necesitamos Cake Size
El tamaño no es solamente información descriptiva.
El comprador debe seleccionar:
Small
Medium
Largey cada opción puede tener:
Different SKU
Different Price
Possibly different weightPor tanto Cake Size es un Product Attribute.
42. Crear Product Attribute
Vamos a:
Commerce
→ Product attributeso directamente:
/admin/commerce/product-attributesSeleccionamos:
Add product attributey creamos:
Label:
Cake Size
Machine name:
cake_sizeDrupal Commerce permite definir Product Attributes libremente según las opciones reales de nuestros productos.
43. Attribute Element Type
El Product Attribute define también cómo pueden presentarse inicialmente sus valores al comprador.
Podemos encontrar opciones como:
Select list
Radio buttons
Rendered attributePara Cake Size podemos comenzar con:
Radio buttonsporque tenemos solamente tres opciones fáciles de entender.
Conceptualmente:
Size
( ) Small
( ) Medium
( ) Large44. Crear Attribute Values
Dentro de Cake Size añadimos:
Small
Medium
LargeY definimos su orden:
Small
↓
Medium
↓
LargeLos Product Attribute Values son entidades de contenido asociadas al Product Attribute correspondiente.
45. Product Attribute y Taxonomy se parecen estructuralmente
Existe una similitud interesante:
Taxonomy
Vocabulary
↓
Termsy:
Commerce Attribute
Product Attribute
↓
Attribute ValuesPor ejemplo:
Vocabulary:
Product Condition
Terms:
Good
Fair
...frente a:
Product Attribute:
Cake Size
Values:
Small
Medium
LargePero sus responsabilidades son diferentes.
46. Taxonomy frente a Product Attribute
Podemos compararlos:
PRODUCT CONDITION
Used for:
Classification
Customer chooses variation?
No
Changes SKU?
No
Changes price?
No
↓
TaxonomyMientras:
CAKE SIZE
Used for:
Purchasable choice
Customer chooses variation?
Yes
Changes SKU?
Yes
Changes price?
Yes
↓
Product AttributeEsta es una de las distinciones más importantes del modelado de Commerce.
47. Añadir Cake Size a Cake Variation
Crear el Attribute no es suficiente.
Debemos decir qué Variation Type lo utiliza.
Vamos a:
Commerce
→ Configuration
→ Products
→ Product variation types
→ Cake Variation
→ EditEn la sección de Attributes deberíamos encontrar:
Cake SizeLo activamos.
La documentación oficial describe precisamente este proceso: al seleccionar un Attribute en el Variation Type, Commerce crea los entity reference fields necesarios para relacionar Variations con Attribute Values.
48. Qué acaba de ocurrir
Antes teníamos:
CAKE VARIATION
SKU
Title
PriceDespués de activar Cake Size tenemos:
CAKE VARIATION
SKU
Title
Price
Cake SizeConceptualmente Commerce ha creado una relación:
Product Variation
│
└── Cake Size
↓
Attribute Value49. El field del Attribute vive en Variation
Esto es importante.
No estamos añadiendo:
Cake Sizeal Product.
Lo añadimos a:
Cake Variationporque:
Chocolate Cake
↓
Product
Chocolate Cake - Small
↓
VariationSize describe qué unidad comprable estamos seleccionando.
50. El Attribute será obligatorio por defecto
Normalmente, cuando añadimos un Product Attribute a un Variation Type, el field generado será obligatorio.
Esto tiene sentido:
Cake Variation
Size:
?no sería una Variation completamente definida en nuestro modelo.
Queremos:
Small
Medium
LargeCommerce permite convertir un Attribute en opcional modificando posteriormente los settings del field si el negocio lo necesita.
51. Añadir campos a Attribute Values
Una característica especialmente poderosa es que los Attribute Values también son fieldable entities.
Por ejemplo, podríamos enriquecer Cake Size.
Small
Approximate servings:
6
Medium
Approximate servings:
10
Large
Approximate servings:
16Podríamos añadir un field:
Approximate Servingsal Attribute Value.
Drupal Commerce permite añadir fields a los valores del Attribute como a otras entidades fieldable.
52. ¿Deberíamos hacerlo?
Debemos preguntarnos primero:
¿Las porciones dependen solamente del tamaño?
Si:
Small
always approximately 6 portions
Medium
always approximately 10
Large
always approximately 16entonces el Attribute Value puede ser un buen lugar.
Pero si depende también del tipo de pastel:
Chocolate Cake Medium
10 portions
Tall Wedding Cake Medium
20 portionsentonces no pertenece al Attribute Value global.
Puede pertenecer a la Variation.
53. Esta decisión muestra la importancia del alcance del dato
Podemos utilizar la pregunta:
¿En qué nivel sigue siendo este dato verdadero?
Por ejemplo:
Size name:
Medium
True globally
↓
Attribute Value
Price:
25 USD
Only true for a specific cake variation
↓
VariationEsta forma de pensar evita duplicación y errores.
54. Nuestro Cake ahora tiene esta arquitectura
CAKE PRODUCT
├── Title
├── Description
├── Category
├── Images
├── Ingredients
└── Allergens
CAKE VARIATION
├── SKU
├── Price
└── Cake Size
│
├── Small
├── Medium
└── LargeAhora ya tenemos todo lo necesario para crear:
Chocolate Cake
├── Small
│ SKU: CAKE-CHO-S
│ Price: 15 USD
│
├── Medium
│ SKU: CAKE-CHO-M
│ Price: 25 USD
│
└── Large
SKU: CAKE-CHO-L
Price: 40 USD55. ¿Y el sabor?
Recordemos que decidimos:
Chocolate Cake
Vanilla Cake
Carrot Cakeserán Products diferentes.
Por tanto no creamos:
Flavor Attributetodavía.
Nuestro modelo será:
Chocolate Cake
├── Small
├── Medium
└── Large
Vanilla Cake
├── Small
├── Medium
└── LargeEsto permite que cada receta tenga:
- Descripción propia
- Imágenes propias
- Ingredientes propios
- Alérgenos propios
56. ¿Cuándo cambiaríamos a Flavor Attribute?
Podría tener sentido si el negocio evoluciona hacia:
Product:
Birthday Cake
Attributes:
Flavor
├── Chocolate
├── Vanilla
└── Strawberry
Size
├── Small
├── Medium
└── LargeY si todas esas combinaciones representan Variations del mismo producto conceptual.
La arquitectura debe seguir al negocio.
57. ¿Y la decoración personalizada?
Supongamos que el cliente puede escribir:
"Feliz cumpleaños María"en el pastel.
No debemos crear un Attribute:
Decoration Textporque no conocemos los posibles valores previamente.
Tampoco queremos generar Variations infinitas.
Ese dato pertenece a la compra concreta.
Order Item
Custom Cake Message:
"Feliz cumpleaños María"Lo implementaremos más adelante mediante un Order Item field y el Add to Cart form.
58. Attribute Values deben ser conocidos previamente
Los Product Attributes funcionan especialmente bien cuando tenemos un conjunto conocido de opciones.
Por ejemplo:
Size
Small
Medium
LargeO:
Color
Black
White
BlueLa documentación de Commerce distingue este patrón de los productos configurables donde el comprador introduce datos únicos durante la compra.
59. Configurar Form Displays
Después de añadir nuestros fields debemos revisar:
Manage form displaypara cada Product Type.
Queremos que el formulario administrativo tenga un orden lógico.
Por ejemplo:
USED PRODUCT
Title
Description
Images
Category
Condition
Purchase Year
Visible Defects
Variation InformationLa interfaz administrativa forma parte de la calidad de nuestra arquitectura.
60. Form Display para Imported Product
Podríamos ordenar:
Title
Description
Images
Category
Brand
Country of Origin
Variation InformationEsto permite que el editor complete la información siguiendo una secuencia natural.
61. Form Display para Cake
Podemos utilizar:
Title
Description
Images
Category
Ingredients
Allergens
VariationsLas Variations pueden administrarse separadamente porque Cake permite múltiples Variations.
62. Configurar Manage Display
También debemos revisar:
Manage displayPor ejemplo, en Used Product podríamos mostrar:
Title
Images
Price
Condition
Description
Visible Defectsy ocultar información puramente administrativa.
Recordemos que Product y Variation pueden renderizarse conjuntamente mediante Variation field injection cuando está habilitada.
63. No todo field administrativo debe mostrarse
Por ejemplo:
Purchase Yearpodría ser información interna.
O quizás queramos mostrarla.
Lo importante es separar:
Data exists
↓
Field
Data is visible
↓
Display configurationNo necesitamos eliminar el field simplemente porque no queramos mostrarlo públicamente.
64. Crear campos reutilizables conscientemente
Nuestra arquitectura comienza a tener fields compartidos:
field_category
Used Product
Imported Product
Cake
field_images
Used Product
Imported Product
Cakey fields específicos:
field_condition
→ Used Product
field_visible_defects
→ Used Product
field_brand
→ Imported Product
field_ingredients
→ Cake
field_allergens
→ CakeEsto es una estructura mucho más limpia que crear fields duplicados para cada bundle.
65. Field Storage frente a Field Instance
Drupal separa conceptualmente:
Field Storage
↓
qué tipo de dato existe
Field Configuration
↓
cómo se utiliza en este bundlePor eso un mismo field storage puede utilizarse en diferentes Product Types cuando su semántica es compatible.
Al exportar configuración veremos esta diferencia reflejada en YAML.
66. Exportar configuración
Una vez terminada esta etapa:
drush cex -yDespués:
git statusy:
git diff --statAhora deberíamos observar muchos más cambios que en el artículo anterior.
67. Configuración de Taxonomy
Podemos encontrar archivos relacionados con:
taxonomy.vocabulary.product_category.yml
taxonomy.vocabulary.product_condition.yml
taxonomy.vocabulary.product_brand.yml
taxonomy.vocabulary.allergen.ymlLos términos concretos normalmente son contenido y no deben confundirse con la definición del Vocabulary.
De nuevo:
Vocabulary
= configuration
Terms
= content68. Configuración de Fields
También veremos archivos como:
field.storage.commerce_product.field_category.yml
field.field.commerce_product.used_product.field_category.ymlConceptualmente:
field.storage
↓
define el storage
field.field
↓
conecta el field
a un bundle concretoLos nombres exactos dependerán de los machine names elegidos.
69. Configuración de Media References
Para Images veremos configuración relacionada con:
field.storage.commerce_product.field_images.ymly las instancias correspondientes en nuestros Product Types.
También aparecerán cambios en:
core.entity_form_display
core.entity_view_displaysi configuramos widgets y formatters.
70. Configuración del Product Attribute
Después de crear:
Cake Sizedeberíamos encontrar configuración de Commerce relacionada con el Product Attribute.
También veremos el field que Commerce crea para:
Cake Variation
↓
Cake SizeEl machine name seguirá normalmente el patrón:
attribute_cake_sizeporque los Attributes se implementan mediante entity reference fields sobre Product Variations.
71. Los Attribute Values no son configuración
Existe una distinción interesante.
El Product Attribute:
Cake Sizees configuración.
Pero sus valores:
Small
Medium
Largeson entidades de contenido.
La documentación oficial describe Product Attribute como configuration entity y Product Attribute Value como content entity.
Esto es importante para deployment.
72. Una consecuencia práctica
Podemos exportar:
Cake Size
↓
Configpero no debemos asumir que:
Small
Medium
Largeaparecerán automáticamente como configuration YAML.
En un proyecto real debemos decidir cómo desplegaremos datos iniciales necesarios para el funcionamiento del sitio.
Podemos utilizar mecanismos como:
- Default content
- Migrations
- Update hooks
- Custom deployment logic
dependiendo del proyecto.
73. Esto también aplica a Taxonomy Terms
Exportamos:
Product Condition vocabularypero términos como:
Good
Fair
Like Newson contenido.
Si estos valores son obligatorios para que la aplicación funcione, debemos incluirlos en nuestra estrategia de instalación o deployment.
74. Este detalle es importante para proyectos reproducibles
Queremos poder instalar nuestro proyecto desde cero mediante algo similar a:
composer install
drush site:install
drush cim
...Pero si la configuración espera:
Cake Size
↓
Small / Medium / Largey esos valores no existen, nuestra instalación estará estructuralmente correcta pero funcionalmente incompleta.
Por tanto debemos distinguir:
Configuration dependencies
vs
Required initial content75. Modelo completo después de este artículo
HOME SHOP
│
├── USED PRODUCT
│ │
│ ├── Category → Taxonomy
│ ├── Condition → Taxonomy
│ ├── Images → Media
│ ├── Purchase Year → Field
│ ├── Visible Defects → Field
│ │
│ └── USED VARIATION
│ ├── SKU
│ └── Price
│
├── IMPORTED PRODUCT
│ │
│ ├── Category → Taxonomy
│ ├── Brand → Taxonomy
│ ├── Images → Media
│ ├── Country of Origin → Field
│ │
│ └── IMPORTED VARIATION
│ ├── SKU
│ └── Price
│
└── CAKE
│
├── Category → Taxonomy
├── Images → Media
├── Ingredients → Field
├── Allergens → Taxonomy
│
└── CAKE VARIATION
│
├── SKU
├── Price
│
└── Cake Size
│
├── Small
├── Medium
└── Large76. Nuestra matriz final
Podemos clasificar cada decisión tomada:
Product Category
→ Taxonomy
Product Condition
→ Taxonomy
Brand
→ Taxonomy
Allergen
→ Taxonomy
Images
→ Media
Visible Defects
→ Text Field
Purchase Year
→ Integer Field
Country of Origin
→ Structured Field
Ingredients
→ Text Field
Cake Size
→ Commerce Product AttributeCada herramienta tiene una responsabilidad distinta.
77. Regla para Taxonomy
¿Es un concepto reutilizable
para clasificar entidades?
↓
TaxonomyEjemplos:
Category
Brand
Condition
Allergen78. Regla para Field
¿Es simplemente información
estructurada de una entidad?
↓
FieldEjemplos:
Purchase Year
Visible Defects
Ingredients79. Regla para Media
¿Es un recurso multimedia
que queremos administrar
como entidad reutilizable?
↓
MediaEjemplo:
Product Images80. Regla para Product Attribute
¿El comprador selecciona
esta propiedad para determinar
qué Variation está comprando?
↓
Product AttributeEjemplo:
Cake SizeLa documentación oficial propone una regla muy similar: cuando una característica está asociada a una combinación específica de SKU/precio y debe aparecer como opción para seleccionar una Variation, encaja naturalmente como Product Attribute.
81. Checklist de esta etapa
Taxonomies
- Product Category
- Product Condition
- Product Brand
- Allergen
Used Product
- Category
- Condition
- Images
- Visible Defects
- Purchase Year
Imported Product
- Category
- Brand
- Images
- Country of Origin
Cake
- Category
- Images
- Ingredients
- Allergens
Product Attributes
- Cake Size
- Small
- Medium
- Large
Variation Types
- Cake Size añadido a Cake Variation
Display
- Form displays revisados
- View displays revisados
- Media Library configurada para Images
Configuration
- Config export ejecutado
- Field storage revisado
- Field instances revisadas
- Attribute configuration revisada
82. Lo que todavía no hemos hecho
Aunque nuestro modelo ya tiene mucha estructura, todavía no hemos creado productos reales.
Tampoco hemos configurado:
Inventory
Shipping weight
Dimensions
Stock
Checkout
Payment
Shipping
Taxes
PromotionsSeguiremos añadiendo cada concepto cuando tengamos una necesidad concreta.
Conclusión
En este artículo hemos convertido nuestros Product Types iniciales en un catálogo estructurado utilizando las herramientas apropiadas de Drupal.
La lección más importante no es cómo añadir un field.
Es aprender a escoger la estructura correcta.
Field
= dato de una entidad
Taxonomy
= clasificación reutilizable
Media
= recurso multimedia reutilizable
Product Attribute
= opción que determina
una Product VariationTambién hemos visto una distinción fundamental para proyectos Drupal reproducibles:
Vocabulary
= Configuration
Taxonomy Term
= Content
Product Attribute
= Configuration
Product Attribute Value
= ContentPor tanto, un proyecto profesional no debe pensar solamente en:
drush cexsino también en cómo proporcionar el contenido inicial imprescindible para que la configuración funcione.
En el siguiente artículo utilizaremos finalmente esta arquitectura para crear nuestros primeros productos reales.
Crearemos paso a paso:
Canon Camera usada
↓
Single Variation
↓
250 USD
USB-C Hub importado
↓
Single Variation
↓
35 USD
Chocolate Cake
↓
Multiple Variations
↓
Small / Medium / LargeAdemás estudiaremos cómo Commerce genera las Variations, cómo se utilizan SKU y Price, cómo funciona el selector de Attributes y qué ocurre internamente cuando visualizamos un Product.