Ir al contenido principal

Sección 04

04 · Online Store 2.0

Anatomía del theme, JSON templates, dynamic sources.

Qué vas a ejecutar en esta sección

  1. rm templates/product.liquid — Elimina el template legacy antes de crear el JSON (desde brew-atlas-theme/)
  2. shopify theme push --store brew-atlas-dev.myshopify.com — Sube el theme con los nuevos archivos al store de desarrollo (desde brew-atlas-theme/)

Buscá los bloques con badge ✓ Ejecutar en el contenido. Los bloques con 📖 Referencia son ilustrativos — no los ejecutes.

En una frase

Online Store 2.0 (2021) cambió la unidad fundamental de composición de los themes: en lugar de templates Liquid monolíticos con secciones hardcodeadas, los templates son JSON que declaran qué secciones aparecen y en qué orden. Eso le da al comerciante control real desde el Theme Editor, sin tocar código.

Qué es y por qué existe

Antes de 2021, el modelo de themes de Shopify era conocido informalmente como OS 1.0. En ese modelo, los templates de página (product.liquid, collection.liquid, index.liquid) eran archivos Liquid que mezclaban lógica de presentación con la estructura de la página. Si querías agregar una sección al PDP — un bloque de “Productos relacionados” después de la descripción, por ejemplo — tenías que hardcodearlo en product.liquid. El comerciante no podía cambiar la estructura desde el Theme Editor sin que el desarrollador modificara el código.

Online Store 2.0 invirtió este modelo. Ahora un template de página (templates/product.json) es un JSON que declara qué sections componen la página, con qué settings iniciales, y en qué orden. El Theme Editor lee ese JSON y le presenta al comerciante una interfaz para reordenar secciones, cambiar sus settings, agregar o quitar bloques — todo sin código. El código Liquid de cada sección describe la lógica de presentación de esa sección específica, no la estructura global de la página.

Esto tiene un nombre en software: composición declarativa. En lugar de procedural (“primero imprime esto, luego aquello, luego lo otro”), declaras las piezas y el sistema las ensambla.

Anatomía del theme

Un theme de OS 2.0 sigue esta estructura de directorios:

theme/
├── assets/           # archivos estáticos: CSS, JS, imágenes, fuentes
├── blocks/           # theme blocks (2025+) — reusables entre sections
├── config/
│   ├── settings_schema.json   # define los settings globales del theme
│   └── settings_data.json     # valores actuales de los settings
├── layout/
│   └── theme.liquid  # el HTML raíz: <html>, <head>, <body> para todas las páginas
├── locales/
│   └── en.default.json        # strings para internacionalización
├── sections/         # archivos .liquid, uno por section
├── snippets/         # partials .liquid sin schema — reutilizables con render
└── templates/        # entry points por tipo de página
    ├── product.json  # OS 2.0: JSON template
    ├── collection.json
    ├── index.json    # homepage
    ├── page.json
    ├── blog.json
    ├── article.json
    └── cart.json

Cada directorio tiene su responsabilidad fija. Shopify valida la estructura al subir el theme — archivos en lugares incorrectos causan errores de validación.

layout/theme.liquid

Es el HTML raíz que envuelve todas las páginas. Aquí van los <head> tags, los CSS globales, el JavaScript de tema, y el tag {{ content_for_layout }} que es donde Shopify inyecta el contenido de cada template. No puedes tener más de un layout file (salvo el caso especial del layout del checkout, que es diferente).

Edita ~/proyectos/shopify/brew-atlas/brew-atlas-theme/layout/theme.liquid (ya existe en el scaffold del CLI — este es el contenido de referencia):

{%- comment -%} layout/theme.liquid {%- endcomment -%}
<!doctype html>
<html lang="{{ request.locale.iso_code }}">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>
      {{ page_title }}
      {%- if current_tags %} &ndash; {{ current_tags | join: ', ' }}{%- endif -%}
      {%- unless page_title contains shop.name %} &ndash; {{ shop.name }}{%- endunless -%}
    </title>
    {{ content_for_header }}
    {{ 'base.css' | asset_url | stylesheet_tag }}
  </head>
  <body>
    {%- sections 'header-group' -%}
    <main id="MainContent">
      {{ content_for_layout }}
    </main>
    {%- sections 'footer-group' -%}
    {{ 'theme.js' | asset_url | script_tag }}
  </body>
