The template repository for the Store Framework course on Learning Lab.
daniel-beta / store-framework Goto Github PK
View Code? Open in Web Editor NEWHome Page: https://lab.github.com/vtex-trainings/store-framework
Home Page: https://lab.github.com/vtex-trainings/store-framework
Además de css, que ya se aprendió anteriormente, Store Framework ofrece otro tipo de personalización de diseño, proporcionada a partir de style.json
.
Todos los bloques de Store Framework utilizan las mismas definiciones semánticas de estilo, definidas usando Tachyons. En la práctica, esto significa que en lugar de tener que cambiar todos los fondos de los botones para usar el color que le interesa, apenas tiene que redefinir el color que tiene un background
de una action-primary
.
Las personalizaciones a través de style.json
tienden a tener un impacto mucho mayor que a través de css, pues, en general, mantienen la identidad visual de la tienda a lo largo de todas las páginas siendo necesarios pocos cambios. Por esta razón, siempre que sea posible, se debe utilizar esta herramienta, evitando así overhead de css innecesario.
style.json
styles/configs/style.json
puede ser confuso en un primer momento, por contener todas las definiciones de estilo que usan todos los bloques visuales de Store Framework. Sin embargo, un buen flujo para identificar qué estilos cambiar es mediante la inspección de elementos en el browser.
Por ejemplo, haga clic derecho en cualquier botón de la tienda y pulse inspeccionar.
Observando la barra lateral que abrió en Chrome es posible ver una serie de definiciones, una de estas es el color de background del botón (#0f3e99):
Además, si inspecciona en el momento en que está solamente pasando el mouse por encima del botón, descubrirá el color de hover (#072c75):
Si buscamos las ocurrencias de ambos colores en style.json
, los colores que descubrimos son, respectivamente, los usados para acción-primaria
en hover-background
y background
, por ejemplo. Esto nos da una mejor idea de dónde podemos encontrar otras ocurrencias de esta misma definición.
Para descubrir definiciones semánticas de texto y qué campos son editables, el proceso es el mismo que el anterior, podemos buscar atributos como tamaño de fuente, peso, familia.
En una cabecera nivel 1, por ejemplo, cuando inspeccionamos descubrimos que su tamaño se definió en 3 rem.
style.json
, reemplace todas las ocurrencias de los colores que encontramos, cambiando:El resultado final esperado debe ser semejante a este:
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Si echa un vistazo a su tienda actual, podrá ver que todos los componentes tienen estilos parecidos, incluso si usted no ha realizado ninguna personalización.
Todos estos, incluyendo el Info Card recién configurado, comparten valores preestablecidos para fuente, color de fondo, color principal, formato de los botones, etc.
Esto se debe al style.json
, archivo responsable de declarar valores genéricos de personalización para toda tienda del Store Framework.
Para crear una identidad propia para los componentes de su tienda, puede sobrescribir estos valores a través de personalizaciones de CSS.
Analizando el recipe para personalizaciones de tienda por CSS, percibimos que serán necesarios algunos pasos para aplicar el estilo propio que usted desea, como:
Cree un nuevo archivo dentro de la carpeta CSS
con el nombre vtex.{AppName}.css
.
Utilice el CSS Handle del componente que se personalizará dentro de este archivo siguiendo el formato a continuación:
.{CSSHandle} {
{PropriedadeDeCSS}: {ValorDesejado};
{PropriedadeDeCSS}: {ValorDesejado};
}
En ausencia de CSS Handles, aplicar CSS Selectors permitidos, como es el caso de :global(vtex-{componentName})
.
Para aplicar CSS en un bloque específico y no a todos los bloques de aquel tipo, se utiliza el recurso de blockClass, que aparece junto a los handles de css al inspeccionar el código. Los blockClass deben ser declarados como una prop en el bloque en cuestión, y luego hacer referencia en el archivo de estilo como se muestra a continuación:
.{CSSHandle}--{blockClass} {
{PropriedadeDeCSS}: {ValorDesejado};
{PropriedadeDeCSS}: {ValorDesejado};
}
Para descubrir los CSS Handles de un componente, como el Info Card, basta con acceder a la sección Customization
de su documentación.
De acuerdo con la descripción de CSS Handles y con el recipe de personalizaciones de tienda por CSS, pudimos implementar un ejemplo de Info Card personalizado, cambiando su título y la configuración del botón call to action al agregar el siguiente código al archivo vtex.store-components.css
dentro de /styles/css
:
.infoCardHeadline {
font-family: serif;
font-size: 2.25rem;
font-weight: normal;
color: gray;
border: 2px solid black;
padding: 24px;
}
.infoCardCallActionContainer :global(.vtex-button) {
color: white;
background-color: gray;
border: transparent;
}
.infoCardCallActionContainer :global(.vtex-button):hover {
color: gray;
background-color: blue;
border: transparent;
}
Puedes comprobar el efecto de los cambios realizados ejecutando el comando vtex link
.
En seguida, añadiremos un estilo específico al info card Vintage. Para empezar, agregue la prop blockClass
en el info-card#button-right
como se muestra a continuación:
"info-card#button-right": {
"props": {
"isFullModeStyle": false,
"textPosition": "right",
"imageUrl": "https://appliancetheme.vteximg.com.br/arquivos/cozinha-rosa-min.png",
"headline": "Vintage Pink",
"subhead": "Give your kitchen a boho style adding vintage apparels.<br>Available until January 2020.",
"callToActionMode": "button",
"callToActionText": "Explore",
"callToActionUrl": "/sale/d",
"textAlignment": "center",
"blockClass": "vintage" // <------------
}
}
Y entonces declare un background-color
para este info card específico en su archivo de css:
.infoCardContainer--vintage {
background-color: #edcfd1
}
Observe el efecto alcanzado al enlazar su app.
vtex.store-components.css
, copie el código anterior para usarlo en el archivo CSS de su tema, siguiendo el recipe sobre personalizaciones de tienda por CSS.max-width
) de todos los info cards en 1260px
, el margin en 0 auto
y el padding en 0
.black
.bold
) .white
.vintage
, aplique un nuevo block class llamado metal
en el info card info-card#button-left
y aplique el color de fondo de #e1e1e1
en este.¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Un Iframe es un elemento HTML que permite la incorporación de otra página HTML en la actual. De esta forma, a partir del bloque Iframe es posible incluir contenidos de otras URLs para que se muestren en nuestra página. Es importante recordar que las URLs renderizadas por Iframe poseen su propio contexto, teniendo un historial de sesión y DOM independientes de su página personalizada.
ATENCIÓN: Solo se permiten Iframes dentro de templates de custom pages.
El bloque iframe
tiene propiedades muy simples:
src
: indica cuál URL iframe debe renderizar.width
: anchura del elemento iframe en píxeles.height
: altura del elemento iframe.A continuación, vemos un ejemplo de implementación del bloque iframe
:
"store.custom#about-us": {
"blocks": [
"flex-layout.row#about-us",
"iframe"
]
},
"iframe": {
"props": {
"src": "http://someURL.com/resource",
"width": 100,
"height": 200
}
}
Vamos a mostrar una publicación de Instagram en nuestra tienda:
rich-text
e incluya un bloque iframe
.iframe
, muestre el contenido del link https://www.instagram.com/p/B973Qp8BacC/embed
en un container de 800px de anchura por 1000px de altura.ℹ️ Recuerde acceder a la documentación del Iframe si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
En este paso, terminaremos de construir nuestra página de producto. Aprenderemos cómo apilar bloques usando Stack Layout, cómo sugerir productos similares y cómo personalizar mejor el SKU Selector para productos con imagen de SKU.
Para probar este step, utilice la url del producto /3-colors-retro-stand-mixer/p
.
stack-layout
es un tipo de layout que permite apilar bloques sobre otros. Es muy útil cuando desea colocar un badge encima de una imagen o producto. También es útil para componer textos compuestos sobre imágenes (usando rich-text
e image
).
(En la imagen, un shelf apilado sobre un carrusel 👆)
En este paso, usaremos stack-layout
para colocar la marca sobre las imágenes de producto.
Evolucione la página de producto añadiendo los siguientes pasos al archivo product.jsonc
:
Declare un shelf.relatedProducts
debajo de la línea principal de producto.
"store.product": {
"children": [
"breadcrumb",
"flex-layout.row#main",
"shelf.relatedProducts"
]
}
/3-colors-retro-stand-mixer/p
.
Cambie product-images
en la columna de la izquierda por una declaración de stack-layout
.
"flex-layout.col#left": {
"children": [
"stack-layout#brand"
]
}
Defina el stack-layout
y coloque como hijos product-images
y product-brand
.
"stack-layout#brand": {
"children": [
"product-images",
"product-brand"
]
}
Consulte la documentación para cambiar la forma en que se muestra product-brand
. Debe hacer que el logo aparezca con una altura de 30 e incluir la prop displayMode: "logo"
.
Consulte la documentación para hacer que el sku-selector
:
image
como el valor de la prop, mostrado en la documentación.ℹ️ Recuerde acceder a la documentación del Stack Layout si tiene alguna duda durante la actividad.
ℹ️ Recuerde utilizar el producto /3-colors-retro-stand-mixer/p
para probar este paso.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Tab Layout es un paradigma de estructuración de layouts creado en Store Framework para permitir la construcción de layouts con pestañas.
En este paradigma tenemos dos containers: tab-list
y tab-content
. En cada uno de estos containers, tenemos los ítems que los componen. Dentro de tab-list
, tenemos los tab-list.item
. En tab-content
, tenemos los tab-content.item
.
A continuación, veremos un ejemplo de implementación de un tab layout.
En primer lugar, es necesario declarar el block tab-layout
en el template deseado:
{
"store.custom#about-us": {
"blocks": [
...
"tab-layout"
]
}
}
Después, es necesario declarar un tab-list
y un tab-content
como children del tab-layout
:
...
"tab-layout": {
"children": [
"tab-list",
"tab-content"
]
}
Con esto, tenemos estos dos containers como componentes de nuestro tab-layout
. El siguiente paso es declarar los tab-list.item
y tab-content.item
como children del tab-list
y tab-content
, respectivamente:
...
"tab-list": {
"children": [
"tab-list.item#1",
"tab-list.item#2"
]
}
...
"tab-content": {
"children": [
"tab-content.item#1",
"tab-content.item#2"
]
}
En la siguiente etapa, tenemos que declarar las propiedades de los tab-list.item
. El siguiente código genera una interfaz de tabs como la de esta imagen:
La propiedad tabId
es muy importante, pues es la llave que conecta el botón de un tab-list.item
con un tab-content.item
.
...
"tab-list.item#1": {
"props": {
"tabId": "majorAppliances",
"label": "Major Appliances",
"defaultActiveTab": true
}
},
"tab-list.item#2": {
"props": {
"tabId": "electronics",
"label": "Electronics"
}
}
A continuación, declararemos los children y las props de los tab-content.item
.
En el array de children, es posible incluir diversos blocks como rich-text
, info-card
, image
, flex-layout
y etc.
En la prop tabId
, es necesario incluir los mismos ids declarados en los tab-list.item
para que el enlace entre la pestaña y el contenido funcione.
...
"tab-content.item#1": {
"children": [
"rich-text#1"
],
"props": {
"tabId": "majorAppliances"
}
},
"tab-content.item#2": {
"children": [
"rich-text#2"
],
"props": {
"tabId": "electronics"
}
}
Por último, debe declarar las propiedades de su contenido. En nuestro ejemplo, colocamos apenas un rich-text
en cada tab-content.item
:
"rich-text#1": {
"props": {
"text": "Texto para Major Appliances",
"textPosition": "CENTER",
"font": "t-heading-3"
}
},
"rich-text#2": {
"props": {
"text": "Texto para Electronics",
"textPosition": "CENTER",
"font": "t-heading-3"
}
}
En esta actividad, crearemos la estructura simple de un tab layout, como en la siguiente imagen. Más adelante incluiremos algún contenido para estilizar nuestra página personalizada.
En el archivo about-us.jsonc
creado anteriormente, agregue un tab-layout#home
al template store.custom#about-us
.
Declare el bloque tab-layout#home
y agregue como sus children un tab-list#home
y un tab-content#home
.
Declare un tab-list#home
y agregue como sus children un tab-list.item#home1
y un tab-list.item#home2
.
Declare las props del tab-list.item#home1
de manera que la interfaz muestre el texto "Major Appliances". (Consejo: no olvide que incluir en las props un tabId
= "majorAppliances"
y la propiedad defaultActiveTab
= true
).
Declare las props de tab-list.item#home2
de manera que la interfaz muestre el texto "Electronics". (Consejo: no se olvide que incluir en las props un tabId
= "electronics"
).
Ahora, vayamos a la parte del contenido. Declare un tab-content#home
en su tema y agregue los children tab-content.item#home1
y tab-content.item#home2
.
En cada tab-content.item
, declare apenas un rich-text
como children (por ejemplo, rich-text#home1
y rich-text#home2
).
Después, incluya una prop tabId
en cada tab-content.item
de manera que se produzca el enlace entre el tab-list
creado anteriormente y tab-content
.
Por último, agregue los rich-text
y declare sus props de acuerdo con el siguiente código:
"rich-text#home1": {
"props": {
"text": "Área do conteúdo da tab-list.item com tabId = majorAppliances",
"textPosition": "CENTER",
"font": "t-heading-3"
}
},
"rich-text#home2": {
"props": {
"text": "Área do conteúdo da tab-list.item com tabId = electronics",
"textPosition": "CENTER",
"font": "t-heading-3"
}
}
ℹ️ Recuerde acceder a la documentación Tab Layout y Rich Text si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
El siguiente bloque que usaremos es Shelf, nuestro estante para una colección de productos. En esta sesión aprenderemos cómo renderizar y configurar este estante en el home de nuestra tienda.
Analizando la documentación de Shelf, vemos que es posible configurar cuál colección de productos queremos mostrar a través de las props category
, specificationFilters
o collection
, de acuerdo con los productos registrados en el catálogo.
Las demás props son para configuración en la manera en que se muestran los ítems. Es importante tener en cuenta que el componente shelf
siempre pide que un bloque del tipo product-summary
forme parte de su composición. Consulte la documentación del bloque product-summary para entender más sobre su funcionamiento.
A continuación, tenemos el ejemplo de la implementación de un Shelf:
{
"store.home": {
"blocks": [
...
"shelf"
]
},
...
"shelf": {
"blocks": ["product-summary.shelf"],
"props": {
"category": 1,
"orderBy": "OrderByTopSaleDESC",
"paginationDotsVisibility": "desktopOnly",
"productList": {
"maxItems": 10,
"itemsPerPage": 5,
"minItemsPerPage": 1,
"scroll": "BY_PAGE",
"arrows": true,
"titleText": "Top sellers"
}
}
},
"product-summary.shelf": {
"children": [
"product-summary-image",
"product-summary-add-to-list-button",
"product-summary-name",
"product-rating-inline",
"product-summary-space",
"product-summary-price",
"product-identifier.summary",
"product-summary-buy-button"
]
}
}
home.jsonc
, declare un componente shelf
en el template store.home
.shelf.jsonc
.shelf.jsonc
, defina el bloque shelf
con todas las props propuestas en el ejemplo anterior.8
.4
.Nota: Es importante tener en cuenta que el bloque product-summary.shelf
ya está declarado dentro del archivo default.jsonc
. Por esta razón, no fue necesario declararlo en esta actividad.
ℹ️ Recuerde acceder a la documentación del Shelf si tiene alguna duda durante la actividad.
El resultado final esperado debe ser semejante a este:
Si estas utilizando su propia cuenta VTEX, asegúrese de que la categoría 1
sea funcional y activa.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
En este paso, aprenderemos a configurar el primer componente de toda tienda: el Header.
El Header tiene un papel muy importante en la página inicial de la tienda, porque es responsable de albergar otros bloques esenciales para la navegación del usuario, como la barra de búsqueda y el menú.
El bloque del Header es responsivo; es decir, puede ser configurado para adaptarse a diferentes dispositivos, como desktop y mobile.
A continuación, podemos ver un ejemplo de implementación:
{
"header": {
"blocks": [
"header-layout.desktop",
"header-layout.mobile"
]
},
"header.full": {
"blocks": [
"header-layout.desktop",
"header-layout.mobile"
]
},
"header-layout.desktop": {
"children": [
"header-row#notification",
"header-row#main"
]
},
"header-layout.mobile": {
"children": [
"header-row#notification",
"header-row#main-mobile",
"header-row#search"
]
},
}
Ahora, vamos a configurar desde cero un Header para la página inicial de su tienda, con barra de notificación y búsqueda, logo, carrito y login. El Menú no se configurará en este momento, porque trabajaremos con este más a fondo en la próxima actividad.
Para la implementación del Header con todos estos bloques, tendremos en cuenta el código de ejemplo presentado anteriormente. Así, será posible construir un Header responsivo, adaptable para usuarios de desktop y mobile.
A diferencia del comportamiento de otros bloques, el Header no tiene que declararse dentro de un template de su tema, pues de todos modos será renderizado en todas las páginas de la tienda. En este ejercicio, vamos a declarar los bloques del header
en el archivo header.jsonc
, que debe crearse en la carpeta store/blocks
.
Luego, declare el siguiente bloque:
"header-row#notification": {
"children": [
"header-spacer",
"rich-text#header",
"header-spacer"
]
},
Basado en el bloque anterior, construya el header-row#main
con los siguientes children: logo
, header-spacer
, search-bar
, minicart
y login
.
Todavía en el bloque header-row#main
, declare las props inverted
, sticky
y fullWidth
con los valores true
, true
y false
, respectivamente.
Copie y pegue el siguiente código para configurar el bloque header para mobile, de la misma forma en que lo hicimos anteriormente para desktop:
"header-row#main-mobile": {
"children": [
"logo",
"header-spacer",
"minicart",
"login"
],
"props": {
"sticky": true,
"inverted":true
}
},
"header-row#search": {
"children": [
"search-bar"
],
"props": {
"sticky": true
}
},
Declare el bloque responsable por definir el login y el logo de la tienda, usando el código presentado a continuación. Estos serán utilizados por el Header de ambos dispositivos.
"login":{
"props": {
"showIconProfile": true,
"iconLabel": "Login"
}
},
"logo":{
"props": {
"url": "https://appliancetheme.vteximg.com.br/assets/vtex.file-manager-graphql/images/flatflat___6081e50402943bcb11bc45a8e613aa72.png"
}
},
Por último, debemos declarar el componente principal de la línea del Header de notificación ("header-row#notification"
): el Rich Text.
"rich-text#header": {
"props": {
"text": "**Free Shipping on orders over $50**",
"textPosition": "CENTER"
}
}
Siguiendo el recipe sobre personalizar íconos de tienda, reemplace el ícono predeterminado utilizado en la barra de búsqueda y el carrito por los que se muestran a continuación.
Nuevo ícono de la barra de búsqueda:
<path fill="currentColor" d="M4,13H1c-0.552,0-1-0.448-1-1v0c0-0.552,0.448-1,1-1h3V13z"></path> <path fill="currentColor" d="M15,3H1C0.448,3,0,2.552,0,2v0c0-0.552,0.448-1,1-1h14c0.552,0,1,0.448,1,1v0C16,2.552,15.552,3,15,3z"></path> <path fill="currentColor" d="M4,8H1C0.448,8,0,7.552,0,7v0c0-0.552,0.448-1,1-1h3V8z"></path> <path fill="currentColor" d="M15.707,13.293l-2.274-2.274C13.785,10.424,14,9.74,14,9c0-2.206-1.794-4-4-4S6,6.794,6,9 s1.794,4,4,4c0.74,0,1.424-0.215,2.019-0.567l2.274,2.274L15.707,13.293z M10,11c-1.103,0-2-0.897-2-2s0.897-2,2-2s2,0.897,2,2 S11.103,11,10,11z"></path>
Nuevo ícono del carrito:
<path fill="currentColor" d="M15,6h-1.4l-2.7-5.4C10.6,0.1,10-0.1,9.6,0.1C9.1,0.4,8.9,1,9.1,1.4L11.4,6H4.6l2.3-4.6 c0.2-0.5,0-1.1-0.4-1.3C6-0.1,5.4,0.1,5.1,0.6L2.4,6H1c-1.1,0-1.1,1-0.9,1.4l3,8C3.2,15.7,3.6,16,4,16h8c0.4,0,0.8-0.3,0.9-0.6l3-8 C16.1,7,16,6,15,6z"></path>
Al concluir el paso 8, los nuevos íconos de la barra de búsqueda y el carrito deben estar renderizados en su tienda de la siguiente forma:
ℹ️ Recuerde acceder a la documentación del Header si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
La página inicial de un e-commerce es siempre el primer contacto del cliente con la marca. Por lo tanto, es común que el administrador de la tienda quiera establecer una comunicación directa con sus usuarios en este momento estratégico de la navegación.
En el Store Framework, existen algunos componentes que atienden a este escenario, como el Info Card visto en los pasos anteriores y el Rich Text.
Como vimos en el tercer paso, Rich Text es responsable de transformar textos en elementos HTML, con la gran ventaja de leer en Markdown. Esto da al componente la flexibilidad de aceptar diferentes estructuras de texto, permitiendo al administrador de la tienda construir su comunicación de forma más clara y directa.
Así como su funcionalidad, la configuración de Rich Text también es simple.
De la misma forma en que se hizo el "Hello, world!", podemos crear un ejemplo de implementación del bloque usando texto escrito en markdown. Por ejemplo:
"rich-text": {
"props": {
"text": "# Your Coffee, Your Way \n ### New Coffee Makers Collection",
"textPosition": "CENTER",
"textAlignment": "CENTER"
}
},
Como se mencionó anteriormente, el uso de Markdown permite flexibilidad al componente. Pero, por otro lado, también puede hacer que su renderización sufra alteraciones de acuerdo con el dispositivo utilizado por el usuario.
Por ejemplo, la frase anterior ( # Your Coffee, Your Way \n ### New Coffee Makers Collection
) puede utilizar un markdown adecuado para desktop, pero no necesariamente para mobile (cuyo tamaño de pantalla es menor).
Para resolver este escenario y hacer que el componente sea más adaptable a otros dispositivos, debemos usar Responsive Layout.
Primeramente, debemos declarar los bloques dentro del template store.home
:
"responsive-layout.desktop#desktop" "responsive-layout.mobile#mobile"
En seguida, debemos declarar estos bloques de la siguiente forma:
...
"responsive-layout.desktop#desktop": {
"children": ["rich-text#desktop"]
},
"responsive-layout.mobile#mobile": {
"children": ["rich-text#mobile"]
},
"rich-text#desktop": {
"props": {
"text": "# Your Coffee, Your Way \n ### New Coffee Makers Collection",
"textPosition": "CENTER",
"textAlignment": "CENTER"
}
},
"rich-text#mobile": {
"props": {
"text": "# Your Coffee, Your Way \n ### New Coffee Makers Collection",
"textPosition": "CENTER",
"textAlignment": "CENTER"
}
}
Al interpretar el código anterior, perciba cómo se construyen dos configuraciones de Rich Text a partir del uso de responsive-layout.desktop#desktop
y responsive-layout.mobile#mobile
.
En esta actividad, juguemos un poco con el markdown del Rich Text y aprendamos a usarlo con el componente Image. Todo esto usando Responsive Layout, ¡está claro!
Agregue el código propuesto anteriormente en el archivo home.jsonc
y declare los bloques de responsive-layout
en el template store.home
.
En rich-text#mobile
, altere el markdown de la primera frase a h3
y de la segunda a h4
.
Si aún no se acuerda de la sintaxis de Markdown, es posible consultarla en Markdown Documentation.
Agregue image#desktop
como children de responsive-layout.desktop#desktop
. Haga lo mismo con image#mobile
en responsive-layout.mobile#mobile
.
Declare los siguientes bloques de Image:
"image#desktop": {
"props": {
"src": "https://appliancetheme.vteximg.com.br/arquivos/Responsive-Image-Desktop.jpg?q=1",
"link": {
"url": "/small-appliances/coffee-makers"
} ,
"alt": "Coffee Makers Collection"
}
},
"image#mobile": {
"props": {
"src": "https://appliancetheme.vteximg.com.br/arquivos/Responsive-Image-Mobile.jpg?q=1",
"link": {
"url": "/small-appliances/coffee-makers"
} ,
"alt": "Coffee Makers Collection"
}
},
Analizando las props del componente Image, defina la anchura máxima de las dos imágenes como 100%
.
ℹ️ Recuerde acceder a la documentación del Responsive Layout si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Una tienda necesita un buen home page para mantener la atención del usuario, aumentando el tiempo de sesión y, por lo tanto, aumentando las posibilidades de conversión. Para que esto sea posible, se pueden usar varios elementos, como: banners promocionales, estantes de destaque, contenidos institucionales.
Crearemos el siguiente bloque en el home page usando un Call to Action. En el Store Framework, tenemos un bloque que sirve para este propósito llamado Info Card.
Con el Info Card, es posible crear imágenes con enlaces y botones (en la parte superior o lateral del bloque) que dirigen el flujo del usuario (Call to Action).
Revisando la documentación es posible ver que:
isFullModeStyle
define si el Call to Action (CTA) debe estar arriba del banner.textPosition
definirá la posición del texto.textAlignment
definirá el alineamiento del texto.imageUrl
definirá cuál imagen será usada como banner.headline
determinará cuál es el texto que será usado de título.callToActionMode
permitirá elegir el CTA como un enlace o un botón.callToActionText
definirá el texto del CTA.callToActionUrl
determinará el enlace al que será dirigido.Así, quedamos con las siguientes props:
{
"store.home": {
"blocks": [
"rich-text",
"info-card"
]
},
"rich-text": {
"props": {
"text": "*Hello, World!*",
"textPosition": "RIGHT"
}
},
"info-card": {
"props": {
"isFullModeStyle": false,
"textPosition": "right",
"imageUrl": "https://appliancetheme.vteximg.com.br/arquivos/cozinha-rosa-min.png",
"headline": "Vintage Pink",
"subhead": "Give your kitchen a boho style adding vintage apparels.<br>Available until January 2020.",
"callToActionMode": "button",
"callToActionText": "Explore",
"callToActionUrl": "/sale/d",
"textAlignment": "center"
}
}
}
Puede ser que usted se haya preguntado:
"¿Y si quiero tener dos Info Cards con apariencias diferentes?"
Esto es posible a través de la instanciación de bloques.
Todos los bloques tienen nombres preestablecidos, pero puede crear instancias de estos y definir apariencias diferentes para el mismo tipo de bloque. Para hacer esto, simplemente coloque un #
con un nombre arbitrario y que tenga sentido después de definir cada bloque, por ejemplo:
{
"store.home": {
"blocks": [
"rich-text",
"info-card#button-right"
]
},
...
"info-card#button-right": {
"props": {
"isFullModeStyle": false,
"textPosition": "right",
"imageUrl": "https://appliancetheme.vteximg.com.br/arquivos/cozinha-rosa-min.png",
"headline": "Vintage Pink",
"subhead": "Give your kitchen a boho style adding vintage apparels.<br>Available until January 2020.",
"callToActionMode": "button",
"callToActionText": "Explore",
"callToActionUrl": "/sale/d",
"textAlignment": "center"
}
}
}
ATENCIÓN Durante el curso se verán varios
...
, esta parte no debe copiarse y representa el progreso de steps anteriores.
A partir del código anterior, en el archivo home.jsonc
, cree el info-card#button-left
justo debajo del infocard info-card#button-right
. Este nuevo infocard debe contener:
Shining chrome
.Go to Collection
en el lugar del botón.https://appliancetheme.vteximg.com.br/arquivos/cozinha-cinza-min.png
.Give your kitchen a cool style adding warm metallic finishes.<br>Available until January 2020.
textPosition
).El resultado esperado es semejante al que se presenta en la siguiente imagen:
ℹ️ Recuerde acceder a la documentación del Info Card si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Flex Layout es un paradigma de estructuración de layout creado en el Store Framework para permitir la construcción de layouts complejos. Este paradigma utiliza el concepto de líneas y columnas para definir la estructura y la colocación deseadas de los bloques en una determinada página.
Hay dos bloques de construcción básicos de cada Flex Layout:
flex-layout.row
flex-layout.col
Si ya está familiarizado con Flexbox utilizado en CSS, Flex Layout debería ser fácil de entender, pues flex-layout.row y flex-layout.col utilizan Flexbox por debajo.
Con Flex Layout es posible crear layouts personalizados, utilizando la estructura de líneas y columnas de Flexbox.
Analizando la documentación del bloque, vemos que puede utilizar cualquier array de bloques como children
de Flex Layout. Además, siempre debe usar flex-layout.row
y flex-layout.col
, NUNCA flex-layout
de forma aislada.
A continuación, tenemos un ejemplo de flex layout compuesto de un flex-layout.row
con dos children: un info-card
y un rich-text
:
"flex-layout.row":{
"children": [
"info-card#rethink",
"rich-text#deletar"
]
},
"info-card#rethink": {
"props": {
"imageUrl": "https://appliancetheme.vteximg.com.br/arquivos/utensilios-cozinha-min.png",
"isFullModeStyle": true,
"headline": "Time to rethink your kitchen",
"callToActionText": "Discover",
"textPosition": "center"
}
},
"rich-text#deletar": {
"props": {
"text": "I'll be deleted soon"
}
}
Declare el flex-layout.row
dentro de los blocks
del template de store.home
y declare los bloques propuestos arriba en su archivo home.jsonc
.
Altere los children de flex-layout.row
reemplazando el bloque rich-text
por una columna flex-layout.col
.
Elimine el bloque de rich-text
propuesto arriba de su tema.
Declare el bloque flex-layout.col
en su archivo home.jsonc
con dos componentes de imagen como children: image#electronics
y image#major-appliance
, en este orden.
Defina los bloques image
con las siguientes props:
...
"image#electronics": {
"props": {
"src": "https://appliancetheme.vteximg.com.br/assets/vtex.file-manager-graphql/images/electronics_banner___25d69b49f8224b369375e68513b4d593.png",
"maxWidth": "100%"
}
},
"image#major-appliance": {
"props": {
"src": "https://appliancetheme.vteximg.com.br/assets/vtex.file-manager-graphql/images/major_appliance_banner___bb10093866a127345ddfbcca3efa5022.png",
"maxWidth": "100%"
}
}
El resultado obtenido debe ser semejante a este:
ℹ️ Recuerde acceder a la documentación de Flex Layout si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Las tiendas están compuestas de varias páginas diferentes, cada una con layout y contenido específicos. Al crear una tienda desde cero en VTEX IO, algunas páginas estándar con URLs predefinidas ya están disponibles para usted. A continuación, se muestra una lista de algunas de estas páginas estándar:
store.home
�(Home page).store.product
(Product page).store.search
(Search Results page).store.account
(Client Account page).store.login
(Login page).store.orderplaced
(Order Placed page).Pero es posible que desee crear un landing page personalizado. En este caso, debe crear una nueva URL y contenido específico para mostrar a los usuarios que acceden a esta ruta.
Se necesitan pocos pasos para crear un landing page personalizado:
Un template define el layout de la página. Por lo tanto, si desea crear una página personalizada, también debe crear un nuevo template en su tema.
Supongamos que desea crear una página sencilla con información sobre su tienda. Dentro de la carpeta blocks
, usted puede crear un archivo que contenga el siguiente código, declarando un nuevo template para una página personalizada.
{
"store.custom#{templatename}": {
"blocks": [
]
}
}
Donde {templateName}
debe reemplazarse con el nombre identificador del template.
A continuación, debe completar el código con los componentes necesarios para armar el layout. Abajo, vemos un ejemplo de esta implementación:
{
"store.custom#{templatename}": {
"blocks": [
"flex-layout.row#about-us"
]
},
"flex-layout.row#about-us": {
"children": [
"image#about-us",
"flex-layout.col#text-about-us"
]
},
"flex-layout.col#text-about-us": {
"children": [
"rich-text#about-title",
"rich-text#about-content"
],
"props": {
"preventVerticalStretch": true
}
},
"rich-text#about-title": {
"props": {
"text":
"# Sobre a FlatFlat"
}
},
"rich-text#about-content": {
"props": {
"text":
" FlatFlat é uma loja de eletro eletrônicos com muita tradição na fabricação de itens modernos e vintage. Nosso objetivo é criar eletrodomésticos que tornem as casas dos nossos clientes interessantes, independente do estilo. Com apenas 2 meses de história, já somos a loja com os produtos mais bonitos de toda a VTEX. Estamos construindo o nosso site nesse momento com o intuito de dar ao nosso cliente uma experiência memorável com a nossa marca!"
}
},
"image#about-us": {
"props": {
"src": "https://appliancetheme.vteximg.com.br/arquivos/cozinha-about-us.png",
"maxHeight": "600px"
}
}
}
Ahora que se ha definido en el código del tema de la tienda un nuevo template con el layout de la página, el siguiente paso es definir la ruta (path) de la página que accederá a este layout.
Debemos crear un archivo routes.json
dentro de la carpeta store
de su tema. Después de esto, ingrese el código a continuación:
{
"store.custom#about-us": {
"path": "/{URL}"
}
}
Donde {URL}
es el nombre del camino deseado.
Crearemos una página con información sobre su tienda como el ejemplo de abajo:
blocks
, cree un archivo about-us.jsonc
.store.custom#about-us
en este archivo.flex-layout.row
, utilice el código del ejemplo dado anteriormente para completar el layout de la página.store
, cree un archivo routes.json
./about-us
.{workspace}--appliancetheme.myvtex.com/about-us
para ver su nuevo landing page.¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Como vimos en el último paso, un Submenú acepta como children cualquier bloque del Store Framework.
A partir de este entendimiento, podemos mejorar la configuración del Menú realizada en la actividad anterior, aumentando su contenido utilizando Flex Layout.
De acuerdo con lo que se practicó en la actividad anterior y lo que se aprendió sobre Flex Layout, apliquemos Flex Layout en el Submenú de Major Appliance.
En el archivo menu.jsonc
, remueva el bloque de código en que son definidos [email protected]:submenu#major
y suyos hijos. Este bloque será declarado en un nuevo archivo pronto:
"[email protected]:submenu#major": {
"children":[ "[email protected]:menu#major" ]
},
"[email protected]:menu#major": {
"children": [
"menu-item#refrigerators",
"menu-item#ovens",
"menu-item#washers"
],
"props": {
"orientation": "vertical"
}
},
Crea el archivo menu-flex.jsonc
, el bloque de código arriba necesita estar en esto archivo; flex-layout.row#major
estará en la lista de children del bloque [email protected]:submenu#major
y defina como:
{
...
"flex-layout.row#major": {
"children": [
"flex-layout.col#menu",
"flex-layout.col#img"
]
},
...
}
``
Ahora tenemos que declarar los bloques definidos en flex-layout.row#major
. Para comenzar, declare el bloque flex-layout.col#menu
con [email protected]:menu#major
como children.
Haga lo mismo para el bloque flex-layout.col#img
, declarándolo con image#menu
y rich-text#header
como children y las siguientes props:
...
"props":{
"paddingRight": 4,
"horizontalAlign": "right"
}
...
Por último, declaremos el image#menu
pasado como children en el último paso. Para esto, use el siguiente código:
...
"image#menu": {
"props": {
"src": "https://appliancetheme.vteximg.com.br/arquivos/menu-washer.jpg",
"link": {
"url": "/small-appliances/coffee-makers"
},
"alt": "Coffee Makers Collection",
"maxWidth": "200px"
}
}
ℹ️ Recuerde acceder a la documentación del Flex Layout y del Menú si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Slider Layout, como Flex Layout, es una forma flexible de crear un nuevo bloque a partir de otros bloques usando children
. Este permite que se creen sliders de otros bloques, como info-card
s e incluso flex-layout
s, por ejemplo.
Utilizaremos Slider Layout para convertir un conjunto de info-cards en un slider.
Analizando la documentación, vemos que usted puede utilizar cualquier array de bloques como children
, así como en el Flex Layout.
A continuación, sigue un ejemplo de implementación de un slider-layout con dos info-card
:
"slider-layout#home": {
"children": ["info-card#1", "info-card#2"],
"props": {
"autoplay": {
"timeout": 5000,
"stopOnHover": false
}
}
},
"info-card#1": {
"props": {
"imageUrl": "https://images.unsplash.com/photo-1524185962737-ea7c028a12cd?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80",
"isFullModeStyle": true,
"headline": "Black Friday",
"callToActionText": "Subscribe",
"textPosition": "center"
}
},
"info-card#2": {
"props": {
"imageUrl": "https://images.unsplash.com/photo-1524185962737-ea7c028a12cd?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80",
"isFullModeStyle": true,
"headline": "Black Friday",
"callToActionText": "Subscribe",
"textPosition": "center"
}
}
En esta actividad, crearemos un slider de marcas para nuestro sitio web:
En el archivo home.jsonc
, declare el bloque slider-layout#home
al template store.home
.
Cree un archivo llamado slider-layout.jsonc
dentro de la carpeta /store/blocks
.
En este archivo, basado en el código anterior, reemplace los info-card
declarados como children de slider-layout#home
y agregue 6 componentes de imagen image
como children. Utilice el formato image#brand1
, image#brand2
(...) image#brand6
para declarar los componentes.
Declare una prop src
específica para cada image#brand
definido. Utilice las siguientes URLs para cada una:
https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square1.png
https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square2.png
https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square3.png
https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square4.png
https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square5.png
https://appliancetheme.vteximg.com.br/arquivos/flatflat-brand-logo-square6.png
Por último, usted debe utilizar la propriedad de autoplay
en el bloque slider-layout#home
. Haga que el slide cambie automáticamente cada 7 segundos y que se detenga cuando el usuario pase el mouse encima del slide.
ℹ️ Recuerde acceder a la documentación del Slider Layout e Image si tiene alguna duda durante la actividad.
Antes de comenzar a poner manos a la obra y aprender más sobre el Store Framework de VTEX IO, usted debe realizar algunas configuraciones básicas, como:
A continuación, consulte el procedimiento para cada una de estas configuraciones:
Instale Git en su computadora accediendo al siguiente enlace y seleccionando el software usado por su computadora (Windows, MAC o Linux):
Toolbelt es la herramienta de línea de comando de VTEX IO. Este le permite realizar cualquier actividad en la plataforma, como crear un nuevo workspace de desarrollo, iniciar sesión en una cuenta VTEX, desarrollar nuevas apps, gestionar las ya existentes, etc.
Dado que Toolbelt es el que establece la comunicación entre el desarrollador y la plataforma, usted lo necesitará para lograr realizar todas las actividades propuestas durante el curso de Store Framework.
npm i -g vtex
en su terminal si usted está trabajando de un Windows y yarn global add vtex
en MAC.Usted puede ejecutar el comando vtex-v
(Windows) o vtex
(MAC) para confirmar si la instalación de Toolbelt ocurrió como se esperaba.
Con la instalación concluida, su próximo paso debe ser iniciar sesión en una cuenta VTEX.
Ejecute el comando vtex login contaVTEX
en su terminal, reemplazando contaVTEX
con el nombre real de la cuenta en la que desea trabajar. Por ejemplo, vtex login appliancetheme
.
Una vez que haya iniciado sesión, ejecute el comando vtex whoami
para confirmar en qué cuenta y workspace usted está.
Workspaces no son más que espacios de trabajo. En la plataforma VTEX IO, las cuentas tienen tres tipos principales de workspaces: master, de producción y desarrollo.
El siguiente paso hará que se cree un workspace de desarrollo para usted, permitiendo que las configuraciones realizadas en las actividades del curso no cambien la versión pública final de la tienda.
vtex use nome-do-workspace
, reemplazando nome-do-workspace
con el nombre deseado. Por ejemplo, vtex use devworkspace
.Una vez creado su workspace, podrá acceder a este desde el enlace https://{workspace}--{cuenta}.myvtex.com
, reemplazando {workspace}
y {cuenta}
con el workspace creado anteriormente y el nombre de la cuenta, respectivamente. Por ejemplo, https://devworkspace--appliancetheme.myvtex.com
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Con todas las configuraciones básicas completadas, ¡usted está listo para comenzar el curso!
En el step anterior, pudo aprender un poco más sobre cómo crear un template personalizado. Es muy común que, en escenarios de promoción y fechas conmemorativas, sea necesario crear landing pages especiales.
Vimos que la búsqueda infiere lo que necesita por el contexto en que se incluye. En una página personalizada, sin embargo, el contexto no existe y es necesario definir cuál query se debe realizar para inferir los resultados. Todo esto es posible a través de search-result-layout.customQuery
.
Query schema es una de las props de search result custom query
con el que puede controlar la búsqueda que debería hacer nuestro landing page. Para conocer todas las posibilidades de query schema, vea su documentación aquí.
Defina una ruta nueva (store.custom#landing
) en el archivo routes.json
.
"store.custom#landing": {
"path": "/landing"
}
Cree un nuevo archivo en la carpeta de bloques llamado search-landing.jsonc
.
Cree un nuevo template custom store.custom#landing
.
Defina el bloque image
como uno de los bloques de este template. Este bloque debe tener props minWidth
de 100% y una imagen de su elección.
Haga lo mismo con search-result-layout.customQuery
:
{
"store.custom#landing": {
"blocks": [
"image#landingbanner",
"search-result-layout.customQuery"
]
}
}
Defina el bloque search-result-layout.customQuery
con prop de querySchema que:
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Antes de comenzar a poner manos a la obra, veamos algunos conceptos importantes a los que se hará referencia de forma recurrente a partir de ahora.
Store Framework es una herramienta commerce low-code de construcción de frentes de tienda únicas y personalizadas.
El flujo de construcción es mediante la personalización de un tema que se puede trabajar en diferentes workspaces sin impactar el ambiente de producción.
Un tema es, esencialmente, un arreglo de bloques y sus posiciones. En este se definen todas las personalizaciones, posiciones y estilos de cada uno de los bloques que lo componen. También es posible declarar nuevas páginas en un tema que, en el futuro, pueden representar páginas institucionales o landing pages promocionales (día de la madre, black friday, cyber monday). El resultado final de un tema y el contenido que lo compone es el frente de una tienda.
Los bloques son la abstracción mínima en el Store Framework. Estos declaran pequeñas piezas que componen el layout de una tienda. Por más simples que parezcan, los bloques tienen un alto poder de personalización, lo que permite que sea posible alcanzar diseños complejos. Hay cuatro niveles de personalización para los bloques:
Ambientes de trabajo protegidos que representan una copia muy cercana a lo que existe en producción, permitiendo la evolución de los temas sin afectar nada en la tienda.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Como hemos visto, Markdown es un lenguaje de marcado amigable que se puede convertir fácilmente a HTML. En esta lección, veremos cómo puede usar este lenguaje en nuestro bloque Rich Text para crear textos interesantes.
Para incluir textos en el bloque de rich-text
, es necesario utilizar la prop text
:
"rich-text#home1": {
"props": {
"text": "Mi texto",
"textPosition": "LEFT",
"textAlignment": "LEFT"
}
La prop text
acepta el formato de markdown. Por lo tanto, si usted desea escribir su texto utilizando este lenguaje, su código debería quedar semejante a este:
```json
"rich-text#home1": {
"props": {
"text": "# Meu título h1 \n Escreva aqui um parágrafo \n ## Meu título h2 \n Escreva aqui seu segundo parágrafo \n Inclua aqui uma lista \n - Item 1 \n - Item 2 \n - Item3",
"textPosition": "LEFT",
"textAlignment": "LEFT"
}
CONSEJO: Utilice siempre el comando \n
para saltar líneas al utilizar markdown en la prop text
.
Otras propiedades del componente rich-text
pueden encontrase en la documentación oficial del Store Framework.
Dentro del archivo about-us.jsonc
, cambie el texto de tab-list.item#home1
para que aparezca un "Sobre" en la primera pestaña.
En el contenido rich-text
asociado a esta pestaña, utilice el siguiente texto:
# Nossa História \n ### Nascemos de uma hackathon interna da VTEX! \n Isso mesmo. A primeira Hackatheme (hackathon de temas de loja) da VTEX teve 3 finalistas. Um deles foi a FlatFlat, essa loja que vocês estão acessando agora. A FlatFlat foi criada pelos engenheiros Afonso Praça e Sávio Muniz, pelos designers Lucas Falcão e Augusto Barbosa, e pelo diretor de novos negócios Maurício Baum. Como a loja foi criada por profissionais com os mais diversos backgrounds, o resultado ficou óbvio: foram finalistas com o layout mais legal dentre os participantes.
Coloque el título y el subtítulo en negrita.
ℹ️ Recuerde acceder a la documentación del Rich Text si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar el siguiente enlace:
https://github.com/daniel-beta/store-framework/issues/2
Hemos terminado de implementar nuestra página de producto y pasaremos a la página de búsqueda. Ambas son muy similares en el sentido de que tienen bloques que son exclusivos de este contexto. Exploraremos este bloque de forma desordenada en este step, solo para entender su comportamiento, y continuaremos mejorando el diseño en el siguiente paso.
store.search
, como otros templates, también puede ser flexible. Para construir un layout único, es necesario usar un bloque llamado search-result-layout
.
{
"store.search": {
"blocks": ["search-result-layout"]
}
}
search-result-layout
, a su vez, debe recibir otros tres bloques:
search-result-layout.desktop
search-result-layout.mobile
search-not-found-layout
Como usted ya debe haber notado, los dos primeros definen cuál layout se mostrará en desktop y mobile, respectivamente, y el tercero define el layout de la página de resultados no encontrados.
{
"store.search": {
"blocks": ["search-result-layout"]
},
"search-result-layout": {
"blocks": [
"search-result-layout.desktop",
"search-result-layout.mobile",
"search-not-found-layout"
]
}
}
En el curso, nos centraremos en implementar layout de desktop
La documentación de Search Result ofrece una buena referencia de los bloques que pueden usarse en el contexto de búsqueda. En este step nos centraremos en tratar de mostrar los principales:
breadcrumb.search
) .search-title.v2
) .total-products.v2
) .order-by.v2
) .search-fetch-more
) .search-fetch-previous
) .filter-navigator.v3
) .search-content
) .Aunque son muchos, todos estos bloques son relativamente simples y funcionan muy bien sin mucha necesidad de configurar sus props
.
Copie el código anterior en el archivo search.jsonc
y defina un search-result-layout.desktop
que tenga como hijos, en este orden:
breadcrumb.search
search-title.v2
total-products.v2
order-by.v2
search-fetch-previous
search-content
filter-navigator.v3
search-fetch-more
ℹ️ Recuerde acceder a la documentación del Search Result si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
En el último paso, aprendimos cómo hacer una página de producto simple con sus ítems mínimos, pero sabemos que lo que hicimos está lejos de ser una página de producto ideal, pondremos otros elementos que a menudo vemos en las páginas de producto de varias tiendas.
En nuestra documentación es posible encontrar 30 bloques más relacionados con el producto. Al comienzo del curso hablamos sobre Shelf y sus bloques relacionados, además de haber visto 4 bloques más en la última parte. En este paso veremos 4 más:
Es importante que al final del curso, usted se tome un tiempo para explorar nuestros componentes, así como las posibilidades de personalización que se tiene con estos.
Evolucione la página de producto agregando los otros 4 bloques listados anteriormente de la siguiente forma en el archivo product.jsonc
:
Defina un breadcrumb
al inicio, antes de la línea principal del producto.
"store.product": {
"children": [
"breadcrumb",
"flex-layout.row#main"
]
}
Defina el product-identifier.product
debajo del product-name
.
Cree una línea debajo del precio con el sku-selector
y el product-quantity
como children.
{
...
"children": [
"product-price",
"flex-layout.row#qty-sku"
]
},
"flex-layout.row#qty-sku": {
"children": [
"sku-selector",
"product-quantity"
]
},
...
}
Defina shipping-simulator
debajo de la row con el SKU Selector y el Product Quantity.
ℹ️ Recuerde acceder a la documentación del Breadcrumb, Product Identifier, Product Quantity y SKU Selector si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
En el último step conocimos la página de búsqueda y sus componentes principales. También aprendimos que el layout de search funciona como cualquier otro bloque, por lo que tiene toda la flexibilidad a su alcance. En este step crearemos algunas líneas y columnas para mejorar el aspecto de la búsqueda creada.
En el archivo search.jsonc
, elimine total-products.v2
y order-by.v2
del search-result-layout.desktop
.
Reemplace los dos anteriores con una línea top que incluya los bloques eliminados:
...
"flex-layout.row#top": {
"children": [
"total-products.v2",
"order-by.v2"
]
}
...
Elimine el search-content
y el filter-navigator.v3
del search-result-layout.desktop
y cree una línea de resultado.
En la línea de resultado, coloque otras dos columnas:
{
...
"search-result-layout.desktop": {
"children": [
"breadcrumb.search",
"search-title.v2",
"flex-layout.row#top",
"search-fetch-previous",
"flex-layout.row#results",
"search-fetch-more"
]
},
"flex-layout.row#results": {
"children": [
"flex-layout.col#filter",
"flex-layout.col#search"
]
},
...
}
Configure la prop width
de la columna filter
en 20%
.
En la columna de la izquierda incluya el filter-navigator.v3
nuevamente y, en la de la derecha, incluya el search-content
.
Para finalizar, usaremos el mismo Resumen de Produto (product-summary
) que usamos en el shelf para mostrar los resultados de búsqueda.
Defina su search-content
con los bloques gallery
y not-found
:
{
...
"search-content": {
"blocks": ["gallery", "not-found"]
}
...
}
Use el product-summary.shelf
en las props de Gallery:
{
...
"search-content": {
"blocks": ["gallery", "not-found"]
},
"gallery": {
"blocks": ["product-summary.shelf"]
}
...
}
En el bloque product-summary.shelf
que se encuentra en el archivo default.jsonc
, incluya product-summary-sku-selector
arriba de product-summary-buy-button
.
ℹ️ Recuerde acceder a la documentación del Flex Layout si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Comencemos nuestra jornada a través del clásico "Hello, World!". Para crear algo como esto, necesitamos conocer los bloques del Store Framework y usar uno que nos permita crear textos. Este bloque se llama Rich Text.
Rich Text es solo una de las decenas de bloques disponibles en el Store Framework. Es un bloque que parece simple, pero que permite una serie de personalizaciones para crear textos. Para empezar, todo el texto escrito en Rich Text soporta el lenguaje Markdown, esto hace con que la estilización del texto sea mucho más fácil.
Revisando la documentación del bloque es posible encontrar la especificación técnica. Una de las secciones presentes es la de Blocks API en la que puede ver la lista completa de propiedades (props) que posee el Rich Text. Las propiedades son el principal punto de personalización de un bloque, son las que garantizan que un mismo bloque pueda verse y comportarse de manera completamente diferente, dependiendo de cómo esté configurado.
Comencemos, entonces, a personalizar el home page. En su tema es posible encontrar un archivo llamado home.jsonc
en la carpeta /store/blocks
. En este archivo se determina la organización de los bloques que se desea utilizar. El lenguaje para la composición del layout es simple y está basado en JSON.
En home.jsonc
se ve un bloque que es estándar en todos los temas: store.home
. Este bloque determina los bloques hijos que se mostrarán en el home page.
{
"store.home": {
"blocks": []
}
...
}
Entonces, vamos a usar el Rich Text en su cuerpo:
{
"store.home": {
"blocks": [
"rich-text"
]
}
...
}
De esta forma, el store.home
ahora sabe que necesitará renderizar un Rich Text. Sin embargo, aún no hemos especificado cómo se ve este Rich Text. Para esto, necesitamos hacer una definición de bloque.
La definición de bloques se debe hacer siempre fuera de cualquier otro bloque, en el nivel de la raíz del archivo JSON.
{
"store.home": {
"blocks": [
"rich-text" <----- Aquí el bloque está siendo usado dentro de otro
]
},
"rich-text": { <----- Aquí está en la raíz
}
}
En la definición es posible determinar el comportamiento y aspecto de un bloque. Para esto, deben usarse puntos de personalización, comenzaremos usando las props
del Rich Text:
{
"store.home": {
"blocks": [
"rich-text"
]
},
"rich-text": {
"props": {
}
}
}
Consulte nuevamente la documentación del Rich Text y definamos, entonces, las props que usaremos para personalizarlo.
Queremos hacer un simple "Hello, World!", examinando las props vemos una que se llama: text
(Text written in markdown language to be displayed). Esta es, entonces, la prop que determinará cuál texto será exhibido.
Incluyendo esta prop tenemos, entonces:
{
"store.home": {
"blocks": [
"rich-text"
]
},
"rich-text": {
"props": {
"text": "Hello, World!"
}
}
}
Revisando la documentación del Markdown vemos que para dejarlo en cursiva basta colocar *
antes y después del texto:
{
"store.home": {
"blocks": [
"rich-text"
]
},
"rich-text": {
"props": {
"text": "*Hello, World!*"
}
}
}
Para centrarlo, podemos agregar la prop textPosition
y atribuirle el valor CENTER
:
{
"store.home": {
"blocks": [
"rich-text"
]
},
"rich-text": {
"props": {
"text": "*Hello, World!*",
"textPosition": "CENTER"
}
}
}
Defina un Rich Text en su home y cree un texto "Hello, World!" en negrita y alineado a la derecha.
ℹ️ Recuerde acceder a la documentación del Rich Text si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Es importante establecer que este no es un curso expositivo. Su objetivo es enseñar a los participantes sobre el Store Framework de VTEX IO a partir de actividades prácticas. Por lo tanto, para que sea posible avanzar, es necesario que se invierta un poco de su tiempo y dedicación.
Al comienzo del curso usted recibió un repositorio con código mínimo y queremos que, al completar todas las tareas, lo haya transformado en una tienda completa y funcional.
El curso está dividido en etapas. Al comienzo de cada etapa, usted recibirá instrucciones iniciales, como ya recibió en esta y en la anterior. Debe leer todo el contenido presentado y recibirá, al final, una pequeña actividad.
Para que sus respuestas se envíen, siga los siguientes pasos:
git clone
.https://github.com/daniel-beta/store-framework
.Open
en la notificación que se abre en la esquina inferior derecha.store-framework
.daniel-beta/store-framework
y haga clic en Install.Cuando haya terminado de leer todo el contenido y de realizar la actividad propuesta, debe enviar su respuesta siguiendo los pasos que se indican a continuación:
Source Control
, en el menú lateral de VSCode.+
en la sección de CHANGES.✓
(Commit).+ Create new branch...
Cuando termine de hacer el flujo completo, nuestro robot responderá si logró o no acertar la respuesta que esperábamos. Si es así, obtendrá una respuesta como:
En seguida, recibirá otra respuesta que le indicará los siguientes pasos:
Si está familiarizado con el git, todo este flujo equivale a crear un branch con un nombre predefinido, hacer commit de los cambios y dar push.
A lo largo del curso, es posible que no pueda completar la actividad correctamente en el primer intento. Si esto sucede, recibirá un mensaje de feedback que le indicará cuál fue el porqué de la falla:
Usted puede enviar tantas respuestas como quiera, basta rehacer todo el proceso explicado en la sección anterior.
En cualquier momento del curso, usted puede acompañar su progreso volviendo a la página de inicio. En esta, se indicarán todos los steps que ya completó y un botón para que vuelva al step desde donde lo dejó:
En todo momento, al abrir el terminal VSCode, puede ejecutar un vtex link
y acompañar la evolución de su proyecto en https://{workspace}--{conta}.myvtex.com
. Asegúrese de que visualmente la solución es equiparable con lo que se presentó y que no se haya producido ningún error en el enlace.
No cree issues y PRs durante el flujo del curso, ya que esto puede interferir en su funcionamiento.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Con el Header ya configurado e implementado, ahora vamos a agregarle el Menú.
La configuración del Menú es un paso importante en la construcción del tema, ya que es el bloque responsable de la navegación del usuario en su tienda.
Debido a su función y relevancia, el Menú tiene una estructura jerárquica compleja, que involucra Menu Items, Submenús y, a partir de este último, cualquier bloque del Store Framework (como otros Menús y Menu Items).
A continuación, puede ver una imagen que ejemplifica la estructura del bloque Menú en la práctica:
Si se compara con las de algunos bloques, la configuración del menú puede parecer más difícil debido a su estructura de menús, ítems de menú y submenús.
Pero el Menú no necesita necesariamente ser configurado siguiendo este escenario más complejo.
A continuación, podemos ver un ejemplo de una implementación básica del bloque, que contiene apenas 3 Menu Items:
{
"[email protected]:menu#categories": {
"children": [
"menu-item#major-appliances",
"menu-item#small-appliances",
"menu-item#electronics"
],
"props":{
"orientation": "horizontal"
}
}
},
En esta actividad, entenderemos mejor sobre la configuración del Menú y la jerarquía dentro de este a partir de la construcción de Menu Items y Submenús.
En el archivo header.jsonc
, agregue header-row#menu
como último ítem en la lista de children del bloque header-layout.desktop
(configurado en la [actividad anterior]) para que el Menú pueda ser renderizado por el Header de la tienda.
Copie y peque el siguiente código para declarar el bloque header-row#menu
:
"header-row#menu": {
"children": [
"header-spacer",
"[email protected]:menu#categories",
"header-spacer"
]
},
También debemos preocuparnos con el Menú en el layout de otros dispositivos, como mobile. Por eso, agregue drawer
como primer ítem de children del bloque header-row#main-mobile
.
Pegue el siguiente código en el archivo menu.jsonc
para renderizar horizontalmente los 3 ítems de su Menú principal:
{
"[email protected]:menu#categories": {
"children": [
"menu-item#major-appliances",
"menu-item#small-appliances",
"menu-item#electronics"
],
"props":{
"orientation": "horizontal"
}
},
Como vimos en la introducción, un Menu Item puede permitir la configuración de un Submenú dentro de este que, a su vez, puede tener otro Menú con Menu Items. Cree entonces el Submenú de Major Appliance, aún en el archivo menu.jsonc
, de acuerdo con el siguiente ejemplo:
"[email protected]:submenu#major":{
"children":[
"[email protected]:menu#major"
]
},
Siguiendo el formato establecido por el bloque [email protected]:menu#categories
, construya el Menú secundario de Major Appliances declarado en el último paso en el archivo menu.jsonc
. Usted debe definir vertical
como valor de la prop orientation
y configurar los siguientes Menu Items en la lista de children del bloque: menu-item#refrigerators
, menu-item#ovens
y menu-item#washers
.
Cree también el Submenú de Small Appliances:
"[email protected]:submenu#small":{
"children":[
"[email protected]:menu#small"
]
},
Construya ahora el Menú secundario de Small Appliances en el archivo menu.jsonc
. Así como se hizo para Major Appliance, usted debe definir vertical
como valor de la prop orientation
y configurar los siguientes Menu Items en la lista de children del bloque: menu-item#mixers
, menu-item#toasters
y menu-item#coffee
.
Basado en los pasos anteriores, haga lo mismo para Eletronics: cree su Submenú ([email protected]:submenu#electronics
) y Menú secundario. Después, construya este último con el mismo valor de prop (vertical
) y configure los siguientes Menu Items en la lista de children del bloque: menu-item#cameras
, menu-item#laptops
y menu-item#tvs
.
ℹ️ Recuerde acceder a la documentación del Menú si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
Una vez terminada la página inicial de nuestra tienda, comenzamos un nuevo template de la tienda: la página de producto. Las páginas de producto son probablemente el template que más tienen bloques diferentes, lo que las hace extremadamente personalizables y flexibles.
Así que construyamos una página de producto mínima donde solo tengamos lo esencial:
La mayoría de los bloques de producto, a diferencia de los de contenido, tienen un contexto en el que están insertados. Todo esto hace que estos bloques sean un poco plug-n-play: colocar un product-images
en la página de producto, automáticamente redenrizará las imágenes del producto de la página, tal como se hace con el precio y el nombre.
Sin embargo, nada de esto significa que estos bloques sean poco personalizables, como veremos más adelante.
Construya una página de producto usando los bloques product-images
, product-price
, product-name
y buy-button
en el archivo product.jsonc
declarado dentro de la carpeta store/blocks
. Esperamos que en la estructura tengamos:
Una línea en store.product
.
{
"store.product": {
"children": [
"flex-layout.row#main"
]
}
}
Dentro de la línea debe haber dos columnas.
"flex-layout.row#main": {
"props": {
"marginTop": 6
},
"children": [
"flex-layout.col#left",
"flex-layout.col#right"
]
}
Dentro de la columna de la izquierda debe haber un product-images
.
"flex-layout.col#left": {
"children": [
"product-images"
]
}
Dentro de la columna derecha debe estar el product-name
, product-price
y buy-button
.
Además, queremos que:
verticalAlign
y preventVerticalStretch
en la documentación de Flex Layout Column).product-price
muestre el ahorro total y el precio de lista (showSavings
y showListPrice
).ℹ️ Recuerde acceder a la documentación del product-images
, product-price
, product-name
y buy-button
si tiene alguna duda durante la actividad.
¿Hay algún problema con este paso? ¿Qué tal si nos envía un feedback? 🙏
Si aún tiene alguna duda sobre cómo enviar su respuesta, puede revisar aquí.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.