Configurar el católogo en Drupal Commerce: Fields, Taxonomies, Media y Product Attributes

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 Variation

Ahora 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 USD

También:

IMPORTED PRODUCT

USB-C Hub

Brand:
Baseus

Category:
Electronics

Country of origin:
China

Price:
35 USD

Y:

CAKE

Chocolate Cake

Ingredients:
Chocolate, flour, eggs...

Allergens:
Eggs, milk, gluten

Sizes:
Small
Medium
Large

Aunque 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 Attribute

Esta 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 information

Drupal 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 Value

Por 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
└── Cakes

Un 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
          ↓
        Image

Esto 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
└── Large

El comprador selecciona:

Size:
Medium

y Commerce determina:

Product Variation

Chocolate Cake - Medium

SKU:
CAKE-CHO-M

Price:
25 USD

Este 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 vocabulary

Creamos:

Name:
Product Category


Machine name:
product_category

Después añadimos algunos términos:

Electronics

Photography

Furniture

Books

Food

Cakes

8. 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
└── Cakes

No 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 Category

si todos pertenecen al mismo sistema de clasificación.

Utilizaremos:

Product Category

como vocabulario compartido.

Por ejemplo:

Canon Camera usada
→ Photography


USB-C Hub
→ Electronics


Chocolate Cake
→ Cakes

10. Crear Product Condition

Los productos usados necesitan representar su estado.

Creamos:

Vocabulary:
Product Condition


Machine name:
product_condition

Valores iniciales:

Like New

Very Good

Good

Fair

For Parts

Esto 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 | Fair

Tambié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_origin

Con:

Used

Imported

Local Production

Esto nos permitirá clasificar:

Canon Camera
→ Used


USB-C Hub
→ Imported


Chocolate Cake
→ Local Production

13. Product Origin nos ayudará a revisar nuestra arquitectura

Recordemos que actualmente tenemos:

Used Product

Imported Product

como Product Types separados.

Pero ahora también tenemos:

Product Origin

Esto 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 fields

Añadimos un field:

Label:
Category


Machine name:
field_category


Field type:
Entity reference


Reference type:
Taxonomy term


Vocabulary:
Product Category

Normalmente 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
Cake

en lugar de crear:

field_used_category

field_imported_category

field_cake_category

sin ninguna necesidad.


16. Añadir Condition a Used Product

Ahora añadimos:

Label:
Condition


Machine name:
field_condition


Type:
Taxonomy term reference


Vocabulary:
Product Condition

Este field será obligatorio para los productos usados.

Por ejemplo:

Canon Camera usada

Condition:
Good

17. Añadir Product Origin

Podemos añadir también:

Origin

→ Product Origin taxonomy

Sin embargo aquí debemos pensar antes de configurar.

Para un Product Type llamado:

Used Product

el valor siempre será:

Used

Entonces almacenar:

Origin = Used

en 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 Product

entonces:

Origin = Used

puede 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_year

Para una implementación sencilla podemos utilizar un Integer field.

Ejemplo:

2021

No 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 references

Esto 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:

Image

Podemos revisarlo en:

Structure
→ Media types
→ Image

Conceptualmente contiene:

Media
   │
   ├── Name
   ├── Image file
   └── Metadata

Drupal 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:
Unlimited

Queremos poder tener:

Canon Camera usada

Images

├── front
├── back
├── side
└── defect detail

24. Configurar Media Library

En:

Manage form display

podemos seleccionar el widget:

Media Library

Esto proporciona una mejor experiencia editorial:

Add media
   ↓
Select existing image
or
Upload new image

En lugar de tratar cada archivo como un simple upload aislado.


25. Añadir Images a otros Product Types

Queremos reutilizar el mismo concepto:

field_images

en:

Used Product

Imported Product

Cake

Todos 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
└── Price

Este modelo ya nos permite crear un artículo usado bastante completo.


27. Configurar Imported Product

Ahora vamos a:

Imported Product
→ Manage fields

Reutilizamos:

Category

Images