</html>

content_for_header inyecta los scripts de Shopify (analytics, App Bridge si hay apps embebidas, etc.). No puedes omitirlo sin romper funcionalidades del ecosistema.

config/settings_schema.json

Define los settings globales del theme que aparecen en “Preferencias del theme” en el Theme Editor. Colores, tipografías, opciones de comportamiento global. La estructura es un array de grupos de settings.

Edita ~/proyectos/shopify/brew-atlas/brew-atlas-theme/config/settings_schema.json:

[
  {
    "name": "theme_info",
    "theme_name": "Brew Atlas",
    "theme_author": "Tu nombre",
    "theme_version": "1.0.0",
    "theme_documentation_url": "https://github.com/...",
    "theme_support_email": "support@example.com"
  },
  {
    "name": "Colores",
    "settings": [
      {
        "type": "color",
        "id": "color_background",
        "label": "Color de fondo",
        "default": "#FFFFFF"
      },
      {
        "type": "color",
        "id": "color_text",
        "label": "Color de texto",
        "default": "#1A1A1A"
      }
    ]
  }
]

Estos settings se leen en Liquid con {{ settings.color_background }}.

JSON templates

Un JSON template define la composición de sections para un tipo de página. Aquí está la anatomía de templates/product.json — es un ejemplo introductorio, el JSON final de Brew Atlas está más abajo:

{
  "sections": {
    "pdp": {
      "type": "pdp",
      "settings": {
        "show_vendor": true,
        "show_sku": false
      }
    },
    "related-products": {
      "type": "related-products",
      "settings": {
        "heading": "También te puede interesar",
        "products_to_show": 4
      }
    }
  },
  "order": ["pdp", "related-products"]
}

La estructura tiene dos partes:

  • sections: un objeto donde cada key es un ID único de sección en esta página, y el valor define qué section type usar ("type" coincide con el nombre del archivo sections/pdp.liquid) y sus settings iniciales.
  • order: el array que determina el orden de renderizado de las sections.

El comerciante puede, desde el Theme Editor, reordenar las secciones (cambia order), cambiar los settings (cambia los valores en sections[id].settings), o agregar/quitar secciones completamente — todo sin código, todo guardado como cambios a este JSON en el store.

Sections everywhere

Antes de OS 2.0, las sections solo podían aparecer en la homepage. OS 2.0 habilitó sections en cualquier template de página (sections everywhere). Eso es lo que hace posible los JSON templates: puedes declarar cualquier combinación de sections en cualquier página.

Preset sections y sticky sections

Algunas sections tienen presets definidos en su schema — configuraciones iniciales que aparecen en el picker “Agregar sección” del Theme Editor. Las sticky sections (header, footer) se declaran como sections-group y aparecen fijas en todas las páginas sin estar en el JSON template de cada una.

Dynamic sources

Una de las features más poderosas de OS 2.0 (mejorada consistentemente desde el lanzamiento) son los dynamic sources: la capacidad de conectar un setting de una section a un metafield del objeto de la página actual, directamente desde el Theme Editor — sin código adicional.

Por ejemplo: si tienes una section de “Notas de cata” en el PDP de Brew Atlas, puedes crear un setting de tipo richtext en el schema de esa section. Desde el Theme Editor, el comerciante puede apuntar ese setting al metafield product.metafields.custom.tasting_notes. A partir de ese momento, cada producto muestra sus propias notas de cata en esa section — el dato viene del metafield del producto, no de un setting fijo.

Esto elimina una clase entera de personalización que antes requería código: el comerciante puede conectar cualquier dato del catálogo a cualquier section que exponga un setting compatible. La sección 06 cubre metafields en detalle.

Puentes mentales

Desde Angular/React

Un JSON template de OS 2.0 es a un theme de Shopify lo que un archivo de rutas con lazy-loading es a una app de Angular: composición declarativa de componentes (sections) donde el sistema decide cómo ensamblarlos, no el código imperativo que los llama en orden. OS 1.0 era JSP o Blade templates de Laravel: HTML procedural donde tú decidías qué se imprimía y cuándo. OS 2.0 es composición declarativa.

