VELSEFYVELSEFY Partners
Documentación de temas

Desarrolla temas
de tienda premium.

Construye, valida y publica temas Liquid para tiendas con la CLI de VELSEFY. Todo lo que necesitas para llevar tu tema del editor local a la tienda del cliente.

Documentación de temas de VELSEFY

Esta es la guía de TEMAS.

Si lo que desarrollas son APPS (integraciones de API, OAuth y webhooks), esa es una documentación distinta. Los flujos de apps no comparten estructura, tokens ni carpetas con los temas — no mezcles ambos contenidos. A continuación solo hablamos de temas Liquid.

01

Empieza aquí

Un tema en VELSEFY define la apariencia y la estructura de una tienda. Está hecho de archivos Liquid + JSON, organizado como una estructura de tienda estándar. Con la CLI puedes descargar un tema, editarlo localmente y publicarlo — sin tocar el panel web.

Lo que puedes construir y modificar:

Secciones

Bloques arrastrables con su propio {% schema %}. Cada una expone settings y blocks editables.

Snippets

Fragmentos reutilizables que incluís con {% render 'x' %}.

Assets y estilos

CSS, JS, imágenes y fuentes servidos desde assets/ con asset_url.

Plantillas

Páginas templates/*.json que componen la tienda con secciones.

El flujo típico es descargar → editar → validar → publicar. Empezá por el Quickstart para tener un tema corriendo en local en menos de dos minutos.

02

Quickstart

La CLI es el único requisito. Se instala global, se autentica con tu token de desarrollador y listo.

1

Instala la CLI de VELSEFY

Terminalbash
npm install -g @velsefy/cli
2

Obtén un token de acceso

Genera el token desde el panel de tu tienda → Aplicaciones Privadas. Este token identifica tu cuenta y define qué puedes hacer (ver Tokens y scopes).

Nunca compartas tu token

Es como una contraseña. No lo subas a git, no lo hardcodees en el tema ni lo publiques. Cualquiera con acceso a él puede operar tus temas.
3

Inicia sesión y verifica tus temas

Terminalbash
# Guarda el token (se almacena localmente en tu máquina)
velsefy login --token <TU_TOKEN>

# Lista los temas instalados en tu tienda
velsefy theme list
4

Descarga un tema base del catálogo

Terminalbash
velsefy theme pull-catalog --sku THEME-DEFAULT -o ./mi-tema

# → "Descargados N asset(s) del catálogo en ./mi-tema."
5

Edita en VS Code, valida y sube a TU tienda

Terminalbash
# Validación local (sin token, puro offline)
velsefy theme validate --dir ./mi-tema

# Sube los cambios a la instalación de tu tienda
velsefy theme push --install <INSTALL_ID> --dir ./mi-tema

Buenas prácticas para el día a día

  • Trabaja siempre sobre una carpeta local distinta del tema instalado y descarga desde la CLI, no desde el editor web. Así evitas pisar cambios.
  • Antes de theme push, corre theme validate. Un tema inválido nunca se sube.
  • Guarda el token en una variable de entorno (p. ej. VELSEFY_TOKEN) y evita escribirlo a mano en cada comando.
03

Estructura del tema

Un tema es una carpeta con subcarpetas fijas. El servidor solo acepta estos directorios; cualquier ruta fuera de ellos se rechaza al publicar.

mi-tema/tree
mi-tema/
├── layout/
│   └── theme.liquid       # Plantilla base (HTML + {{ content_for_layout }})
├── sections/              # Secciones arrastrables (cada una con {% schema %})
│   ├── hero.liquid
│   └── product_main.liquid
├── snippets/              # Fragmentos reutilizables ({% render 'x' %})
│   └── price.liquid
├── assets/                # CSS / JS / imágenes / fuentes
│   ├── theme.css
│   └── theme.js
├── config/
│   ├── settings_schema.json  # Settings globales (array de grupos)
│   └── settings_data.json    # Valores actuales del tema
├── templates/             # Plantillas de página (*.json)
│   ├── index.json
│   ├── product.json
│   └── page.json
└── theme.json             # (solo al exportar; wrapper con name/version)

Qué va en cada carpeta

CarpetaPropósito
layout/La plantilla base. Un solo theme.liquid con el shell HTML y el output dinámico con {{ content_for_layout }}.
sections/Secciones editables desde el editor. Cada archivo Liquid termina en {% schema %} para declarar sus settings.
snippets/Fragmentos que se reutilizan en varias vistas vía {% render 'x' %}. No se pueden arrastrar.
assets/CSS, JS, SVGs, imágenes y fuentes. Se referencian con {{ 'x.css' | asset_url }}.
config/settings_schema.json (declaración de settings) y settings_data.json (valores).
templates/Páginas en JSON que componen el layout con secciones.

Carpetas y extensiones permitidas

Carpetas permitidas: assets · sections · layout · snippets · config · templates.

Extensiones permitidas: css · js · mjs · json · svg · png · jpg · jpeg · webp · gif · ico · woff · woff2 · ttf · txt · xml · liquid.

Los path traversal (.., \\, %) están bloqueados.

¿Por qué la publicación rechaza un archivo?

  • La ruta está fuera de una carpeta permitida. Mueve el archivo dentro de assets, sections, layout, snippets, config o templates.
  • La extensión no está en la whitelist. Opciones habituales: css, js, json, svg o liquid.
  • El nombre intenta salir de la carpeta con .., con backslash o escapando barras. Estos valores se bloquean por seguridad.
04

Secciones y `{% schema %}`

Cada sección es un archivo sections/nombre.liquid y DEBE terminar con un bloque {% schema %}…{% endschema %} que declara su configuración. Ahí se definen settings (configuración de la sección), blocks (piezas internas repetibles) y presets (cómo aparece al agregarla).

sections/hero.liquidliquid
{% style %}
  #velsefy-section-{{ section.id }} .mi-hero {
    color: {{ section.settings.text_color }};
    background: {{ section.settings.bg_color }};
  }
{% endstyle %}

Los tres pilares del schema:

ClaveQué defineCómo se lee
settingsInputs editables de la sección.{{ section.settings.x }}
blocksSub-bloques repetibles y arrastrables.{% for block in section.blocks %} → {{ block.settings.x }}
presetsApariencia en el selector al crear la sección.—

Tipos de setting permitidos

VELSEFY soporta este subconjunto. Si usas un tipo que no está en la lista, el renderer no lo dibuja y velsefy theme validate lo reporta como error.

colorrangenumberselecttexttextareacheckboximage_pickerrichtexturl
sections/hero.liquid (schema)json
{% schema %}
{
  "name": "Hero",
  "tag": "section",
  "max_blocks": 4,
  "settings": [
    { "type": "text",     "id": "title",        "label": "Título", "default": "Bienvenido" },
    { "type": "color",    "id": "text_color",   "label": "Color de texto", "default": "#111827" },
    { "type": "image_picker", "id": "logo",     "label": "Imagen" },
    { "type": "url",      "id": "cta_link",     "label": "Enlace del botón" },
    { "type": "range",    "id": "font_scale",   "label": "Escala", "min": 100, "max": 130, "step": 5, "unit": "%", "default": 100 }
  ],
  "blocks": [
    {
      "type": "text",
      "name": "Texto",
      "settings": [
        { "type": "textarea", "id": "text", "label": "Texto" }
      ]
    }
  ],
  "presets": [
    { "name": "Hero", "blocks": [ { "type": "text" } ] }
  ]
}
{% endschema %}
05

Settings del tema y versión

Los settings globales se declaran en config/settings_schema.json como un array de grupos. Cada grupo tiene un name y un array de settings con los mismos tipos permitidos que en las secciones.

config/settings_schema.jsonjson
[
  {
    "name": "theme_info",
    "theme_name": "Mi Tema",
    "theme_version": "1.0.0",
    "theme_author": "Mi Agencia",
    "theme_documentation_url": "https://docs.velsefy.com",
    "theme_support_url": "https://support.velsefy.com"
  },
  {
    "name": "Colores",
    "settings": [
      { "type": "color",  "id": "primaryColor", "label": "Color Principal", "default": "#000000" },
      { "type": "range",  "id": "fontScale",    "label": "Escala", "min": 100, "max": 130, "step": 5, "unit": "%", "default": 100 },
      { "type": "select", "id": "fontFamily",   "label": "Fuente", "options": [{ "value": "Inter", "label": "Inter" }], "default": "Inter" },
      { "type": "checkbox","id": "enableX",     "label": "Habilitar X", "default": false }
    ]
  }
]

Se leen en el tema

Usa {{ settings.primaryColor }} o {{ settings.fontScale }} en cualquier Liquid del tema.

Versionado semver

La versión vive solo en theme_info.theme_version (MAJOR.MINOR.PATCH). Es la única fuente de verdad del tema. El grupo theme_info se descarta al renderizar: es solo metadata.

Versiona SIEMPRE con semver

No pongas la versión en otro archivo. Al publicar con velsefy theme release, la plataforma maneja la versión del catálogo y hace bump (patch por defecto; puedes pedir major/minor en el changelog).

Buenas prácticas con settings

  • Define un default para cada setting. Un tema sin defaults renderiza vacío y confunde al editor del cliente.
  • Usa id estables (en minúsculas, camelCase o snake_case) y no los cambies entre releases: romperías el settings_data.json existente.
  • Agrupa los settings por tema (colores, tipografía, layout). Un settings_schema.json plano y sin grupos es difícil de mantener.
06

Snippets, assets y plantillas

Snippets

Fragmentos reutilizables vía {% render 'nombre', parametros: valor %}. Son la forma de no repetir markup.

snippets/price.liquidliquid
{%- if price != blank -%}
  <span class="vs-price">{{ price | money }}</span>
{%- endif -%}
usoliquid
{% render 'price', price: product.price, compare_at: product.compare_price %}

Assets

Los archivos de assets/ se referencian con el filtro asset_url.

usoliquid
{{ 'theme.css' | asset_url | stylesheet_tag }}
{{ 'theme.js'  | asset_url | script_tag }}

Plantillas de página

Las plantillas templates/*.json componen la página declarando qué secciones van y en qué orden.

templates/index.jsonjson
{
  "sections": {
    "main": { "type": "hero", "settings": { "title": "Hola" } }
  },
  "order": ["main"]
}

Problema común: la sección no aparece

Si en el editor no se ve tu sección, la causa casi siempre es un presets ausente o mal escrito en el {% schema %}, o que el type de la plantilla no coincide con el nombre del archivo de sections/. Verifica que la sección tenga al menos un preset y que el archivo exista en la carpeta sections/.

07

Validación

Valida siempre antes de publicar. Hay dos capas: la local con la CLI y la del servidor al publicar. El servidor aplica las mismas reglas, así que un validate limpio evita errores al subir.

Terminalbash
# Local, sin necesidad de token (puede correr en CI)
velsefy theme validate --dir ./mi-tema

# → "Versión del tema (theme_info): 1.0.0"
# → "Tema válido."                                          si todo está OK
# → "Tema inválido (N problema(s))." + detalle por archivo  si hay errores

Qué chequea la validación

Balance Liquid

{% schema %}/{% endschema %} balanceados (y presentes en secciones) y {% if %}/{% endif %} balanceados.

Tipos de setting

Valida settings[].type contra la whitelist y exige el campo id.

JSON y paths

Todo .json debe parsear, y las rutas deben ser permitidas (sin ../\\/%).

Semver en theme_info

Extrae y valida theme_info.theme_version.

Autocompletado y errores inline en VS Code (opcional)

Conecta el JSON Schema del paquete para que VS Code valide config/settings_schema.json en vivo (tipos autocompletados + errores). Agrega esto a tu .vscode/settings.json:

.vscode/settings.jsonjson
{
  "json.schemas": [
    {
      "fileMatch": ["config/settings_schema.json"],
      "url": "https://raw.githubusercontent.com/fivepulsespa-spec/velsefy-cli/main/packages/theme-validate/velsefy.settings_schema.json"
    }
  ]
}

El schema vive en packages/theme-validate/velsefy.settings_schema.json del repositorio de la CLI.

Errores frecuentes de validación

  • {% schema %} sin {% endschema %} o con las llaves desbalanceadas. Asegúrate de cerrar el bloque y validar el JSON dentro.
  • settings[].type fuera de la whitelist o sin id. Usa exactamente uno de los tipos soportados.
  • theme_info.theme_version ausente o no semver. El validador exige un MAJOR.MINOR.PATCH válido.
08

Comandos de la CLI

Todos los comandos van bajo velsefy theme …, salvo login y logout que son globales.

ComandoQué hace¿Toca el tema?
login --token <t>Guarda localmente tu token de acceso.No
logoutElimina el token guardado del equipo.No
theme listLista los temas instalados en tu tienda (id, nombre, estado).No
theme pull --install <id>Descarga a local los assets de un tema instalado y guarda el base_updated_at para el push.Sí (lectura)
theme pull-catalog --sku <sku>Descarga los assets actuales de un tema del catálogo global (el base).Sí (lectura)
theme push --install <id> --dirSube los assets locales al tema instalado. Devuelve 409 si hay conflicto.Sí (escritura)
theme validate --dirValida el tema local (Liquid, JSON, paths, semver). No pide token.No
theme release --sku --changelog --dirPublica una release del tema al catálogo global.Sí (catálogo)

pull vs pull-catalog

theme pull descarga TU instalación (la copia privada que editas). theme pull-catalog baja el base oficial del catálogo para empezar de cero.

validate no pide token

theme validate es 100% local: útil para pre-push y CI sin credenciales. El resto de comandos de theme sí requieren sesión.

¿Cómo subo cambios sin pisar los del equipo?

El theme push usa el base_updated_at que guarda el theme pull para detectar conflictos. Si alguien más modificó el tema entre que descargaste y subiste, la CLI responde con 409 en lugar de sobrescribir ciegamente. La solución es hacer un theme pull de nuevo, resolver los cambios y reintentar el theme push.

09

Tokens y scopes

Tu token define qué capacidades tienes, no cómo está construido por dentro. Es un contrato público: los scopes describen solo lo que puedes hacer con temas. La CLI los traduce en acciones concretas.

Capacidades de tu token

  • Ver los temas instalados en tu tienda (theme list).
  • Descargar a local los assets de un tema (theme pull / theme pull-catalog).
  • Subir cambios a tu tema instalado (theme push).
  • Publicar releases al catálogo con credenciales de plataforma (theme release).

Scopes de acceso

read_themeswrite_themes

read_themes

Permite listar y descargar temas: operaciones de lectura sobre tu instalación y el catálogo.

write_themes

Permite subir cambios y publicar: operaciones de escritura sobre tus temas instalados y releases.

Token de la cuenta vs. credenciales de plataforma

Con el token de tu cuenta editas la copia privada de un tema (pull/push). Para publicar al catálogo global se usan credenciales de plataforma con permiso de publicación. Son dos contratos distintos; no los confundas.

¿Qué hago si mi token queda en el repositorio?

Si un token subió a git o a un historial público, considéralo comprometido y regenera uno nuevo de inmediato. El token viejo, aunque lo borres del archivo, ya no es seguro. Trabaja siempre con velsefy login --token desde una variable de entorno y no lo dejes en el código del tema.

10

Ejemplo completo

Vamos a crear una sección hero desde cero, validarla y publicarla en tu tienda. Todo en un solo tema local.

1

Descarga el tema base

Terminalbash
velsefy theme pull-catalog --sku THEME-DEFAULT -o ./mi-tema
2

Crea la sección assets y markup

Crea sections/hero.liquid con el render y su schema. Nota que el {% schema %} siempre cierra.

sections/hero.liquidliquid
{% comment %} Sección hero construida para el tema de ejemplo {% endcomment %}
<section class="mi-hero" style="background: {{ section.settings.bg_color }}">
  <h1 class="mi-hero__title">{{ section.settings.title }}</h1>

  {% for block in section.blocks %}
    <p class="mi-hero__text">{{ block.settings.text }}</p>
  {% endfor %}

  {% if section.settings.cta_label != blank %}
    <a href="{{ section.settings.cta_link }}" class="mi-hero__cta">
      {{ section.settings.cta_label }}
    </a>
  {% endif %}
</section>

{% schema %}
{
  "name": "Hero",
  "tag": "section",
  "settings": [
    { "type": "text",        "id": "title",     "label": "Título",        "default": "Bienvenido a VELSEFY" },
    { "type": "color",       "id": "bg_color",  "label": "Fondo",         "default": "#f7c05a" },
    { "type": "text",        "id": "cta_label", "label": "Texto del CTA", "default": "Comprar" },
    { "type": "url",         "id": "cta_link",  "label": "Enlace del CTA" }
  ],
  "blocks": [
    {
      "type": "text",
      "name": "Texto",
      "settings": [ { "type": "textarea", "id": "text", "label": "Texto" } ]
    }
  ],
  "presets": [ { "name": "Hero", "blocks": [ { "type": "text" } ] } ]
}
{% endschema %}
3

Regístrala en una plantilla de página

templates/index.jsonjson
{
  "sections": {
    "main": { "type": "hero", "settings": { "title": "Hola" } }
  },
  "order": ["main"]
}
4

Valida localmente (sin token)

Terminalbash
velsefy theme validate --dir ./mi-tema

# → "Versión del tema (theme_info): 1.0.0"
# → "Tema válido."
5

Sube a tu tienda y publica

Terminalbash
# Sube los assets a TU instalación
velsefy theme push --install <INSTALL_ID> --dir ./mi-tema

# (Opcional) Publica al catálogo con credenciales de plataforma
velsefy theme release --sku THEME-DEFAULT --changelog "v2: nuevo hero" --dir ./mi-tema

Si algo falla al publicar

Que la theme release devuelva 400 validation_failedindica un problema con el archivo señalado (balance Liquid, tipo de setting no soportado o path fuera de la whitelist). Corrígelo en local, pasa theme validate y vuelve a intentar.

11

Recursos

Materiales de apoyo para profundizar: la referencia de Liquid, el repositorio de la CLI y el esquema JSON que da autocompletado en VS Code.

Guía de Liquid

Consulta la referencia de etiquetas, filtros y operadores para escribir un markup líquido correcto:{% if %}, {% for %}, {% render %}, asset_url y el resto de la sintaxis.

Repositorio de la CLI

El código fuente de velsefy-cli. Útil para leer cómo se implementan validate, pull, push y release, y seguir los cambios de la herramienta.

Esquema JSON para VS Code

velsefy.settings_schema.json dentro de packages/theme-validate. Permite validar config/settings_schema.json en vivo y con autocompletado.

Referencia de comandos

Si dudas de un parámetro o de la salida de un comando, esta misma guía es el punto de partida: la sección de Comandos de la CLI describe cada subcomando y su efecto.

¿Por qué dice “tema no encontrado”?

Suele significar que el install_id no existe o que el token no tiene acceso a esa tienda. Verifica con velsefy theme list que el tema siga instalado, o que hayas descendido con theme pull desde esa misma instalación. Si el id es correcto pero el tema ya no está, vuelve a crear la instalación y descarga de nuevo.