Y añadiremos algunos fields específicos.


28. Brand

Un producto importado puede tener:

Brand:
Baseus

Podríamos utilizar:

Text field

pero si queremos construir un catálogo serio probablemente Brand es un concepto reutilizable.

Por ejemplo:

Brand

├── Anker
├── Baseus
├── Xiaomi
├── Ugreen
└── Generic

Por tanto crearemos una nueva Taxonomy.


29. Crear Product Brand

Creamos:

Vocabulary:
Product Brand


Machine name:
product_brand

Y algunos términos:

Anker

Baseus

Xiaomi

Ugreen

Generic

Después añadimos a Imported Product:

Brand

→ Taxonomy term reference
→ Product Brand

30. Brand como Taxonomy nos permitirá evolucionar

Más adelante podemos añadir fields al término Brand.

Por ejemplo:

Brand

Baseus

├── Logo
├── Website
├── Description
└── Country

Entonces una página de marca podría mostrar:

Baseus

Logo

Description

Products from this brand

Este 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:
China

Aquí 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

CN

representando 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_supplier

má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
└── Price

Más adelante Variation puede incorporar:

Stock

Weight

Dimensions

Attributes

cuando 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
Large

Empezaremos con los fields del Product.


35. Category

Reutilizamos:

field_category

y seleccionaremos:

Cakes

Esto permitirá integrar Cakes dentro del catálogo general.


36. Images

Reutilizamos:

field_images

con Media Library.

Por ejemplo:

Chocolate Cake

Images:

├── whole cake
├── slice
└── decoration detail

37. 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
└── Soy

Esto sugiere utilizar Taxonomy.


39. Crear Allergen

Creamos:

Vocabulary:
Allergen


Machine name:
allergen

Valores iniciales:

Gluten

Milk

Eggs

Nuts

Peanuts

Soy

Después añadimos al Cake:

Allergens

→ Taxonomy reference
→ Multiple values

Por ejemplo:

Chocolate Cake

Allergens:

Gluten
Milk
Eggs

40. 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 reutilizables

Si 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

Large

y cada opción puede tener:

Different SKU

Different Price

Possibly different weight

Por tanto Cake Size es un Product Attribute.


42. Crear Product Attribute

Vamos a:

Commerce
→ Product attributes

o directamente:

/admin/commerce/product-attributes

Seleccionamos:

Add product attribute

y creamos:

Label:
Cake Size


Machine name:
cake_size

Drupal 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 attribute

Para Cake Size podemos comenzar con:

Radio buttons

porque tenemos solamente tres opciones fáciles de entender.

Conceptualmente:

Size

( ) Small

( ) Medium

( ) Large

44. Crear Attribute Values

Dentro de Cake Size añadimos:

Small

Medium

Large

Y definimos su orden:

Small
  ↓
Medium
  ↓
Large

Los 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
   ↓
Terms

y:

Commerce Attribute

Product Attribute
   ↓
Attribute Values

Por ejemplo:

Vocabulary:
Product Condition

Terms:
Good
Fair
...

frente a:

Product Attribute:
Cake Size

Values:
Small
Medium
Large

Pero 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

        ↓

Taxonomy

Mientras:

CAKE SIZE

Used for:
Purchasable choice

Customer chooses variation?
Yes

Changes SKU?
Yes

Changes price?
Yes

        ↓

Product Attribute

Esta 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
→ Edit

En la sección de Attributes deberíamos encontrar:

Cake Size

Lo 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

Price

Después de activar Cake Size tenemos:

CAKE VARIATION

SKU

Title

Price

Cake Size

Conceptualmente Commerce ha creado una relación:

Product Variation
      │
      └── Cake Size
              ↓
      Attribute Value

49. El field del Attribute vive en Variation

Esto es importante.

No estamos añadiendo:

Cake Size

al Product.

Lo añadimos a:

Cake Variation

porque:

Chocolate Cake
        ↓
Product


Chocolate Cake - Small
        ↓
Variation

Size 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

Large

Commerce 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:
16

Podríamos añadir un field:

