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)

  1. Descarga y descomprime el tema inicial.
  2. Renombra el slug en theme.json.
  3. Edita las secciones en sections/; añade snippets en snippets/.
  4. 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, sin javascript: 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.

Contáctanos

Síguenos