Visión general

La estructura de carpetas estándar incluye layouts (ej.:
layouts/layout.tpl
),
templates de páginas (home, categoría, producto, etc.),
snipplets (componentes reutilizables) y la carpeta static (imágenes, CSS, JS). Consulta la documentación de las páginas en
docs.tiendanube.com.
Variables e interpolación
TWIG
{% set nombre = 'Camisa' %}
<p>{{ nombre }}</p>
{% set producto = { 'nombre': 'Camisa', 'precio': 99.9 } %}
<p>{{ producto.nombre }} - $ {{ producto.precio }}</p>
JavaScript
const nombre = 'Camisa';
document.body.innerHTML += `${nombre}
`;
const producto = { nombre: 'Camisa', precio: 99.9 };
document.body.innerHTML += `${producto.nombre} - $ ${producto.precio}
`;
PHP
$nombre = 'Camisa';
echo "$nombre
";
$producto = [ 'nombre' => 'Camisa', 'precio' => 99.9 ];
echo "{$producto['nombre']} - $ {$producto['precio']}
";
Condicionales (if / elseif / else)
TWIG
{% set stock = 5 %}
{% set preventa = false %}
{% if stock > 0 %}
En stock
{% elseif preventa %}
Preventa
{% else %}
Agotado
{% endif %}
JavaScript
const stock = 5;
const preventa = false;
let estado;
if (stock > 0) estado = 'En stock';
else if (preventa) estado = 'Preventa';
else estado = 'Agotado';
PHP
$stock = 5;
$preventa = false;
if ($stock > 0) {
$estado = 'En stock';
} elseif ($preventa) {
$estado = 'Preventa';
} else {
$estado = 'Agotado';
}
Operador ternario y valor por defecto (null coalescing)
TWIG
{# Operador ternario #}
{% set badge = (stock > 0) ? 'success' : 'danger' %}
{# Valor por defecto con default #}
{{ titulo | default('Sin título') }}
{# Coalescencia nula (cuando esté disponible) #}
{{ subtitulo ?? 'Opcional' }}
JavaScript
const badge = stock > 0 ? 'success' : 'danger';
const tituloMostrado = titulo ?? 'Sin título';
PHP
$badge = $stock > 0 ? 'success' : 'danger';
$tituloMostrado = $titulo ?? 'Sin título';
Iterar lista (arreglos)
TWIG
{% set tags = 'promoción,camisas,verano' | split(',') %}
<ul>
{% for tag in tags %}
<li>{{ tag }}</li>
{% endfor %}
</ul>
JavaScript
const tags = 'promoción,camisas,verano'.split(',');
const ul = document.createElement('ul');
for (const tag of tags) {
const li = document.createElement('li');
li.textContent = tag;
ul.appendChild(li);
}
PHP
$tags = explode(',', 'promoción,camisas,verano');
echo '';
foreach ($tags as $tag) {
echo "- $tag
";
}
echo '
';
Bucle por rango (range)
TWIG
{% for i in 1..5 %}
{{ i }}
{% endfor %}
JavaScript
for (let i = 1; i <= 5; i += 1) {
console.log(i);
}
PHP
for ($i = 1; $i <= 5; $i += 1) {
echo $i;
}
Vacío / Existencia
TWIG
{% if tags is empty %}
Sin etiquetas
{% endif %}
{% if producto is defined %}
{{ producto.nombre }}
{% endif %}
JavaScript
if (!tags || tags.length === 0) {
console.log('Sin etiquetas');
}
if (typeof producto !== 'undefined') {
console.log(producto.nombre);
}
PHP
if (empty($tags)) {
echo 'Sin etiquetas';
}
if (isset($producto)) {
echo $producto['nombre'];
}
Comparaciones y operadores útiles
TWIG
{% set precio = 120 %}
{% set tags = ['promoción', 'camisas'] %}
{% if precio >= 100 and precio < 200 %}Rango medio{% endif %}
{% if 'promoción' in tags %}Tiene promoción{% endif %}
{% if 'invierno' not in tags %}Sin invierno{% endif %}
JavaScript
const precio = 120;
const tags = ['promoción', 'camisas'];
if (precio >= 100 && precio < 200) console.log('Rango medio');
if (tags.includes('promoción')) console.log('Tiene promoción');
if (!tags.includes('invierno')) console.log('Sin invierno');
PHP
$precio = 120;
$tags = ['promoción', 'camisas'];
if ($precio >= 100 && $precio < 200) echo 'Rango medio';
if (in_array('promoción', $tags, true)) echo 'Tiene promoción';
if (!in_array('invierno', $tags, true)) echo 'Sin invierno';
Renderizado condicional de atributos/estilos (con settings)
TWIG (Tiendanube)
{# clases condicionales #}
<button class="btn {{ settings.header_colors ? 'btn-primary' : 'btn-secondary' }}"
style="color: {{ settings.text_color }}; background-color: {{ settings.background_color }};">
Comprar
</button>
{# atributo presente solo si hay enlace #}
<a {% if settings.menu_banner_mobile_url %}href="{{ settings.menu_banner_mobile_url }}"{% endif %}>
Banner
</a>
JavaScript
const settings = {
header_colors: true,
text_color: '#111',
background_color: '#f2f2f2',
menu_banner_mobile_url: 'https://ejemplo.com'
};
const cls = `btn ${settings.header_colors ? 'btn-primary' : 'btn-secondary'}`;
const style = `color:${settings.text_color};background-color:${settings.background_color};`;
const href = settings.menu_banner_mobile_url ? ` href="${settings.menu_banner_mobile_url}"` : '';
const html = `` +
`Banner`;
PHP
$settings = [
'header_colors' => true,
'text_color' => '#111',
'background_color' => '#f2f2f2',
'menu_banner_mobile_url' => 'https://ejemplo.com',
];
$cls = 'btn ' . ($settings['header_colors'] ? 'btn-primary' : 'btn-secondary');
$style = 'color:' . $settings['text_color'] . ';background-color:' . $settings['background_color'] . ';';
$href = !empty($settings['menu_banner_mobile_url']) ? ' href="' . $settings['menu_banner_mobile_url'] . '"' : '';
echo '';
echo 'Banner';
Algunos otros puntos importantes
{{ product.name | raw }}
{# Si product.name = "<b>Camisa</b>", renderiza Camisa en negrita #}
{{ product.name | upper }} {# CAMISA POLO #}
{{ product.name | lower }} {# camisa polo #}
{% set tags = product.tags | split(',') %}
<ul>
{% for tag in tags %}
<li>{{ tag }}</li>
{% endfor %}
</ul>
{# Si product.tags = "promoción,camisas,verano" #}
{{ (product.tags | split(','))[0] | capitalize }} {# Primera etiqueta en mayúsculas #}
{{ (product.tags | split(',')) | last | lower }} {# Última etiqueta en minúsculas #}
{# Bucle con filtro aplicado #}
{% for tag in product.tags | split(',') %}
<span class="tag">{{ tag | trim | upper }}</span>
{% endfor %}