Düzenleyici sözleşmesi

Temanın tasarımı serbest; Mağaza Düzenleyici ve MultiZeka ile nasıl konuştuğu değil. Bloğa nitelik, metne duzenle, hareketli parçada mk:select.

Temanı istediğin gibi tasarlayabilirsin. Satıcı ise her temada aynı düzenleyiciyi kullanır. Önizlemede bir bannera tıklayınca o banner seçilir, başlığa çift tıklayınca yazı yerinde değişir, slayt seçilince durur. MultiZeka da aynı alanları okuyup yazar. Bunun için temanın uyması gereken birkaç kural var.

Kurallar yüklemede denetlenir. Hata varsa tema yüklenmez; uyarı yüklemeyi durdurmaz. Yüklemeden önce kendin denetle:

npx @multikolay/tema dogrula

MCP sunucusundaki tema_dogrula aracı da aynı denetimi yapar.

1. Bloğa nitelik

Her bloğun kök ögesine {{ b.nitelik }} yaz. Düzenleyici tıklanan noktadaki en içteki işaretli ögeyi seçer: bannera tıklayan satıcı bölümü değil, o bannerı düzenler. Esc bir üst ögeye (bölüme) çıkar.

{%- for b in section.blocks -%}
  <a class="banner" href="{{ b.settings.url | default: '#' }}" {{ b.nitelik }}>…</a>
{%- endfor -%}

Döngü dışında tek bir blok çiziyorsan (ör. yalnız ilk slayt) onu da işaretle:

{%- assign ilk = section.blocks | first -%}
<div class="giris" {{ ilk.nitelik }}>…</div>

Bölümün kendi kök ögesini platform verir; bölüme nitelik yazma.

2. Metne duzenle

Sayfada görünen her text ve textarea ayarının ögesine | duzenle süzgecini yaz. Satıcı önizlemede yazıya çift tıklar, yazar, Enter'a basar; değer o ayara kaydedilir.

<h2 {{ section | duzenle: 'baslik' }}>{{ section.settings.baslik }}</h2>
{%- for b in section.blocks -%}
  <p {{ b | duzenle: 'metin' }}>{{ b.settings.metin }}</p>
{%- endfor -%}
  • Süzgeç bölüm için section, blok için döngüdeki blok değişkenini (b) ve ayarın kimliğini alır.
  • Önizlemede data-edit niteliği basar, canlı sitede boş döner. Canlı HTML değişmez, CSS'in etkilenmez.
  • Ögenin içinde yalnız o metin olsun. Yanında ikon ya da başka yazı varsa metni kendi <span>'ine al: <a href="…"><span {{ b | duzenle: 'dugme' }}>{{ b.settings.dugme }}</span> →</a>. Temanın CSS'i o ögedeki span'leri hedefliyorsa (.etiket > span { … }) yeni span de etkilenir; o zaman işareti dış ögeye koy ya da seçiciyi daralt. Boş süs ögeleri (ikon, nokta) yerinde düzenlemede yok sayılır.
  • Nitelik içindeki değerler (alt="{{ … }}"), default: ile gelen yedek değer ve meta_doldur ile ürün bilgisinden dolan kalıp yerinde düzenlenmez; bunlar için duzenle gerekmez.

3. Olaylar

Önizlemede düzenleyici sayfaya şu olayları gönderir. Slayt, akordeon, sekme gibi hareketli parçalar dinlemeli.

OlaydetailNe zaman
mk:select{ id }: seçilen bölüm ya da blok kimliği; null seçim kalktıSatıcı önizlemede ya da Katmanlar'da bir öge seçince
mk:bolum:yuklendi{ id }: yeniden çizilen bölümSatıcı bir ayarı değiştirince bölüm yeniden çizilir; ardından geçerli seçim yeniden mk:select olarak gelir

Olaylar window'a gönderilir. Kimlik, bloğun data-mk-blok niteliğindeki değerdir. Önizlemede kökte data-mk-tasarim="1" bulunur. Canlı sitede ne olay ne de bu nitelik vardır.

Kendiliğinden geçen bir parçan varsa (şemada otomatik ya da autoplay onay kutusu) tema.js mk:select'i dinlemek zorunda. Seçilen slayta geçmeli ve seçim sürdükçe durmalı; yoksa satıcı düzenlediği slaytı göremez.

bolumler/slayt.liquid
<section class="slayt" data-slayt data-otomatik="{{ section.settings.otomatik }}">
  {%- for b in section.blocks -%}
    <div class="slayt-kare{% if forloop.first %} is-aktif{% endif %}" {{ b.nitelik }}>
      <h2 {{ b | duzenle: 'baslik' }}>{{ b.settings.baslik }}</h2>
    </div>
  {%- endfor -%}
</section>

{% schema %}
{
  "name": "Slayt",
  "settings": [{ "type": "checkbox", "id": "otomatik", "label": "Kendiliğinden geçsin", "default": true }],
  "blocks": [{ "type": "kare", "name": "Slayt", "settings": [{ "type": "text", "id": "baslik", "label": "Başlık" }] }],
  "presets": [{ "name": "Slayt", "blocks": [{ "type": "kare" }, { "type": "kare" }] }]
}
{% endschema %}
varliklar/tema.js
function slayt(kok) {
  const kareler = [...kok.querySelectorAll(".slayt-kare")]
  let i = 0
  let zaman = null
  let sabit = false // düzenleyicide seçiliyken durur
  const git = (n) => {
    i = (n + kareler.length) % kareler.length
    kareler.forEach((k, j) => k.classList.toggle("is-aktif", j === i))
    sur()
  }
  const sur = () => {
    clearTimeout(zaman)
    if (kok.dataset.otomatik === "true" && !sabit) zaman = setTimeout(() => git(i + 1), 6000)
  }
  const secim = (e) => {
    // Bölüm yeniden çizildiyse eski kopya dinlemeyi bırakır.
    if (!kok.isConnected) return window.removeEventListener("mk:select", secim)
    const id = e.detail?.id
    const el = id ? document.querySelector(`[data-mk-blok="${CSS.escape(id)}"]`) : null
    const n = el ? kareler.findIndex((k) => k.contains(el)) : -1
    sabit = n >= 0
    if (n >= 0 && n !== i) git(n)
    else sur()
  }
  window.addEventListener("mk:select", secim)
  git(0)
}

const kurulu = new WeakSet()
const kur = () => document.querySelectorAll("[data-slayt]").forEach((k) => kurulu.has(k) || (kurulu.add(k), slayt(k)))
kur()
window.addEventListener("mk:bolum:yuklendi", kur)

4. Görsel

Görsel ayarını image_url ile bas: mağazanın görselleri istenen genişlikte, hızlı yüklenir.

<img src="{{ b.settings.gorsel | image_url: width: 1200 }}" alt="{{ b.settings.gorsel_alt }}">

Denetlenen kurallar

KuralDüzey
Bloğu olan bölümde blok işareti yok ({{ b.nitelik }})hata
Döngü dışında çizilen tek blok işaretsizhata
Görünen text/textarea ayarında | duzenle yokhata
Kendiliğinden geçen bölüm var, tema.js mk:select dinlemiyorhata
Görsel image_url olmadan basılıyoruyarı

Denetim bölümün {% render %} ile çağırdığı parçalara da bakar: blok kartını bir parçada çizebilirsin. Alt temada yalnız kendi dosyaların denetlenir.

Bu sayfada