Documentation
Feedback
Guides
Learning Center

Learning Center
Learning Center
Conditional Layout
View in English
This content was migrated from the VTEX Learning Center and is no longer being actively maintained. For the most accurate and up-to-date information, please check the official documentation.

Introdução

Em alguns momentos, quando desenvolvendo uma loja, precisamos criar layouts condicionais que seriam aplicados somente a um contexto específico. Já vimos que na utilização de dispositivos diferentes, é possível condicionar o layout através do Responsive Layout, mas e se quiséssemos, por exemplo, ter uma página de produto diferente para produtos específicos? Para isso serve o Conditional Layout.

Setup opcional

Para criar um layout condicional de página de produto é necessário, inicialmente, ter uma página de produto. Se você já não tiver definido um template de produto para sua loja, copie o disponível abaixo:


_70
//product.jsonc
_70
{
_70
"store.product": {
_70
"children": [
_70
"flex-layout.row#product-breadcrumb",
_70
"flex-layout.row#product-main"
_70
]
_70
},
_70
"flex-layout.row#product-breadcrumb": {
_70
"props": {
_70
"marginTop": 20
_70
},
_70
"children": ["breadcrumb"]
_70
},
_70
"flex-layout.row#product-main": {
_70
"props": {
_70
"colGap": 9,
_70
"rowGap": 7,
_70
"marginTop": 4,
_70
"marginBottom": 7,
_70
"paddingTop": 7,
_70
"paddingBottom": 7,
_70
"blockClass": "product-main"
_70
},
_70
"children": ["product-images", "flex-layout.col#right-col"]
_70
},
_70
"product-images": {
_70
"props": {
_70
"displayThumbnailsArrows": true,
_70
"thumbnailsOrientation": "vertical"
_70
}
_70
},
_70
"flex-layout.col#right-col": {
_70
"props": {
_70
"preventVerticalStretch": true,
_70
"rowGap": 0
_70
},
_70
"children": [
_70
"product-name",
_70
"product-price#product-details",
_70
"sku-selector",
_70
"flex-layout.row#buy-button",
_70
"shipping-simulator",
_70
"share#default"
_70
]
_70
},
_70
"product-price#product-details": {
_70
"props": {
_70
"showInstallments": true,
_70
"showSavings": true
_70
}
_70
},
_70
"flex-layout.row#buy-button": {
_70
"props": {
_70
"marginTop": 4,
_70
"marginBottom": 7
_70
},
_70
"children": ["buy-button"]
_70
},
_70
"share#default": {
_70
"props": {
_70
"social": {
_70
"Facebook": true,
_70
"WhatsApp": true,
_70
"Twitter": false,
_70
"Pinterest": true
_70
}
_70
}
_70
}
_70
}

Fazendo isso, teremos uma página de produto como a mostrada abaixo:

