Primeros pasos
Los temas son Liquid en un entorno aislado — plantillas solo de datos renderizadas en el servidor contra un contrato de datos fijo. Los temas se entregan con cero JavaScript: el carrito, las opciones de artículos y el pago provienen del runtime de comercio de la plataforma, al que tu marcado se vincula de forma declarativa.
Descargar el tema inicial (.zip)
- Descarga y descomprime el tema inicial.
- Renombra el
slugentheme.json. - Edita las secciones en
sections/; añade snippets ensnippets/. - Comprime el contenido de la carpeta en un ZIP y envíalo para revisión.
Estructura del paquete
mytheme.zip
├── theme.json # manifest (data, never code)
├── templates/index.json # OS 2.0 sectioned template (or index.liquid single-file)
├── sections/*.liquid # section files, each with its schema block
├── snippets/*.liquid # reusable partials for the render tag
├── config/settings_schema.json # theme-level settings (Shopify-style groups)
├── locales/en.json … # theme strings for the t filter
├── assets/ # css / images / fonts — static only
└── preview.png # listing screenshot
Límites: 10 MB C.P. 2 MB por archivo, profundidad de carpetas ≤ 3. Tipos de archivo permitidos: .liquid .json .css .png .jpg .jpeg .webp .svg .woff2.
Sin PHP. Sin JavaScript. Los SVG no deben contener script ni foreignObject.
theme.json Manifiesto
{
"name": "My Theme",
"slug": "my-theme", // letters/numbers/dashes — becomes the install path
"version": "1.0.0", // published versions are immutable; ship updates as new versions
"author": "You",
"description": "…",
"min_platform_version": "2.0"
}
Plantillas y secciones (OS 2.0)
templates/index.json lista instancias de sección; cada sección es un archivo Liquid en
sections/ que lleva su esquema de ajustes en un bloque schema. Límites:
≤ 25 secciones por plantilla, ≤ 50 bloques por sección.
// templates/index.json
{
"sections": {
"hero": { "type": "hero", "settings": { "heading": "Welcome" } },
"menu": { "type": "menu-grid",
"blocks": { "b1": { "type": "badge", "settings": { "label": "New" } } },
"block_order": ["b1"] }
},
"order": ["hero", "menu"]
}
Dentro de un archivo de sección recibes section.id, section.type,
section.settings.* y section.blocks (cada bloque:
id / type / settings.*). Tipos de ajuste: text, textarea,
color, checkbox, select (Opciones), range
(mín/máx), image_picker.
Datos — la referencia de Drop
Las plantillas pueden acceder a solo las propiedades de abajo (generadas a partir de las clases Drop de la plataforma — esta tabla no puede desviarse). Globales:
restaurant, options, settings, menu,
allergies, banners, branches, active_branch,
table, customer, localization, flags,
stats, y section dentro de los archivos de sección. Cualquier otra cosa se renderiza en blanco (y da error al subir).
AllergyDrop
id int
image string
title string
BannerDrop
id int
image string
image_url string
link_url string
subtitle string
title string
BlockDrop
id string
settings App\Storefront\Drops\SettingsDrop
type string
BranchDrop
accepts_orders bool
id int
is_open bool
name string
status string
CategoryDrop
id int
image_url string
items array
name string
CustomerDrop
name string
phone string
store_credit float
store_credit_formatted string
ExtraDrop
id int
name string
price float
FlagsDrop
allow_order bool
delivery bool
on_table bool
payment bool
scheduling bool
takeaway bool
ItemDrop
description string
dietary_tags array
extras array
has_variants bool
id int
image string
is_daily_special bool
is_gluten_free bool
is_halal bool
is_popular bool
is_sold_out bool
is_vegan bool
name string
option_groups array
price float
rating float
rating_count int
variants array
LanguageDrop
code string
direction string
name string
LocalizationDrop
currencies array
current App\Storefront\Drops\LanguageDrop
direction string
languages array
MenuDrop
categories array
is_empty bool
items array
OptionGroupDrop
choices array
id int
max_select int
min_select int
name string
required bool
OptionsDrop
allow_call_waiter bool
allow_coupons bool
allow_dietary_filters bool
allow_multi_branch_switch bool
allow_order_scheduling bool
allow_tips bool
currency_code string
currency_pos string
currency_sign string
customer_auth_mode string
delivery_charge float
enable_multi_currency bool
menu_sections string
min_order_value float
open_close_store bool
tax_charge float
tax_label string
whatsapp_number string
RestaurantDrop
address string
color string
cover string
description string
id int
logo string
main_image string
phone string
slug string
sub_title string
title string
SectionDrop
blocks array
id string
settings App\Storefront\Drops\SettingsDrop
type string
SettingsDrop
StatsDrop
scans_today int
TableDrop
id int
table_no string
VariantDrop
id int
name string
price float
Filtros y etiquetas
Filtros de la plataforma (más el conjunto estándar seguro de Liquid — escape, date, where, map, sort, size…):
media_urlmoneymoney_codettheme_asset
t— traduce una clave. De solo lectura; las claves desconocidas devuelven la propia clave.money/money_code— da formato a un precio con la moneda del restaurante.media_url— URL de imagen del restaurante:{{ item.image | media_url: 'menu' }}(tipos: menu, logo, cover, allergy, banner).theme_asset— URL de uno de tus recursos incluidos:{{ 'css/style.css' | theme_asset }}.
Etiquetas schema (ajustes de sección, eliminados de la salida), render
(snippets por nombre — tu snippets/ solo dir), commerce (emite el runtime de comercio una vez por página). Los filtros/etiquetas desconocidos fallan al subir.
Runtime de comercio
Caída {% commerce %} una vez (normalmente al final de tu plantilla), luego vincula con atributos data — el runtime gestiona el estado del carrito, la hoja de opciones y el pago:
<button data-mb-add="{{ item.id }}">Add</button>
<span data-mb-cart-count></span>
<span data-mb-cart-total></span>
<button data-mb-open-cart>Cart</button>
<button data-mb-call-waiter>Call waiter</button>
<div data-mb-item-sheet-mount hidden></div>
<div data-mb-cart-mount hidden></div>
Personaliza la interfaz del runtime mediante sus .mb-* clases y propiedades personalizadas de CSS
(--mb-sheet-bg, --mb-sheet-ink, --mb-accent).
Ajustes del comercio
Los comercios personalizan tu tema en el panel según tus esquemas. Precedencia: valores por defecto del esquema ← valores de la plantilla ← valores del comercio. Los ajustes se guardan de forma independiente de la versión del tema, así que publicar una actualización nunca borra la personalización de un comercio.
Reglas y límites
- No
<script>, sin manejadores de eventos en línea, sinjavascript:URLs, sin iframes — rechazados al subir. - Escapa los datos visibles para el usuario:
{{ item.name | escape }}. - Los renderizados tienen límites de recursos (longitud de salida + trabajo del motor). Una sección que falla en tiempo de ejecución se omite, nunca una página en blanco; al subir es un error grave.
- Las versiones publicadas son inmutables — las actualizaciones son versiones nuevas que pasan por revisión.
- Usa propiedades lógicas de CSS (
inline-size,margin-inline…) — los menús también se renderizan en RTL.
