Neste artigo, adicionaremos campos para oferecer produtos mais personalizados. Por exemplo, para casos em que a loja vende camisetas com um número e um nome.
Essas informações serão então levadas para o checkout e, finalmente, serão refletidas no detalhe do pedido do Administrador nuvem.

HTML
1. Criamos a pasta forms dentro da pasta snipplets. Aqui, precisamos adicionar um novo arquivo com o nome form-input.tpl que usaremos para cada input nos detalhes do produto.
{# /*============================================================================
#Form input
==============================================================================*/
#Properties
#Group
//input_group_custom_class for custom CSS classes
#Label
// input_label_id for ID
// input_for for label for
// input_label_custom_class for custom CSS classes
// input_label_text for label text
#Prepend
// input_prepend_content to add content before input
#Container (Only if has prepend or append)
// form_control_container_custom_class for container custom class. E.g: col
#Input
// Can be text_area or input
// input_type to define type (text, tel, number or passowrd)
// input_id for id
// input_name for name
// input_value for val
// input_placeholder for placeholder
// input_custom_class for custom CSS classes
// input_rows for textarea rows
// input_data_attr for data attributes
// input_data_val for input_data_attr value
// input_aria_label for aria-label attribute
#Append
// input_append_content to add content after input
#Alerts
// input_form_alert to insert alerts
#}
<div class="form-group {{ input_group_custom_class }}">
{% if input_label_text %}
<label {% if input_label_id %}id="{{ input_label_id }}"{% endif %} class="form-label {{ input_label_custom_class }}" {% if input_for %}for="{{ input_name }}"{% endif %}>{{ input_label_text }}</label>
{% endif %}
{% block input_prepend_content %}
{% endblock input_prepend_content %}
{% if input_append_content or input_prepend_content %}
<div class="form-control-container {{ form_control_container_custom_class }}">
{% endif %}
{% if text_area %}
<textarea
{% if input_id %}id="{{ input_id }}"{% endif %}
class="form-control form-control-area {{ input_custom_class }} {% if input_append_content %}form-control-inline{% endif %}"
autocorrect="off"
autocapitalize="off"
{% if input_name %}name="{{ input_name }}"{% endif %}
{% if input_value %}value="{{ input_value }}"{% endif %}
{% if input_rows %}rows="{{ input_rows }}"{% endif %}
{% if input_placeholder %}placeholder="{{ input_placeholder }}"{% endif %}
{% if input_data_attr %}data-{{ input_data_attr }}="{{ input_data_val }}"{% endif %}></textarea>
{% else %}
<input
type="{% if type_text %}text{% elseif type_number %}number{% elseif type_tel %}tel{% elseif type_password %}password{% elseif type_hidden %}hidden{% endif %}"
{% if input_id %}id="{{ input_id }}"{% endif %}
class="form-control {{ input_custom_class }} {% if input_append_content %}form-control-inline{% endif %}"
autocorrect="off"
autocapitalize="off"
{% if type_password %}autocomplete="off"{% endif %}
{% if input_name %}name="{{ input_name }}"{% endif %}
{% if input_value %}value="{{ input_value }}"{% endif %}
{% if input_min %}min="{{ input_min }}"{% endif %}
{% if input_placeholder %}placeholder="{{ input_placeholder }}"{% endif %}
{% if input_data_attr %}data-{{ input_data_attr }}="{{ input_data_val }}"{% endif %}
{% if input_aria_label %}aria-label="{{ input_aria_label }}"{% endif %}/>
{% endif %}
{% if input_append_content or input_prepend_content %}
</div>
{% endif %}
{% block input_append_content %}
{% endblock input_append_content %}
{% if input_help %}
<div class="mt-4 text-center">
<a href="{{ input_help_link }}" class="btn-link {{ input_link_class }}">{% block input_help_text %}{% endblock input_help_text %}</a>
</div>
{% endif %}
{% block input_form_alert %}
{% endblock input_form_alert %}
</div>2. No snipplet do formulário do produto, product-form.tpl, dentro da pasta snipplets/product; ou dependendo do design pode ser diretamente no modelo product.tpl, adicione um input para a propriedade que você precisa. O importante é que esteja no form com o ID "product_form".
Este input deve ter um atributo "name" com o valor "properties [x]", substituindo o "X" pelo nome da propriedade que você precisa.
Por exemplo, para um número e um nome, precisamos de algo como:
{% embed "snipplets/forms/form-input.tpl" with{type_text: true, input_name: 'properties[Número]', input_label_text: 'Nombre' | translate } %}
{% endembed %}
{% embed "snipplets/forms/form-input.tpl" with{type_text: true, input_name: 'properties[Nombre]', input_label_text: 'Nombre' | translate } %}
{% endembed %}Este embed mostra um HTML similar ao seguinte:
<div class="form-group">
<label>{{ 'Número' | translate }}</label>
<input type="text" name="properties[Número]" class="form-control">
</div>
<div class="form-group">
<label>{{ 'Nombre' | translate }}</label>
<input type="text" name="properties[Nombre]" class="form-control">
</div>Se quisermos que o input seja informação oculta e que ela seja visível apenas na ordem da pessoa que gerencia a loja, basta adicionar o hifen no início do nome, por exemplo:
{% embed "snipplets/forms/form-input.tpl" with{type_text: true, input_name: 'properties[_Nombre]', select_label: false %}
{% endembed %}Imprimindo algo como:
<div class="form-group">
<input type="text" name="properties[_Nombre]" class="form-control">
</div>Se, por algum motivo, precisarmos mostrar o input apenas em alguns produtos, será melhor adicionar essos inputs a partir da descrição do produto no Administrador nuvem, habilitando o formato HTML.

Mas devemos considerar que este campo não usa o Twig, então temos que usar o HTML “clássico”, por exemplo:
<div class="form-group">
<label>{{ 'Nombre' | translate }}</label>
<input type="text" name="properties[Nombre]" class="form-control">
</div>Nós só temos que lembrar de colocar o código {{ product.description }} dentro do formulário do produto, uma vez que geralmente está fora dele.
A funcionalidade permite qualquer tipo de entrada (texto, número, etc), deve ser dentro do formulário do produto para que as informações sejam enviadas para o checkout e, depois, para o pedido gerado.
2. Para mostrar essas propriedades no carrinho, devemos adicionar o seguinte código no snipplet cart-item-ajax.tpl ou no template cart.tpl (dependendo do seu design):
{% for key, value in item.attributes if key[:1] != '_' %}
<div><strong>{{key}}</strong>: {{value}}</div>
{% endfor %}CSS
Requisito:
Ter adicionado helper classes em seu layout. Você pode seguir este pequeno tutorial para fazer isso (é só copiar e colar algumas classes, não leva mais que 1 minuto).
1. Adicionamos o seguinte SASS de cores em style-colors.scss.tpl (ou na stylesheet do seu layout que possui as cores e fontes da loja). Lembre-se de que as variáveis de cores e fontes podem variar em relação ao seu layout:
{# This mixin adds browser prefixes to a CSS property #}
@mixin prefix($property, $value, $prefixes: ()) {
@each $prefix in $prefixes {
#{'-' + $prefix + '-' + $property}: $value;
}
#{$property}: $value;
}
{# /* // Forms */ #}
input,
textarea {
font-family: $body-font;
}
.form-control {
display: block;
padding: 10px 8px;
width: 100%;
border: 0;
border-bottom: 1px solid rgba($main-foreground, .5);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
color: $main-foreground;
background-color: $main-background;
&:focus{
outline: 0;
}
&-inline{
display: inline;
}
}
.form-control::-webkit-input-placeholder {
color: $main-foreground;
}
.form-control:-moz-placeholder {
color: $main-foreground;
}
.form-control::-moz-placeholder {
color: $main-foreground;
}
.form-control:-ms-input-placeholder {
color: $main-foreground;
}2. Adicione os estilos no arquivo static/style-critical.tp
Se em seu layout você usar um stylesheet para o CSS crítico, precisaremos do seguinte código dentro dele, do contrário, você pode unificar o CSS dos passos 2 e 3 em um único arquivo.
{# /* // Forms */ #}
.form-group {
position: relative;
width: 100%;
}
.form-group .form-select-icon{
position: absolute;
bottom: 12px;
right: 0;
pointer-events: none;
}
.form-row {
width: auto;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-right: -5px;
margin-left: -5px;
clear: both;
}
.form-row > .col,
.form-row > [class*=col-]{
padding-right: 5px;
padding-left: 5px;
}
.form-label {
display: block;
font-size: 10px;
text-transform: uppercase;
}3. Adicione os estilos no arquivo static/style-async.tpl
Se em seu layout você usar um stylesheet CSS assíncrono, precisaremos do seguinte código dentro dela, do contrário, você pode unificar o CSS dos passos 2 e 3 em um único arquivo.
{# /* // Margin and Padding */ #}
%element-margin {
margin-bottom: 35px;
}
{# /* // Mixins */ #}
{# This mixin adds browser prefixes to a CSS property #}
@mixin prefix($property, $value, $prefixes: ()) {
@each $prefix in $prefixes {
#{'-' + $prefix + '-' + $property}: $value;
}
#{$property}: $value;
}
{# /* // Forms */ #}
.form-group{
@extend %element-margin;
.form-label{
float: left;
width: 100%;
margin-bottom: 10px;
}
.alert{
margin: 10px 0 0 0;
}
}
{# /* Disabled controls */ #}
input,
select,
textarea{
&[disabled],
&[disabled]:hover,
&[readonly],
&[readonly]:hover{
background-color: #DDD;
cursor: not-allowed;
}
}Pronto, agora você pode oferecer produtos personalizados em seu design!