{"base64":"  ","img":{"width":3152,"height":1306,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":553467,"url":"https://user-images.githubusercontent.com/18701182/90407144-84650180-e07c-11ea-9036-838d4d662ba1.png"}}

Atividade

  1. Vamos criar um banner exclusivo para a geladeira Geladeira Retrô, para isso, use como primeiro filho da store.product um condition-layout.product:

_10
//product.jsonc
_10
{
_10
"store.product": {
_10
"children": [
_10
+ "condition-layout.product"
_10
...
_10
]
_10
}
_10
...
_10
}

  1. Defina, então, o condition-layout.product, com uma condição específica para a Batedeira Retrô:

_10
//product.jsonc
_10
{
_10
...
_10
+ "condition-layout.product": {
_10
+ "children": [
_10
+ "condition.product#retro-mixer"
_10
+ ]
_10
+ }
_10
}

  1. Agora, precisamos definir a condição para a batedeira.

O condition.product requer a prop conditions para definir em quais condições deve ser aplicada (veja a documentação), uma condição é dividida em três partes:

  • subject: é o dado que vai ser usado para fins de comparação, no nosso caso usaremos productId, na documentação é possível ver todas as opções disponíveis;
  • verb: é o método comparativo, usaremos o is para validar se o productId é de um produto específico, mas poderíamos usar: is, is-not, contains ou does-not-contain;
  • object: é o valor com que queremos comparar, no nosso caso, usaremos o productId 20.

Sendo assim, o objeto formado é:


_16
//product.jsonc
_16
{
_16
...
_16
+ "condition.product#retro-mixer": {
_16
+ "props": {
_16
+ "conditions": [
_16
+ {
_16
+ "subject": "productId",
_16
+ "verb": "is",
_16
+ "object": "20"
_16
+ }
_16
+ ]
_16
+ },
_16
+ "children": ["image#retro-mixer-banner"]
_16
+ }
_16
}

NOTA: Se você estiver fazendo o curso na sua própria loja, identifique o productId do produto que deseja customizar e coloque o valor no campo object. Você descobrir o valor atualizando a página, abrindo o console do seu navegador e digitando __RUNTIME__.route.params.id:

{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABCAIAAAB2XpiaAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAFUlEQVR4nGN49+7N2bOn8/PSjY31ADlaBwZWmq8/AAAAAElFTkSuQmCC","img":{"src":"https://user-images.githubusercontent.com/18701182/90410392-aeb8be00-e080-11ea-8880-f5470c4e5d00.png","width":404,"height":74,"type":"png"}}

  1. Para finalizar, vamos definir o banner retrô:

_12
//product.jsonc
_12
{
_12
...
_12
+ "image#retro-mixer-banner": {
_12
+ "props": {
_12
+ "src": "https://appliancetheme.vtexassets.com/assets/app/src/retroimage___92a8271aac7c51d2059193bdbe019016.jpg",
_12
+ "width": "100%",
_12
+ "height": "200px",
_12
+ "blockClass": "cover"
_12
+ }
_12
+ }
_12
}

Visite a página do produto testado para ver o layout funcionando, se tiver usando a appliancetheme e o produto for a batedeira retro, a url será:

https://{{seuworkspace}}--appliancetheme.myvtex.com/3-colors-retro-stand-mixer/p:

{"base64":"  ","img":{"width":1278,"height":817,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":725502,"url":"https://user-images.githubusercontent.com/43679629/93816475-f6a5a480-fc2d-11ea-80e9-45f4b7907007.png"}}

Para garantir que o layout condicional de fato funciona, visite qualquer outra página de produto, e verifique que o banner não é aplicado:

{"base64":"  ","img":{"width":1954,"height":952,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":613036,"url":"https://user-images.githubusercontent.com/18701182/90412377-68b12980-e083-11ea-86a8-99495acfd997.png"}}

Fim

Chegamos ao último passo do curso e nele aprendemos como criar layouts complexos se alavancando de blocos mais simples, não exploramos todos os layouts possíveis, mas a ideia de todos eles é muito parecida, para conhecer mais visite a seção de LAYOUT APPS no Developer Portal.

Answer sheet

See answer sheet for product.jsonc
product.jsonc

_92
{
_92
"store.product": {
_92
"children": [
_92
"condition-layout.product",
_92
"flex-layout.row#product-breadcrumb",
_92
"flex-layout.row#product-main"
_92
]
_92
},
_92
"condition-layout.product": {
_92
"children": ["condition.product#retro-mixer"]
_92
},
_92
"condition.product#retro-mixer": {
_92
"props": {
_92
"conditions": [
_92
{
_92
"subject": "productId",
_92
"verb": "is",
_92
"object": "20"
_92
}
_92
]
_92
},
_92
"children": ["image#retro-mixer-banner"]
_92
},
_92
"image#retro-mixer-banner": {
_92
"props": {
_92
"src": "https://appliancetheme.vtexassets.com/assets/app/src/retroimage___92a8271aac7c51d2059193bdbe019016.jpg",
_92
"width": "100%",
_92
"height": "200px",
_92
"blockClass": "cover"
_92
}
_92
},
_92
"flex-layout.row#product-breadcrumb": {
_92
"props": {
_92
"marginTop": 20
_92
},
_92
"children": ["breadcrumb"]
_92
},
_92
"flex-layout.row#product-main": {
_92
"props": {
_92
"colGap": 9,
_92
"rowGap": 7,
_92
"marginTop": 4,
_92
"marginBottom": 7,
_92
"paddingTop": 7,
_92
"paddingBottom": 7
_92
},
_92
"children": ["product-images", "flex-layout.col#right-col"]
_92
},
_92
"product-images": {
_92
"props": {
_92
"displayThumbnailsArrows": true,
_92
"thumbnailsOrientation": "vertical"
_92
}
_92
},
_92
"flex-layout.col#right-col": {
_92
"props": {
_92
"preventVerticalStretch": true,
_92
"rowGap": 0
_92
},
_92
"children": [
_92
"product-name",
_92
"product-price#product-details",
_92
"sku-selector",
_92
"flex-layout.row#buy-button",
_92
"shipping-simulator",
_92
"share#default"
_92
]
_92
},
_92
"product-price#product-details": {
_92
"props": {
_92
"showInstallments": true,
_92
"showSavings": true
_92
}
_92
},
_92
"flex-layout.row#buy-button": {
_92
"props": {
_92
"marginTop": 4,
_92
"marginBottom": 7
_92
},
_92
"children": ["buy-button"]
_92
},
_92
"share#default": {
_92
"props": {
_92
"social": {
_92
"Facebook": true,
_92
"WhatsApp": true,
_92
"Twitter": false,
_92
"Pinterest": true
_92
}
_92
}
_92
}
_92
}

See answer sheet for vtex.store-components.css
vtex.store-components.css

_10
.imageElement--cover {
_10
object-fit: cover;
_10
}

On this page