Approximate Servings

al 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 16

entonces 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 portions

entonces 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
        ↓
Variation

Esta 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
       └── Large

Ahora 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 USD

55. ¿Y el sabor?

Recordemos que decidimos:

Chocolate Cake

Vanilla Cake

Carrot Cake

serán Products diferentes.

Por tanto no creamos:

Flavor Attribute

todavía.

Nuestro modelo será:

Chocolate Cake
├── Small
├── Medium
└── Large


Vanilla Cake
├── Small
├── Medium
└── Large

Esto 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
└── Large

Y 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 Text

porque 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
Large

O:

Color

Black
White
Blue

La 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 display

para 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 Information

La 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 Information

Esto 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

Variations

Las Variations pueden administrarse separadamente porque Cake permite múltiples Variations.


62. Configurar Manage Display

También debemos revisar:

Manage display

Por ejemplo, en Used Product podríamos mostrar:

Title

Images

Price

Condition

Description

Visible Defects

y 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 Year

podría ser información interna.

O quizás queramos mostrarla.

Lo importante es separar:

Data exists
        ↓
Field


Data is visible
        ↓
Display configuration

No 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
Cake

y fields específicos:

field_condition
→ Used Product


field_visible_defects
→ Used Product


field_brand
→ Imported Product


field_ingredients
→ Cake


field_allergens
→ Cake

Esto 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 bundle

Por 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 -y

Después:

git status

y:

git diff --stat

Ahora 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.yml

Los términos concretos normalmente son contenido y no deben confundirse con la definición del Vocabulary.

De nuevo:

Vocabulary
= configuration


Terms
= content

68. Configuración de Fields

También veremos archivos como:

field.storage.commerce_product.field_category.yml

field.field.commerce_product.used_product.field_category.yml

Conceptualmente:

field.storage
        ↓
define el storage


field.field
        ↓
conecta el field
a un bundle concreto

Los 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.yml

y las instancias correspondientes en nuestros Product Types.

También aparecerán cambios en:

core.entity_form_display

core.entity_view_display

si configuramos widgets y formatters.


70. Configuración del Product Attribute

Después de crear:

Cake Size

deberíamos encontrar configuración de Commerce relacionada con el Product Attribute.

También veremos el field que Commerce crea para:

Cake Variation
        ↓
Cake Size

El machine name seguirá normalmente el patrón:

attribute_cake_size

porque 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 Size

es configuración.

Pero sus valores:

Small

Medium

Large

son 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
        ↓
Config

pero no debemos asumir que:

Small

Medium

Large

aparecerá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 vocabulary

pero términos como:

Good

Fair

Like New

son 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 / Large

y esos valores no existen, nuestra instalación estará estructuralmente correcta pero funcionalmente incompleta.

Por tanto debemos distinguir:

Configuration dependencies

vs

Required initial content

75. 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
                        └── Large

76. 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 Attribute

Cada herramienta tiene una responsabilidad distinta.


77. Regla para Taxonomy

¿Es un concepto reutilizable
para clasificar entidades?

        ↓

Taxonomy

Ejemplos:

Category

Brand

Condition

Allergen

78. Regla para Field

¿Es simplemente información
estructurada de una entidad?

        ↓

Field

Ejemplos:

Purchase Year

Visible Defects

Ingredients

79. Regla para Media

¿Es un recurso multimedia
que queremos administrar
como entidad reutilizable?

        ↓

Media

Ejemplo:

Product Images

80. Regla para Product Attribute

¿El comprador selecciona
esta propiedad para determinar
qué Variation está comprando?

        ↓

Product Attribute

Ejemplo:

Cake Size

La 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

Promotions

Seguiremos 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 Variation

También hemos visto una distinción fundamental para proyectos Drupal reproducibles:

Vocabulary
= Configuration


Taxonomy Term
= Content


Product Attribute
= Configuration


Product Attribute Value
= Content

Por tanto, un proyecto profesional no debe pensar solamente en:

drush cex

sino 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 / Large

Ademá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.