HystoreWiki

2 min de lecturaVer en Markdown

Ejemplos listos

Recetas para copiar. Cada bloque muestra el archivo donde va y pasa la revisión de la tienda. Después de crear una sección, agrégala en Personalizar tema > Secciones de la página o en templates/<página>.json.

Un banner con título, texto y botón, todo editable en Personalizar tema.

sections/promo-banner.liquidLiquid
<section class="promo">
  <div class="promo-in">
    <p class="promo-tag">{{ section.settings.tag }}</p>
    <h2>{{ section.settings.title }}</h2>
    <p>{{ section.settings.text }}</p>
    {%- if section.settings.button_url != blank -%}
      <a class="promo-btn" href="{{ section.settings.button_url }}">{{ section.settings.button_label }}</a>
    {%- endif -%}
  </div>
</section>
{% schema %}
{
  "name": "Banner de promoción",
  "settings": [
    { "id": "tag", "type": "text", "label": "Etiqueta", "default": "Solo esta semana" },
    { "id": "title", "type": "text", "label": "Título", "default": "Black Friday: hasta 50% off" },
    { "id": "text", "type": "textarea", "label": "Texto", "default": "Kits, VIPs y cosméticos con descuento." },
    { "id": "button_label", "type": "text", "label": "Texto del botón", "default": "Ver ofertas" },
    { "id": "button_url", "type": "url", "label": "Enlace del botón", "default": "/loja" }
  ]
}
{% endschema %}
styles/promo-banner.cssCSS
.promo { padding: 48px 20px; background: linear-gradient(120deg, hsl(var(--primary)), #1d4ed8); color: #fff; }
.promo-in { max-width: 960px; margin: 0 auto; }
.promo-tag { display: inline-block; padding: 4px 10px; border-radius: 999px; background: rgba(255, 255, 255, .18); font-weight: 700; font-size: 13px; }
.promo h2 { margin: 12px 0 8px; font-size: clamp(28px, 4vw, 44px); }
.promo-btn { display: inline-block; margin-top: 12px; padding: 12px 22px; border-radius: 12px; background: #f5b544; color: #1c1305; font-weight: 700; text-decoration: none; }

Vitrina de una categoría

Los productos de una categoría, con precio, promoción y botón de comprar.

sections/category-showcase.liquidLiquid
{% load products, category: section.settings.category, limit: section.settings.count as items %}
<section class="showcase">
  <h2>{{ section.settings.title }}</h2>
  <div class="showcase-grid">
    {%- for p in items -%}
      <article class="showcase-card">
        <a href="{{ p.url }}">
          {%- if p.image -%}<img src="{{ p.image }}" alt="{{ p.name }}" loading="lazy">{%- endif -%}
          <h3>{{ p.name }}</h3>
        </a>
        <p class="showcase-price">
          {%- if p.on_sale -%}<s>{{ p.original_price | money }}</s> {% endif -%}
          <strong>{{ p.price | money }}</strong>
        </p>
        {%- if p.sold_out -%}
          <span class="showcase-off">{{ 'product.sold_out' | t }}</span>
        {%- else -%}
          <button type="button" data-hystore-add-to-cart="{{ p.id }}">{{ 'product.add' | t }}</button>
        {%- endif -%}
      </article>
    {%- else -%}
      <p>{{ 'showcase.empty' | t }}</p>
    {%- endfor -%}
  </div>
</section>
{% schema %}
{
  "name": "Vitrina de categoría",
  "settings": [
    { "id": "title", "type": "text", "label": "Título", "default": "Kits" },
    { "id": "category", "type": "text", "label": "Slug de la categoría", "default": "kits" },
    { "id": "count", "type": "range", "label": "Cantidad", "min": 2, "max": 24, "default": 8 }
  ]
}
{% endschema %}

El slug es el final de la dirección de la categoría en la tienda (/loja/survival/kits tiene el slug kits). Los textos product.add, product.sold_out y showcase.empty quedan en los archivos de idioma:

locales/es.jsonJSON
{
  "product": { "add": "Comprar", "sold_out": "Agotado" },
  "showcase": { "empty": "Todavía no hay productos aquí." }
}

Cuenta regresiva

La tienda completa los números sola, sin JavaScript en el tema.

sections/countdown.liquidLiquid
<section class="countdown" data-hystore-countdown="{{ section.settings.ends_at }}">
  <h2>{{ section.settings.title }}</h2>
  <div class="countdown-row">
    <span><b data-hystore-days>0</b> {{ 'time.days' | t }}</span>
    <span><b data-hystore-hours>0</b> {{ 'time.hours' | t }}</span>
    <span><b data-hystore-minutes>0</b> {{ 'time.minutes' | t }}</span>
    <span><b data-hystore-seconds>0</b> {{ 'time.seconds' | t }}</span>
  </div>
</section>
{% schema %}
{
  "name": "Cuenta regresiva",
  "settings": [
    { "id": "title", "type": "text", "label": "Título", "default": "La nueva temporada empieza en" },
    { "id": "ends_at", "type": "text", "label": "Fecha y hora (UTC)", "default": "2026-12-24T23:59:00Z" }
  ]
}
{% endschema %}

IP del servidor y jugadores en línea

sections/server-bar.liquidLiquid
{% load server_status as status %}
<section class="server-bar">
  <button type="button" class="server-ip" data-hystore-copy="{{ store.ip }}">{{ store.ip }}</button>
  {%- if status and status.online -%}
    <span class="server-on">{{ status.players_online }}/{{ status.players_max }} {{ 'server.online' | t }}</span>
  {%- else -%}
    <span class="server-off">{{ 'server.offline' | t }}</span>
  {%- endif -%}
  <hystore-online-players></hystore-online-players>
</section>
{% schema %}
{ "name": "Barra del servidor", "settings": [] }
{% endschema %}

Hacer clic en la IP copia la dirección. La tienda completa <hystore-online-players> con los jugadores en línea.

Mejores compradores del mes

sections/top-buyers.liquidLiquid
{% load ranking, period: 'month', limit: 5 as top %}
<section class="top-buyers">
  <h2>{{ section.settings.title }}</h2>
  <ol>
    {%- for row in top -%}
      <li>
        <img src="{{ row.nick | skin_url: 48 }}" alt="" width="48" height="48">
        <span>{{ row.position }}. {{ row.nick }}</span>
        <b>{{ row.total_spent | money }}</b>
      </li>
    {%- endfor -%}
  </ol>
</section>
{% schema %}
{
  "name": "Mejores compradores",
  "settings": [{ "id": "title", "type": "text", "label": "Título", "default": "Top del mes" }]
}
{% endschema %}

Preguntas frecuentes

Un acordeón con preguntas que el dueño de la tienda agrega como bloques.

sections/faq.liquidLiquid
<section class="faq" data-hystore-accordion="single">
  <h2>{{ section.settings.title }}</h2>
  {%- for block in section.blocks -%}
    <div class="faq-item" data-hystore-accordion-item>
      <button type="button" data-hystore-accordion-toggle>{{ block.settings.question }}</button>
      <div class="faq-answer" data-hystore-accordion-panel>{{ block.settings.answer }}</div>
    </div>
  {%- endfor -%}
</section>
{% schema %}
{
  "name": "Preguntas frecuentes",
  "settings": [{ "id": "title", "type": "text", "label": "Título", "default": "Dudas" }],
  "blocks": [
    {
      "type": "question",
      "name": "Pregunta",
      "settings": [
        { "id": "question", "type": "text", "label": "Pregunta" },
        { "id": "answer", "type": "textarea", "label": "Respuesta" }
      ]
    }
  ]
}
{% endschema %}

Colores y opciones del tema

La configuración general queda en theme.json y se vuelve campos en Personalizar tema:

theme.jsonJSON
{
  "name": "Mi tema",
  "version": "1.0.0",
  "color_modes": ["dark", "light"],
  "settings": [
    { "id": "accent", "type": "color", "label": "Color de acento", "default": "#f5b544" },
    { "id": "radius", "type": "range", "label": "Redondeo", "min": 0, "max": 28, "default": 14 }
  ]
}

Los colores y números se vuelven variables CSS en la raíz del tema:

styles/theme.cssCSS
.button { background: var(--theme-accent); border-radius: calc(var(--theme-radius) * 1px); }
html:not(.dark) .card { background: #fff; color: #0b1526; }
html.dark .card { background: #0d1524; color: #e8eef8; }

Y cualquier configuración general aparece en Liquid como {{ settings.accent }}.

Cambiar modo de color e idioma

components/header-tools.liquidLiquid
<div class="header-tools">
  <button type="button" data-hystore-color-mode="toggle">{{ 'header.theme' | t }}</button>
  <button type="button" data-hystore-language="pt">PT</button>
  <button type="button" data-hystore-language="en">EN</button>
  <button type="button" data-hystore-language="es">ES</button>
  <button type="button" data-hystore-open="cart">{{ 'header.cart' | t }} (<span data-hystore-cart-count>0</span>)</button>
  <hystore-account></hystore-account>
</div>

Úsalo en el layout con {% render 'header-tools' %}.

Más

  • La guía del tema lista todos los datos, filtros, bloques listos y piezas interactivas.
  • Para JavaScript (ruleta, quiz, calculadora), mira Apps aisladas.
  • Los temas Base, Aurora, Celeste y Prisma son excelentes para estudiar: empieza uno en el panel y abre sus archivos en el editor.