El Theme Editor que usa el comerciante para reconfigurar las secciones es análogo a un builder visual que modifica el archivo de rutas y las props de los componentes. El developer define los posibles componentes (sections) y sus props (settings); el comerciante (o el merchant onboarding team) decide cómo ensamblarlos en cada página.

Estado 2026

OS 2.0 como branding se mantiene. Los cambios desde el lanzamiento en 2021 han sido aditivos — no se han roto las APIs del modelo. Lo más relevante de los últimos 12 meses:

  • Theme blocks (2025): una capa adicional de composición por encima de las section blocks. La sección 05 lo cubre en profundidad.
  • Horizon (2025): el nuevo tema de referencia de Shopify está construido completamente sobre theme blocks. Si analizas un tema moderno para aprender, Horizon es el punto de partida.
  • Los dynamic sources se expandieron para soportar más tipos de metafields (URL, referencias, JSON) como fuentes válidas.
  • Section groups: el mecanismo para sections sticky (header/footer) que aparecen en todas las páginas independientemente del template JSON de cada una.

Sintaxis y anatomía detallada

Sections y su schema

Un archivo de section (sections/related-products.liquid) tiene dos partes: el template Liquid en la parte superior y el schema JSON al final.

Crea ~/proyectos/shopify/brew-atlas/brew-atlas-theme/sections/related-products.liquid:

{%- comment -%} sections/related-products.liquid {%- endcomment -%}
{%- if section.settings.heading != blank -%}
  <h2 class="section-heading">{{ section.settings.heading }}</h2>
{%- endif -%}
 
{%- if recommendations.performed -%}
  <ul class="product-grid">
    {%- for product in recommendations.products limit: section.settings.products_to_show -%}
      {%- render 'product-card', product: product, show_vendor: section.settings.show_vendor -%}
    {%- endfor -%}
  </ul>
{%- else -%}
  <p class="no-results">No hay recomendaciones disponibles.</p>
{%- endif -%}
 
{% schema %}
{
  "name": "Productos relacionados",
  "settings": [
    {
      "type": "text",
      "id": "heading",
      "label": "Título",
      "default": "También te puede interesar"
    },
    {
      "type": "range",
      "id": "products_to_show",
      "label": "Productos a mostrar",
      "min": 2,
      "max": 8,
      "step": 2,
      "default": 4
    },
    {
      "type": "checkbox",
      "id": "show_vendor",
      "label": "Mostrar proveedor",
      "default": false
    }
  ],
  "presets": [
    {
      "name": "Productos relacionados"
    }
  ]
}
{% endschema %}

Los tipos de setting disponibles en schemas incluyen: text, textarea, richtext, html, number, range, checkbox, select, radio, color, color_background, font_picker, collection, product, blog, page, link_list, url, video, video_url, image_picker, inline_richtext, header, paragraph.

El JSON template final de Brew Atlas

Crea (o reemplaza si existe) ~/proyectos/shopify/brew-atlas/brew-atlas-theme/templates/product.json:

{
  "sections": {
    "pdp": {
      "type": "pdp",
      "settings": {
        "show_vendor": true,
        "show_sku": true,
        "show_quantity_selector": true
      }
    },
    "related-products": {
      "type": "related-products",
      "settings": {
        "heading": "También te puede interesar",
        "products_to_show": 4,
        "show_vendor": false
      }
    }
  },
  "order": ["pdp", "related-products"]
}

Proyecto · Brew Atlas

Brew Atlas · Paso 4

El primer cambio real en la estructura del theme de Brew Atlas es reemplazar cualquier template Liquid de producto con el JSON template de OS 2.0. Esto establece el patrón que vamos a seguir en todas las páginas: composición declarativa, sections separadas, settings configurables desde el Theme Editor.

Qué vas a crear/tocar en esta sección (archivos):

  • ~/proyectos/shopify/brew-atlas/brew-atlas-theme/templates/product.json — crea este archivo (o reemplaza el product.liquid existente). El contenido está en “El JSON template final de Brew Atlas” arriba.
  • ~/proyectos/shopify/brew-atlas/brew-atlas-theme/sections/related-products.liquid — crea este archivo. El contenido está en “Sections y su schema” arriba.
  • ~/proyectos/shopify/brew-atlas/brew-atlas-theme/layout/theme.liquid — edita (ya existe en el scaffold) con el contenido de referencia de esta sección.
  • ~/proyectos/shopify/brew-atlas/brew-atlas-theme/config/settings_schema.json — edita con los settings globales de Brew Atlas.

