Guia de recursos do layout Sass (catalogo)
{{searchMetaDescription}}, {{searchCanonicalPath}}, {{siteNameJson}}.{{seoStoreJsonLd}} e {{seoWebsiteJsonLd}}.{{productSchemaJsonLdRaw}} e {{productSchemaHasJsonLd}}.Padrão como as tags de SEO podem ser usadas:
<title>{{searchQueryLabelTitle}} | {{mainData.siteName}}</title>
<meta name="description" content="{{searchMetaDescription}}" />
<link rel="canonical" href="{{searchCanonicalPath}}" />
Formatação padrão para schema de Store em JSON
{{#if seoStoreJsonLd}}
<script type="application/ld+json">{{seoStoreJsonLd}}</script>
{{/if}}
| Placeholder | Exemplo de saída no HTML |
|---|---|
| {{mainData.siteName}} | TechShop |
| {{mainData.siteDomain}} | loja.exemplo.com |
| {{mainData.configPath}} | /catalogo |
| {{mainData.seoOrganizationName}} | TechShop Comércio Ltda |
| {{mainData.seoAuthor}} | Equipe TechShop |
| {{mainData.seoOrganizationUrl}} | www.techshop.com.br (URL “lógica” do cadastro; em JSON-LD de produto o código prefixa https://) |
| {{mainData.seoBaseHref}} | https://loja.exemplo.com/catalogo/ |
| {{mainData.seoOrganizationLogo}} | https://cdn.exemplo.com/logo.png |
| {{mainData.seoOrganizationLogoWidth}} / Height | 140 / 70 |
| {{mainData.seoCoordinates}} | -23.5505;-46.6333 (se preenchido) |
| {{mainData.seoRegion}} | BR-SP |
| {{mainData.seoState}}, seoCountry, endereço, CEP, telefone, horários | texto cadastrado, ex.: São Paulo, Brasil, Rua X, 100, 01310-100, 11999999999, Mo-Fr 09:00-18:00 |
{{visitsToken}}{{mainData.*}}{{searchTermsFirst}}, {{searchTermsMore}}, {{searchTermsHasMore}}.Exemplo de uso do token e exibição de todos os termos mais pesquisados, caso haja:
<input type="hidden" id="visitsToken" value="{{visitsToken}}" />
{{#if searchTermsFirst}}
{{#each searchTermsFirst}}
<a href="{{href}}">{{searchUserQuery}}</a>
{{/each}}
{{/if}}
| Placeholder | Exemplo de saída |
|---|---|
| {{searchQueryLabelRaw}} | notebook gamer (ou string mais longa se houver catName, faixa de preço, filtros, marca — ver sassBuildSearchQueryLabelFromGet) |
| {{searchQueryLabelTitle}} | Notebook Gamer |
| {{searchMetaDescription}} | Resultados de Notebook Gamer aqui em TechShop Comércio Ltda (padrão em buildSassPayloadForSearchData) |
| {{searchCanonicalPath}} | Se existir REQUEST_URI válido: /catalogo/q.php?m=search&q=notebook+gamer; senão, path montado com configPath + http_build_query($get) |
São uma string JSON (não escapar de novo com {{ — nos templates usa-se {{{...}}}).
Organization (listagem/busca) — formato gerado por sassEncodeListOrganizationJsonLdString:
{"@type":"Organization","@context":"http://schema.org","name":"TechShop Comércio Ltda","url":"https://www.techshop.com.br","logo":{"@type":"ImageObject","url":"https://cdn.exemplo.com/logo.png","width":"140","height":"70"}}
Store (seoStoreJsonLd / listStoreJsonLd) — só é não vazio se seoOrganizationHoursWeek estiver preenchido (sassEncodeStoreJsonLdString). Exemplo típico:
{"@context":"https://schema.org","@type":"Store","address":{"@type":"PostalAddress","addressLocality":"São Paulo","addressRegion":"BR-SP","postalCode":"01310-100","streetAddress":"Rua X, 100"},"name":"TechShop Comércio Ltda","openingHours":["Mo-Fr 09:00-18:00","Sa 09:00-13:00"],"telephone":"11999999999","url":"https://loja.exemplo.com","image":"https://cdn.exemplo.com/logo.png"}
Se não houver horário de semana, a string fica vazia e o {{#if seoStoreJsonLd}} não imprime o <script>.
O template emite JSON literal com valores de mainData, por exemplo:
<script data-schema="Organization" type="application/ld+json"> { "@type":"Organization", ... "name":"TechShop Comércio Ltda", ... }</script>
| Placeholder | O que é | Exemplo ilustrativo |
|---|---|---|
| {{siteNameJson}} | Nome do site como literal JSON (uso em JS). | "Minha Loja" |
| {{searchUiBootstrapJson}} | JSON da UI de busca (ex.: texto inicial da query). | {"typingQuery":"notebook"} |
| {{seoStoreJsonLd}} | JSON-LD Store (schema.org); vazio se faltar horário de semana no SEO. | {"@context":"https://schema.org","@type":"Store",…} |
| {{listOrganizationJsonLd}} | JSON-LD Organization (listagem / busca). | {"@type":"Organization","@context":"http://schema.org",…} |
| {{listStoreJsonLd}} | Mesmo encoder que seoStoreJsonLd (Store). | Igual ao Store acima ou vazio |
| {{productSeoOrganizationJsonLdRaw}} | JSON-LD Organization no <head> do produto. | {"@type":"Organization",…} |
| {{productSeoStoreJsonLdRaw}} | JSON-LD Store no produto. | {"@type":"Store",…} ou vazio |
| {{productSchemaJsonLdRaw}} | JSON-LD Product (e Offer etc.); vazio se preço zero ou preview rápido. | {"@context":"https://schema.org/","@type":"Product",…} |
| {{productsJson}} | Lista de produtos serializada em JSON. | [{"id":1,"title":"…"},…] |
| {{priceLabelDataJson}} | Regras de etiqueta de preço (parcelas, riscado, etc.). | {"pricelabelInstallments":10,…} |
| {{paymentDiscountsJson}} | Descontos por forma de pagamento. | {"0":12,"1":6} |
| {{categoryDiscountsJson}} | Descontos por categoria. | {"0":{"categorydiscountValue":8,…}} |
| {{productsDiscountsJson}} | Descontos por produto (alinhado a products). | {} ou {"123":{…}} |
| {{productsJsonB64}} | Base64 do JSON de productsJson. | W3si… |
| {{priceLabelDataJsonB64}} | Base64 de priceLabelDataJson. | eyJw… |
| {{paymentDiscountsJsonB64}} | Base64 de paymentDiscountsJson. | eyIw… |
| {{categoryDiscountsJsonB64}} | Base64 de categoryDiscountsJson. | eyIw… |
| {{productsDiscountsJsonB64}} | Base64 de productsDiscountsJson. | e30= |
| {{productAdditionalMediaJson}} | Array JSON de mídias extras. | [] ou [{"type":"image",…}] |
| {{productMainImageJson}} | Objeto JSON da imagem principal. | {"src":"https://…","w":700,…} |
| {{productVariationImagesB64}} | Base64 da string JSON de imagens por variação (decodificar para obter JSON). | Após base64_decode → {…} |
{{sassListCustomProducts[ as=products, category={{category.categoryId}}, max=12, orderBy="ProductTitle ASC", includeVariations=true ]}}
{{#if products}}
{{#each products}}
<article class="card" data-product-id="{{item.id}}"> <img src="{{item.img350}}" alt="{{item.title}}" />
<h2>{{item.title}}</h2>
<p class="js-product-price"></p> </article>
{{/each}}
{{/if}}
Todos os parâmetros de sassListCustomProducts
{{sassListCustomProducts[as=products, category=0, min=0, max=30, stock=0, brand=0, excludeProduct=0, filters="", medias="", description=false, orderBy="", addAdditionalCatsIds=false, showBrand=false, showChildren=false, getShippingInfo=false, includeVariations=false]}}
Todos os parâmetros de sassListCustomProducts em formato de tabela com exemplos
| Parâmetro | Tipo | Padrão | O que faz |
|---|---|---|---|
| as | string | obrigatório na prática | Nome da variável que receberá a lista, ex.: products |
| category | int | 0 | Filtra por categoria |
| min | int | 0 | Offset / início da listagem |
| max | int | 30 | Quantidade máxima de itens |
| stock | int | 0 | Filtro relacionado a estoque |
| brand | int | 0 | Filtra por marca |
| excludeProduct | int | 0 | Exclui um produto da lista |
| filters | string | "" | Filtros adicionais em formato textual |
| medias | string | "" | Restrições / dados ligados a mídias |
| description | bool | false | Inclui descrição no retorno |
| orderBy | string | "" | Ordenação SQL / campo de ordenação |
| addAdditionalCatsIds | bool | false | Inclui categorias adicionais do produto |
| showBrand | bool | false | Inclui dados de marca no retorno |
| showChildren | bool | false | Inclui filhos / descendentes de categoria |
| getShippingInfo | bool | false | Inclui dados de frete |
| includeVariations | bool | false | Anexa variações ao resultado final |
Parâmetros alternativos também reconhecidos e compatíveis
Exemplos de usos do sassListCustomProducts
1) Listagem excluindo alguns produtos específicos
{{sassListCustomProducts[as=products, category={{category.categoryId}}, min=0, max=12, stock=0, brand=0, excludeProduct={{product.productId}}, filters="", medias="", description=false, orderBy="ProductTitle ASC", addAdditionalCatsIds=false, showBrand=false, showChildren=false, getShippingInfo=false, includeVariations=true]}}
2) Utilizando um filtro de cor com id 12, no caso, pegando só os valores iguais a Azul
{{sassListCustomProducts[as=products, category={{category.categoryId}}, min=0, max=20, stock=0, brand=0, excludeProduct=0, filters="filtro_12_Cor=Azul", medias="", description=true, orderBy="ProductTitle ASC", addAdditionalCatsIds=false, showBrand=true, showChildren=false, getShippingInfo=false, includeVariations=false]}}
3) Utilizando medias (espera-se imagem_{productfilterId}_{position}, anexando dados armazenados em ProductMedias. As medias recebe uma lista de IDs de filtros de mídia, separados por vírgula, e faz o template engine anexar ao produto as mídias cadastradas em ProductMedias para esses filtros. As mídias retornam com chaves no formato imagem_{filtro}_{posição}. Ele apenas acrescenta campos extras no objeto de retorno
{{sassListCustomProducts[as=products, category=0, max=10, medias="12,15"]}} <!-- vai adicionar medias do productFilterId = 12 e productFilterId - 15 -->
{{#if listPriceRangeLinks}}
{{#each listPriceRangeLinks}}
<a href="/q.php?catId={{category.categoryId}}&priceRange={{min}}-{{max}}"> De {{displayMin}} a {{displayMax}} </a>
{{/each}}
{{/if}}
{{#each listVariationFilterGroups}}
<h4>{{variationName}}</h4>
{{#each items}}
<a href="/q.php?variation_{{variationoptSearchName}}">{{variationoptName}}</a>
{{/each}}
{{/each}}
| Filtro | Parâmetros na query (q.php?…) | Dados no payload / template ({{#each}} / campos) | Efeito (resumo) |
|---|---|---|---|
| Categoria | catId={id} e, nos links do layout, também catName={nome} | Objeto category (category.categoryId, category.categoryName, etc.) | Restringe produtos da categoria na tabela Product e em ProductInCategory (search3.php). |
| Faixa de preço | priceRange={min}-{max} (valores numéricos) | listPriceRangeLinks: min, max, displayMin, displayMax (só existem 3 faixas se houver 4 pisos em listPriceRangeFloors) | productPrice BETWEEN min AND max. |
| Texto simples (filtro cadastrado) | filtro_{productfilterId}_{productsimpletextKey}={productsimpletextValue} | listSimpleTextFilterGroups → key (rótulo do grupo); em cada item: productfilterId, productsimpletextKey, productsimpletextValue | Busca em ProductSimpleText por productfilterId e valor exato em productsimpletextValue (ou LIKE se forcelikefilter estiver ativo no script de busca). |
| Variação | variation_{variationoptSearchName} (no HTML do Sass o link não inclui =; o valor útil é o nome do parâmetro após variation_) | listVariationFilterGroups → variationName; em cada item: variationoptSearchName, variationoptName | Filtra por VariationOpt.variationoptSearchName; várias variações na URL fazem interseção de produtos. |
| Marca | brand_{brandId}={brandName} | listBrandFilters: brandId, brandName | Filtra Product por brandId; com outros filtros ativos, o resultado é intersectado com eles (search3.php). |
| Recurso | Função |
|---|---|
| listPriceRangeFloors | Pisos numéricos vindos do DS; deles são derivados listPriceRangeLinks. |
| listSimpleTextFilters | Lista plana antes do agrupamento; o template costuma usar só listSimpleTextFilterGroups. |
| listVariationFilters | Lista plana de variações; o template usa listVariationFilterGroups. |
| listHasProducts | Indica se há produtos na categoria (útil para esconder blocos). |
| listCategoryBannerSrc | Banner da categoria (imagem), não filtra resultados. |
<h1>{{product.productTitle}}</h1>
{{#if productSchemaHasJsonLd}}
<script type="application/ld+json">{{productSchemaJsonLdRaw}}</script>
{{/if}}
var products = safeJsonParseB64('{{productsJsonB64}}', safeJsonParse('{{productsJson}}', []));
var priceLabelData = safeJsonParseB64('{{priceLabelDataJsonB64}}', safeJsonParse('{{priceLabelDataJson}}', {}));
var paymentDiscounts = safeJsonParseB64('{{paymentDiscountsJsonB64}}', safeJsonParse('{{paymentDiscountsJson}}', {}));
var categoryDiscounts = safeJsonParseB64('{{categoryDiscountsJsonB64}}', safeJsonParse('{{categoryDiscountsJson}}', {}));
var productsDiscounts = safeJsonParseB64('{{productsDiscountsJsonB64}}', safeJsonParse('{{productsDiscountsJson}}', {}));
Além das funções para um único filtro como {{#if productHasRichDescription}} para descrição rica é possível invocar o filtro diretamente pelo id para uso no layout, conforme:
Exemplo simples onde se sabe que o filtro retorna só um conteúdo como texto simples:
<div data-filter-1430='{{productFiltersById.1430}}'></div>
Exemplos mais avançados para cada tipo de filtro e seu conteúdo:
1) Filtro simples
Retorno esperado em filtersById['1430']: string JSON com:
<script> const rawSimple = filtersById['1430']; // ex: '{"filterKey":"Cor","filterValue":"Azul",...}' let simple = null; try { simple = JSON.parse(rawSimple); } catch(e) {} if (simple) { console.log(simple.filterKey, simple.filterValue, simple.filterSearchKey, simple.filterSearchValue); }</script>
2) Filtro rich text
Retorno esperado em filtersById['1431']: string HTML (ou '')
<div id="richTextFilterBox"></div><script> const richHtml = filtersById['1431'] || ''; document.getElementById('richTextFilterBox').innerHTML = richHtml;</script>
3) Filtro de mídias
Retorno esperado em filtersById['1432']: array de strings JSON, cada item com:
<script> const mediaRows = Array.isArray(filtersById['1432']) ? filtersById['1432'] : []; const mediaList = mediaRows .map((row) => { try { return JSON.parse(row); } catch(e) { return null; } }) .filter(Boolean); mediaList.forEach((m) => { console.log(m.productmediasUrl, m.productmediasType); });</script>
4) Filtro HTML (tipo 3)
Retorno esperado em filtersById['1433']: string HTML (ou '')
<div id="htmlFilterBox"></div><script> const htmlFilter = filtersById['1433'] || ''; document.getElementById('htmlFilterBox').innerHTML = htmlFilter;</script>
| Recurso | O que faz | Exemplo |
|---|---|---|
| {{productSeoPageTitleEscaped}} | Título da página do produto | Notebook Gamer X - Minha Loja |
| {{productSeoMetaDescriptionEscaped}} | Meta description | Notebook Gamer X com placa dedicada... - Notebook Gamer X |
| {{productSeoCanonicalHrefEscaped}} | URL canônica do produto | https://loja.exemplo.com/catalogo/item/notebook-gamer-x |
| {{productSeoKeywordsEscaped}} | Keywords geradas a partir do título | Notebook,Gamer,X |
| {{productSeoAuthorEscaped}} | Autor da página | Equipe Minha Loja |
| {{productSeoGeoPositionEscaped}} | Coordenadas geo | -23.5505;-46.6333 |
| {{productSeoGeoPlacenameEscaped}} | Nome do local | Minha Loja Ltda |
| {{productSeoGeoRegionEscaped}} | Região geo | BR-SP |
| {{productSeoBaseHrefEscaped}} | <base href> da página | https://loja.exemplo.com/catalogo/ |
| {{productSeoOgTitleEscaped}} | Open Graph title | Notebook Gamer X - Minha Loja |
| {{productSeoOgImageEscaped}} | Open Graph image | https://cdn.exemplo.com/produto.jpg |
| {{productSeoOgUrlEscaped}} | Open Graph URL | https://loja.exemplo.com/catalogo/item/notebook-gamer-x |
| {{productSeoOgDescriptionEscaped}} | Open Graph description | Notebook Gamer X com placa dedicada... |
| {{productSeoOgSiteNameEscaped}} | Nome do site no OG | Minha Loja |
| {{productSeoTwitterTitleEscaped}} | Título no Twitter Card | Notebook Gamer X em Minha Loja |
| {{productSeoTwitterImageEscaped}} | Imagem no Twitter Card | https://cdn.exemplo.com/produto.jpg |
| {{productSeoOrganizationJsonLdRaw}} | JSON-LD de Organization | {"@type":"Organization",...} |
| {{productSeoStoreJsonLdRaw}} | JSON-LD de Store | {"@type":"Store",...} |
| {{productSchemaJsonLdRaw}} | JSON-LD de Product | {"@type":"Product",...} |
| {{productInactiveRefreshUrlEscaped}} | Redirecionamento se produto estiver inativo | https://loja.exemplo.com |
| Recurso | O que faz | Exemplo |
|---|---|---|
| {{product.productId}} | ID do produto | 123 |
| {{product.productTitle}} | Nome do produto | Notebook Gamer X |
| {{product.productDescription}} | Descrição simples do produto | Notebook com 16GB de RAM... |
| {{product.productPrice}} | Preço bruto usado em partes simples do layout | 2999.90 |
| {{product.productSKU}} | SKU do produto | NOTE-GAMER-X |
| {{product.productUrl}} | Slug / URL do produto | notebook-gamer-x |
| {{product.brandName}} | Marca do produto | Dell |
| {{category.categoryName}} | Nome da categoria | Notebooks |
| {{category.categoryUrl}} | URL da categoria | /notebooks |
| Recurso | O que faz | Exemplo |
|---|---|---|
| {{productDetailHeroImg}} | Imagem principal simplificada usada em algumas versões do template | https://cdn.exemplo.com/produto.jpg |
| {{productMainImgSrc350Escaped}} | Imagem principal em resolução menor | https://cdn.exemplo.com/w_350_produto.jpg |
| {{productMainImgSrc500Escaped}} | Imagem principal média | https://cdn.exemplo.com/w_500_produto.jpg |
| {{productMainImgSrc700Escaped}} | Imagem principal maior | https://cdn.exemplo.com/w_700_produto.jpg |
| {{productMainTitleEscaped}} | Título escapado para alt e title | Notebook Gamer X |
| {{productGalleryThumbItems}} | Lista de thumbs extras da galeria | imagens / vídeos adicionais |
| {{productShowGalleryThumbs}} | Mostra ou oculta a galeria lateral | 1 ou 0 |
| {{productAdditionalMediaJson}} | JSON com mídias extras padrão | [{"additionalMainType":"0",...}] |
| {{productMainImageJson}} | JSON da imagem principal | "https://cdn.exemplo.com/w_700_produto.jpg" |
| {{productPriceIsConsultation}} | Indica preço “sob consulta” | 1 ou 0 |
| {{productPriceShowDePor}} | Exibe “De ... por ...” | 1 ou 0 |
| {{productPriceShowAPartir}} | Exibe “A partir de” | 1 ou 0 |
| {{productFullPriceFormatted}} | Preço cheio formatado | R$ 3.499,90 |
| {{productCurrentPriceFormatted}} | Preço atual formatado | R$ 2.999,90 |
| {{productPriceHasInstallments}} | Indica se há parcelamento | 1 ou 0 |
| {{productInstallmentCount}} | Quantidade de parcelas | 10 |
| {{productInstallmentValueFormatted}} | Valor da parcela formatado | R$ 299,99 |
| {{productPricePaymentMethodSmall}} | Controla <small> com meio de pagamento | 1 ou 0 |
| {{productPricePaymentMethodLabel}} | Nome do meio de pagamento | PIX |
| {{productFessText}} | Texto complementar de taxas / condições | texto curto |
| {{productDiscountPercentLabel}} | Label de desconto percentual | 10% OFF |
| {{productPriceFreeShippingEscaped}} | Texto de frete grátis | Frete grátis |
| {{productNumericPriceForJs}} | Preço numérico para scripts | 2999.9 |
| {{productNumericOriginalPriceForJs}} | Preço original numérico | 3499.9 |
| {{productPriceForInstallmentsJs}} | Base numérica para cálculo de parcelas | 2999.9 |
| {{productShowVariationBlock}} | Exibe bloco de variações | 1 ou 0 |
| {{productVariations}} | Estrutura completa das variações | lista de grupos |
| {{item.variationId}} | ID do grupo de variação | 5 |
| {{item.variationName}} | Nome do grupo | Cor |
| {{item.helpMessage}} | Ajuda exibida no grupo | Escolha uma opção |
| {{item.variationReqsOk}} | Estado interno da obrigatoriedade | 0 ou 1 |
| {{item.required}} | Indica se a variação é obrigatória | 1 ou 0 |
| {{item.optionId}} | ID da opção | 18 |
| {{item.optionParentId}} | ID pai da opção | 0 ou outro ID |
| {{item.inputType}} | Tipo do input | radio |
| {{item.lastChild}} | Marca opção final em árvore de variação | 1 ou 0 |
| {{item.optionSkuValue}} | SKU da opção | NOTE-GAMER-X-AZUL |
| {{item.optionPrice}} | Acréscimo / valor da opção | 50 |
| {{item.optionWeight}} | Peso adicional da opção | 0.2 |
| {{item.optionNameEsc}} | Nome da opção | Azul |
| {{item.optionHasImage}} | Se a opção tem imagem | 1 ou 0 |
| {{item.optionImageSrc}} | Imagem da opção | https://cdn.exemplo.com/azul.jpg |
| {{item.optionImageAltTitle}} | Alt/title da imagem da opção | Azul |
| {{item.optionShowPrice}} | Mostra preço adicional na label | 1 ou 0 |
| {{item.optionPricePlusLabel}} | Label do acréscimo | + R$ 50,00 |
| {{productVariationImagesB64}} | Mapa Base64 de imagens por variação | Base64 de JSON |
| Recurso | O que faz | Exemplo |
|---|---|---|
| {{productShowAddToCart}} | Exibe o botão de compra | 1 ou 0 |
| {{productCartTitleAttr}} | Nome enviado ao carrinho | Notebook Gamer X |
| {{productCartImgUrl}} | Imagem enviada ao carrinho | https://cdn.exemplo.com/w_100_produto.jpg |
| {{productShipAttrWidth}} | Largura para cálculo de frete | 30 |
| {{productShipAttrHeight}} | Altura para cálculo de frete | 8 |
| {{productShipAttrLength}} | Comprimento para cálculo de frete | 45 |
| {{productShipAttrFragile}} | Indica se é frágil | 1 ou 0 |
| {{productShipAttrWeight}} | Peso do produto | 1.2 |
| {{productShipAttrSku}} | SKU usado no bloco de frete | NOTE-GAMER-X |
| {{productShipAttrCategory}} | Categoria usada no frete | 10 |
| {{productShipAttrPrice}} | Preço usado no frete | 2999.90 |
| {{productShipAttrInternalId}} | ID interno usado no frete | 123 |
| {{productShipHasFreeShipping}} | Indica frete grátis | 1 ou 0 |
| {{productShipAttrFreeShippingMessage}} | Mensagem de frete grátis | Frete grátis para Sul e Sudeste |
| {{productShippingScriptAttrs}} | Atributos extras do script de frete | data-...="..." |
| {{productStockScriptSimple}} | Liga script de estoque simples | 1 ou 0 |
| {{productStockScriptVariation}} | Liga script de estoque por variação | 1 ou 0 |
| {{productStockWhatsappDigits}} | Telefone para fallback via WhatsApp | 11999999999 |
| {{productStockTitleUrlEncoded}} | Título codificado na URL | Notebook%20Gamer%20X |
| {{productStockOrgEscaped}} | Nome da loja para tooltip / title | Minha Loja |
| {{productStockTokenEscaped}} | Token do script de estoque | token |
| {{productStockSiteId}} | ID do site no script de estoque | 358 |
| {{productStockProductId}} | ID do produto no script de estoque | 123 |
| Recurso | O que faz | Exemplo |
|---|---|---|
| {{productHasRichDescription}} | Decide entre HTML rico e descrição plana | 1 ou 0 |
| {{productRichDescriptionRaw}} | HTML rico da descrição | <p><strong>Detalhes</strong>...</p> |
| {{productDescriptionPlainEscaped}} | Descrição simples escapada | Notebook com 16GB... |
| Recurso | O que faz | Exemplo |
|---|---|---|
| {{productRatingResumeEmpty}} | Indica ausência de avaliações | 1 ou 0 |
| {{productRatingResumeStars}} | Estrelas do resumo | lista com classes |
| {{productRatingResumeAverageFormatted}} | Média formatada | 4,8 |
| {{productRatingResumeQuantity}} | Quantidade de avaliações | 27 |
| {{productRatingCommentsEmpty}} | Indica ausência de comentários | 1 ou 0 |
| {{productRatingComments}} | Lista de comentários | lista estruturada |
| {{item.starClass}} | Classe visual da estrela | starFull |
| {{item.commentEscaped}} | Texto do comentário | Produto excelente. |
| {{item.dateFormatted}} | Data formatada | 16/04/2026 |
| {{item.hasReply}} | Se a loja respondeu | 1 ou 0 |
| {{item.replyEscaped}} | Resposta da loja | Obrigado pela avaliação! |
| Recurso | O que faz | Exemplo |
|---|---|---|
| {{listHasProducts}} | Controla a renderização dos relacionados | 1 ou 0 |
| {{products}} | Lista de produtos relacionados | array |
| {{item.id}} | ID do item relacionado | 456 |
| {{item.url}} | URL do item relacionado | mouse-gamer-y |
| {{item.img175}}, {{item.img250}}, {{item.img350}} | Imagens responsivas do relacionado | URLs |
| {{item.title}} | Título do produto relacionado | Mouse Gamer Y |
| {{searchTermsFirst}} | Primeiros termos mais buscados | lista |
| {{searchTermsMore}} | Termos extras | lista |
| {{searchTermsHasMore}} | Exibe botão “Mais” | 1 ou 0 |
| {{searchUserQuery}} | Termo buscado | notebook gamer |
| {{href}} | Link do termo buscado | https://.../q.php?... |
| {{position}} | Posição no breadcrumb / schema | 1 |
| Recurso | O que faz | Exemplo |
|---|---|---|
| {{mainData.siteDomain}} | Monta links absolutos | loja.exemplo.com |
| {{mainData.configPath}} | Prefixo das URLs do catálogo | /catalogo |
| {{mainData.siteId}} | ID do site em scripts | 358 |
| {{mainData.configHead}} | HTML extra no <head> | scripts / metas |
| {{mainData.configBody}} | HTML extra no fim do <body> | scripts |
| {{siteNameJson}} | Nome do site em JSON para JS | "Minha Loja" |
| {{globalDiscountEnabled}} | Desconto global ativo | 1 |
| {{globalDiscountType}} | Tipo do desconto global | 1 |
| {{bestPaymentEnabled}} | Melhor pagamento ativo | 1 |
| {{bestPaymentMethodLabel}} | Rótulo do melhor pagamento | PIX |
| {{visitsToken}} | Token do script de visitas | token |
| {{whatsappNomeAttr}}, {{whatsappLogoAttr}}, {{whatsappPhoneAttr}}, {{whatsappMsgAttr}} | Dados do botão flutuante de WhatsApp | valores configurados |
1) Exibição de produto simples (título, descrição, imagem principal, imagens adicionais e preço)
<section class="sectionProductDetail">
<div class="container productContainer">
<div class="row productDetails">
<div class="col-12 col-lg-7 productItemImg">
{{#if productShowGalleryThumbs}}
<div class="boxAdditionalMediaThumbs">
{{#each productGalleryThumbItems}}
{{#if item.isImage}}
<a data-fancybox="gallery" data-src="{{item.largeSrc}}">
<img width="55" height="75" src="{{item.thumbSrc}}" alt="{{item.thumbAlt}}">
</a>
{{/if}}
{{/each}}
</div>
{{/if}}
<div class="boxMainMedia">
<a data-fancybox="gallery" data-src="{{productMainImgSrc700Escaped}}">
<img src="{{productMainImgSrc700Escaped}}" alt="{{productMainTitleEscaped}}">
</a>
</div>
</div>
<div class="col-12 col-lg-5 productInfo">
<h1 class="productItemTitle">{{product.productTitle}}</h1>
<p class="productPrice">
{{#if productPriceIsConsultation}}
Sob consulta
{{else}}
{{productCurrentPriceFormatted}}
{{/if}}
</p>
{{#if productHasRichDescription}}
<div class="productItemDescription">{{productRichDescriptionRaw}}</div>
{{else}}
<p class="productItemDescription">{{productDescriptionPlainEscaped}}</p>
{{/if}}
</div>
</div>
</div>
</section>
2) Produto com título, descrição e variações
<section class="sectionProductDetail">
<div class="container productContainer">
<h1 class="productItemTitle">{{product.productTitle}}</h1>
{{#if productHasRichDescription}}
<div class="productItemDescription">{{productRichDescriptionRaw}}</div>
{{else}}
<p class="productItemDescription">{{productDescriptionPlainEscaped}}</p>
{{/if}}
{{#if productShowVariationBlock}}
<div class="boxVariations">
{{#each productVariations}}
<div class="variationContent" id="variationContent_{{item.variationId}}">
<p class="variationContentTitle">
{{item.variationName}}
<span class="variationContentTitleHelpMessage">{{item.helpMessage}}</span>
</p>
<div class="variationContentBoxOptions">
{{#each item.variationOptions}}
<div class="variationOptionContent" optId="{{item.optionId}}">
<input type="{{item.inputType}}" name="option_{{item.variationId}}" id="option_{{item.optionId}}_{{item.optionParentId}}" value="{{item.optionId}}" class="optionComponent" />
<label for="option_{{item.optionId}}_{{item.optionParentId}}" class="labelForOption">
{{#if item.optionHasImage}}
<img src="{{item.optionImageSrc}}" alt="{{item.optionImageAltTitle}}">
{{/if}}
<span>{{item.optionNameEsc}}</span>
{{#if item.optionShowPrice}}
<small>{{item.optionPricePlusLabel}}</small>
{{/if}}
</label>
</div>
{{/each}}
</div>
</div>
{{/each}}
</div><section class="sectionProductDetail">
<div class="container productContainer">
<h1 class="productItemTitle">{{product.productTitle}}</h1>
{{#if productHasRichDescription}}
<div class="productItemDescription">{{productRichDescriptionRaw}}</div>
{{else}}
<p class="productItemDescription">{{productDescriptionPlainEscaped}}</p>
{{/if}}
{{#if productShowVariationBlock}}
<div class="boxVariations">
{{#each productVariations}}
<div class="variationContent" id="variationContent_{{item.variationId}}">
<p class="variationContentTitle">
{{item.variationName}}
<span class="variationContentTitleHelpMessage">{{item.helpMessage}}</span>
</p>
<div class="variationContentBoxOptions">
{{#each item.variationOptions}}
<div class="variationOptionContent" optId="{{item.optionId}}">
<input type="{{item.inputType}}" name="option_{{item.variationId}}" id="option_{{item.optionId}}_{{item.optionParentId}}" value="{{item.optionId}}" class="optionComponent" />
<label for="option_{{item.optionId}}_{{item.optionParentId}}" class="labelForOption">
{{#if item.optionHasImage}}
<img src="{{item.optionImageSrc}}" alt="{{item.optionImageAltTitle}}">
{{/if}}
<span>{{item.optionNameEsc}}</span>
{{#if item.optionShowPrice}}
<small>{{item.optionPricePlusLabel}}</small>
{{/if}}
</label>
</div>
{{/each}}
</div>
</div>
{{/each}}
</div>
{{/if}}
</div>
</section>
3) Listas de produtos relacionados
<section class="relatedProducts">
<div class="container">
<h3>Produtos <strong>relacionados</strong></h3>
<div class="row productsList" id="relatedProductsContainer">
{{#if listHasProducts}}
{{#each products}}
<div class="col-6 col-lg-3 productItem" id="{{item.id}}">
<a href="https://{{mainData.siteDomain}}{{mainData.configPath}}/item/{{item.url}}">
<div class="productImg">
<picture>
<source media="(min-width:300px) and (max-width:499px)" srcset="{{item.img175}}">
<source media="(min-width:500px) and (max-width:699px)" srcset="{{item.img250}}">
<source media="(min-width:700px)" srcset="{{item.img350}}">
<img src="{{item.img350}}" alt="Imagem de {{item.title}}" loading="lazy">
</picture>
</div>
<div class="productDescription">
<h4 class="productTitle">{{item.title}}</h4>
<p class="productPrice js-product-price"></p>
</div>
</a>
</div>
{{/each}}
{{else}}
<p>Nenhum produto relacionado encontrado.</p>
{{/if}}
</div>
</div>
</section>
{{#if menuHasCategories}}
<ul class="menuList">
{{#each menuCategories}}
<li id="item_{{categoryId}}" parent="{{categoryParentId}}">
<a href="{{href}}">{{categoryName}} <span>{{qtd}}</span></a>
</li>
{{/each}}
</ul>
{{/if}}