Dokumentasi theme
Ringkasan
Theme Fauqa One Click memakai Liquid dan meniru Shopify Online Store 2.0: template JSON berisi daftar section, setiap section membawa {% schema %} sendiri, dan section group untuk header/footer. Developer theme Shopify bisa langsung bekerja; bedanya ada pada objek e-commerce yang tidak tersedia (lihat Porting dari Shopify).
Theme bisa diedit langsung di browser (Theme → Edit code), atau diunduh sebagai .zip, diubah di komputer, lalu diunggah lagi. Setiap simpan dan unggah divalidasi; file yang gagal validasi tidak pernah menggantikan file yang sedang tayang.
Struktur folder
layout/
theme.liquid wajib. Kerangka HTML
password.liquid opsional. Halaman password / segera hadir
templates/ JSON: daftar & urutan section per tipe halaman
index.json wajib
page.json wajib
page.contact.json template alternatif (suffix "contact")
product.json collection.json list-collections.json
blog.json article.json search.json 404.json password.json
sections/
header-group.json section group
footer-group.json
hero.liquid HTML Liquid + {% schema %}
snippets/ {% render 'card-product', product: p %}
assets/ css, js, svg, gambar, font → {{ 'base.css' | asset_url }}
config/
settings_schema.json wajib. Definisi theme settings
settings_data.json nilai theme settings + preset gaya
locales/
id.default.json en.json string untuk filter tBelum didukung: folder blocks/ (theme blocks) dan nested blocks. Block didefinisikan di schema section, seperti OS 2.0 awal.
Layout
layout/theme.liquid wajib memanggil {{ content_for_header }} di <head> (SEO, canonical, hreflang, data terstruktur, kode tambahan pemilik situs) dan {{ content_for_layout }} di tempat isi halaman. Badge {{ powered_by_link }} wajib tampil; bila theme tidak memanggilnya, badge disisipkan otomatis sebelum </body>.
<!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 }}</title>
<meta name="description" content="{{ page_description | escape }}">
{{ 'base.css' | asset_url | stylesheet_tag }}
{{ content_for_header }}
</head>
<body>
{% sections 'header-group' %}
<main id="main">{{ content_for_layout }}</main>
{% sections 'footer-group' %}
{{ powered_by_link }}
</body>
</html>Template JSON
Template berisi section beserta nilai setting-nya. Urutan tampil mengikuti order; block mengikuti block_order. Section dengan "disabled": true tidak dirender. Template alternatif memakai suffix (page.contact.json) dan dipilih per halaman/produk di admin.
{
"sections": {
"hero": {
"type": "hero",
"settings": { "heading": "Solusi baja untuk industri", "height": "large" },
"blocks": {
"btn-1": { "type": "button", "settings": { "label": "Lihat produk", "link": "/collections/all" } }
},
"block_order": ["btn-1"]
},
"clients": { "type": "logo-list", "disabled": false, "settings": {} }
},
"order": ["hero", "clients"]
}Maksimal 25 section per template dan 50 block per section.
Section & schema
Pasang {{ section.fauqa_attributes }} di elemen terluar section dan {{ block.fauqa_attributes }} di setiap block, agar klik di pratinjau editor memilih section/block yang tepat. Alias shopify_attributes juga tersedia.
<section class="hero hero--{{ section.settings.height }}" {{ section.fauqa_attributes }}>
<h1>{{ section.settings.heading }}</h1>
{% for block in section.blocks %}
{% case block.type %}
{% when 'button' %}
<a href="{{ block.settings.link }}" class="btn" {{ block.fauqa_attributes }}>{{ block.settings.label }}</a>
{% endcase %}
{% endfor %}
</section>
{% schema %}
{
"name": "Hero",
"class": "section-hero",
"settings": [
{ "type": "text", "id": "heading", "label": "Judul", "default": "Judul" },
{ "type": "select", "id": "height", "label": "Tinggi", "default": "large",
"options": [{ "value": "small", "label": "Kecil" }, { "value": "large", "label": "Besar" }] }
],
"blocks": [
{ "type": "button", "name": "Tombol", "limit": 2,
"settings": [{ "type": "text", "id": "label", "label": "Teks" }, { "type": "url", "id": "link", "label": "Link" }] }
],
"max_blocks": 4,
"presets": [{ "name": "Hero", "blocks": [{ "type": "button" }] }],
"enabled_on": { "templates": ["index", "page"] }
}
{% endschema %}presets: section muncul di daftar “Tambah section” editor. Tanpa preset, section hanya bisa dipakai dari template JSON.limit(per tipe block),max_blocks,enabled_on/disabled_ondihormati editor.classditambahkan ke pembungkus<div id="fauqa-section-<id>" class="fauqa-section">;tagmengganti elemen pembungkusnya.- Section statis:
{% section 'header' %}, nilainya disettings_data.json → current.sections.header. Section group:{% sections 'header-group' %}membacasections/header-group.json.
Tipe setting
| Tipe | Keterangan |
|---|---|
text, textarea | Teks satu baris / beberapa baris |
richtext, inline_richtext | HTML terbatas dari editor teks; disanitasi |
html, liquid | Hanya owner/admin. liquid dirender sebagai Liquid |
number, range | range wajib min, max, step |
checkbox, select, radio | select/radio wajib options |
color, color_background, color_scheme | Warna, gradien, skema dari theme settings |
image_picker, video, video_url | Dari file manager; video_url YouTube/Vimeo |
url, page, product, product_list, collection, collection_list, blog, article, link_list | Link dan referensi konten |
font_picker | Google Fonts terkurasi |
header, paragraph | Penanda di panel editor, tanpa nilai |
Objek
| Objek | Isi |
|---|---|
site | name, url, logo, favicon, tagline, contact (email, phone, whatsapp, address), social, hours, locale |
settings | Theme settings dari settings_data.json (preset aktif atau current) |
request | path, host, locale.iso_code, design_mode (true di editor), page |
localization | available_languages[] (iso_code, name, url, root_url), language |
routes | root_url, search_url, collections_url, all_products_collection_url |
linklists | linklists['main-menu'].links[] → title, url, current, child_active, links |
pages, collections, blogs | Bisa di-loop atau diakses per handle: collections['atap'] |
page | title, content, url, handle, template_suffix, seo |
product | title, summary, content, url, images, featured_image, specs[] (label, value), price_label, tags, downloads[], cta (type, label, url), related[] |
collection | title, description, url, image, products[], products_count |
blog / article | blog: title, url, articles[]; article: title, excerpt, content, image, author, tags, published_at, url |
search | performed, terms, results[] (object_type, title, url, excerpt, image), results_count |
section / block | id, type, settings, blocks, index, fauqa_attributes |
template | name, suffix |
page_title, page_description, page_image, canonical_url | Untuk tag meta |
Harga hanya tampilan (price_label, mis. “Mulai Rp 85.000”); tidak ada keranjang atau checkout.
Tag & filter
Tag: semua tag standar LiquidJS (if, for, case, assign, capture, render, raw, liquid, echo, …) ditambah section, sections, schema, form, paginate, style, stylesheet, javascript.
| Filter | Contoh |
|---|---|
asset_url | {{ 'base.css' | asset_url | stylesheet_tag }}, {{ 'theme.js' | asset_url | script_tag }} |
image_url, image_tag | {{ product.featured_image | image_url: width: 800 | image_tag: loading: 'lazy' }} → WebP + srcset |
file_url | {{ 'hero.jpg' | file_url }}: file dari file manager situs |
t | {{ 'contact.send' | t }}: string dari locales/<bahasa>.json |
date | {{ article.published_at | date: '%d %B %Y' }}: nama bulan sesuai bahasa |
money | {{ product.price_label | money }}: label harga apa adanya |
link_to, handleize | {{ 'Tentang' | link_to: '/pages/tentang-kami' }} |
default_pagination | {{ paginate | default_pagination }} |
placeholder_svg_tag | {{ 'image' | placeholder_svg_tag: 'placeholder' }} |
{% paginate collection.products by 12 %}
{% for product in collection.products %}
{% render 'card-product', product: product %}
{% endfor %}
{{ paginate | default_pagination }}
{% endpaginate %}Form
{% form 'contact' %} membuat <form method="post" action="/contact"> lengkap dengan field tersembunyi, honeypot anti-spam, dan Cloudflare Turnstile bila aktif. Tipe: contact, inquiry (minta penawaran; berikan produk sebagai argumen), newsletter. Kiriman masuk ke inbox Form di admin dan email pemilik situs.
{% form 'inquiry', product %}
{% if form.posted_successfully %}
<p role="status">{{ 'contact.success' | t }}</p>
{% else %}
{% if form.errors.size > 0 %}<p role="alert">{{ form.errors | join: ' ' }}</p>{% endif %}
<input type="text" name="contact[name]" required>
<input type="email" name="contact[email]" required>
<input type="tel" name="contact[phone]">
<textarea name="contact[body]" required></textarea>
<button type="submit">{{ 'contact.send' | t }}</button>
{% endif %}
{% endform %}Jangan membuat field password atau data kartu: validator memberi peringatan karena form seperti itu di situs company bisa dianggap phishing.
Bahasa
Situs bisa punya dua bahasa (Indonesia dan English). Bahasa kedua tampil di /en/… (atau /id/…). String theme ada di locales/id.default.json dan locales/en.json, dipanggil dengan filter t; kunci yang tidak ada di bahasa aktif diambil dari bahasa utama situs. Konten dan teks section diterjemahkan pemilik situs di menu Terjemahan, jadi theme tidak perlu menangani apa pun: section.settings sudah berisi teks bahasa aktif. Link internal di menu otomatis diberi awalan bahasa; untuk link lain pakai routes.root_url.
{% for language in localization.available_languages %}
<a href="{{ language.url }}" {% if language.iso_code == request.locale.iso_code %}aria-current="true"{% endif %}>
{{ language.iso_code | upcase }}
</a>
{% endfor %}Theme editor
Di editor, situs dirender dengan request.design_mode = true dan perubahan setting dirender ulang per section (Section Rendering API). JavaScript section yang memasang event listener atau slider harus mendengarkan event berikut agar tetap bekerja setelah dirender ulang:
| Event | Kapan |
|---|---|
fauqa:section:load | Section baru dirender ulang / ditambahkan |
fauqa:section:unload | Section akan diganti / dihapus |
fauqa:section:select, fauqa:section:deselect | Section dipilih di panel editor |
fauqa:block:select, fauqa:block:deselect | Block dipilih (mis. buka slide yang sesuai) |
document.addEventListener('fauqa:section:load', (e) => initSlider(e.target));
document.addEventListener('fauqa:block:select', (e) => goToSlide(e.target));event.detail berisi sectionId dan, untuk block, blockId. Kode tambahan <head> pemilik situs tidak dijalankan di editor.
Validasi & batas
- ZIP maksimal 50 MB dan 1.000 file; hanya folder di atas. Folder pembungkus (mis.
my-theme/) dibuang otomatis. - Wajib ada
layout/theme.liquid,templates/index.json,templates/page.json,config/settings_schema.json. - Setiap
.liquiddi-parse, setiap JSON dan{% schema %}dicek; laporan error menyebut file dan baris. Section yang dipakai template harus ada. - Nama file: huruf kecil, angka,
_,-. Ekstensi aset: css, js, json, svg, png, jpg, webp, gif, ico, woff, woff2, ttf, otf (maks. 5 MB per aset). - Render dibatasi ±500 ms per template dan tanpa akses jaringan atau file: template hanya membaca objek di atas. Section yang error tidak menjatuhkan halaman (di editor, pesan error tampil di tempatnya).
- JavaScript theme berjalan di domain situs, terpisah dari admin.
Porting dari Shopify
Struktur folder, template JSON, schema, section group, render, t, asset_url, dan form sama. Yang perlu diubah:
- Hapus
cart,customer,checkout,variant, dan formproduct/cart. Ganti tombol beli denganproduct.cta(WhatsApp, form penawaran, atau link). product.pricebukan angka; pakaiproduct.price_label.shopmenjadisite;shop.name→site.name.- Theme blocks (
blocks/) dan app blocks belum didukung.
Cara tercepat memulai: buka Theme → Edit code → Unduh .zip dari salah satu theme bawaan, lalu ubah dari sana.