Las copias de referencia del tutorial viven en brew-atlas/theme/ (en este repo).

Comandos a ejecutar (orden):

Si tienes el template product.liquid en tu scaffold, elimínalo antes de crear product.json — los dos no pueden coexistir.

Desde ~/proyectos/shopify/brew-atlas/brew-atlas-theme/:

Ejecutar Eliminar template legacy

rm templates/product.liquid

Para sincronizar el theme local con tu store de desarrollo después de crear los archivos:

Desde ~/proyectos/shopify/brew-atlas/brew-atlas-theme/:

Ejecutar Subir theme al store de desarrollo

shopify theme push —store brew-atlas-dev.myshopify.com

El archivo templates/product.json conecta la section pdp (que construiremos en la sección 05) con la section related-products. La página de producto de Brew Atlas queda compuesta por dos sections independientes que el comerciante puede reordenar o configurar sin tocar código.

Errores comunes

Cuidado

Si tu archivo se llama product.liquid y product.json existen al mismo tiempo en /templates/, el comportamiento es indefinido — Shopify puede usar cualquiera de los dos dependiendo del contexto. Elimina el .liquid cuando migres a JSON templates. El CLI advierte sobre esto, pero no lo corrige automáticamente.

Cuidado

El "type" en el JSON template debe coincidir exactamente con el nombre del archivo de la section en sections/, sin la extensión .liquid. Si tu section se llama sections/pdp.liquid, el tipo es "pdp". Si hay un typo o diferencia de capitalización, la section no renderiza y el error no es obvio.

Nota

Los JSON templates no reemplazan a los templates Liquid en todos los casos. El layout theme.liquid sigue siendo Liquid. Los snippets son siempre Liquid. Y puedes tener un template Liquid como password.liquid para la página de contraseña de la tienda, que no necesita ser configurable desde el Theme Editor. El JSON template es para páginas donde el comerciante necesita control de composición.

Tip

Cuando el Theme Editor guarda cambios, modifica directamente el JSON del template en el store (no en tu repositorio local). Si necesitas sincronizar esos cambios al repositorio, ejecuta desde ~/proyectos/shopify/brew-atlas/brew-atlas-theme/:

shopify theme pull --store brew-atlas-dev.myshopify.com

Eso baja la versión actual del theme del store a tu directorio local.

Checklist senior

Checklist senior

  • Puedes explicar la diferencia entre un template OS 1.0 y un JSON template de OS 2.0
  • Sabes qué hace content_for_layout y por qué es necesario en theme.liquid
  • Puedes leer un templates/product.json y decir exactamente qué sections se van a renderizar y en qué orden
  • Sabes dónde vive la configuración global del theme y cómo leerla en Liquid
  • Entiendes qué son los dynamic sources y cuándo son la solución correcta vs hardcodear un valor
  • Sabes que el "type" de una section en el JSON template debe coincidir con el nombre del archivo .liquid
  • Puedes escribir el schema de una section con al menos 3 tipos de settings diferentes
  • Sabes la diferencia entre sections, snippets y layouts — cuándo usar cada uno

Quiz

Quiz · ¿Lo tenés claro?

5 preguntas · respondé para marcar la sección como completada.

  1. 1. ¿Qué diferencia principal introdujo OS 2.0 sobre OS 1.0?

  2. 2. En `templates/product.json` aparece `"type": "product-gallery"`. ¿Qué convención aplica?

  3. 3. ¿Qué hace `content_for_layout` en `theme.liquid`?

  4. 4. Quieres que el valor de un setting en el Theme Editor no sea un texto fijo, sino 'el nombre del producto actual' (dinámico por página). ¿Qué usas?

  5. 5. ¿Cuál es la diferencia correcta entre section, snippet y layout?

Siguiente

La sección que sigue entra en el detalle de sections y theme blocks: qué hace una section, cómo se declaran los blocks dentro de ella, y por qué en 2025 Shopify introdujo un modelo de blocks reutilizables que cambia la arquitectura de composición de themes. Es el concepto más nuevo del ecosistema de themes y merece atención cuidadosa.