# Özel Kart Oluşturma

Kendi kartınızı tanımlayın
Kaynak: https://selwise.com/docs/product-cards/creating

Tasarımcının veremediği bir düzen gerekiyorsa kartın HTML'ini, CSS'ini ve (hesabınızda varsa) JavaScript'ini kendiniz yazabilirsiniz. En sık sebep, mağazanızdaki mevcut kart HTML'ini birebir yakalamaktır: sitenizin kart HTML'ini kopyalayıp yer tutucuları yerleştirmek en hızlı yoldur.

## Panelde nerede

**Tasarım → Ürün Kartları** (Design → Product Cards) → kart → editör başlığındaki **Drawn by** (Kartı çizen) anahtarında **My own code** (Kendi kodum). Seçtiğiniz anda kod editörü açılır ve sağda **Live Preview** (Canlı Önizleme) görünür; yazdığınız her harf önizlemeye anında yansır. Editörün içinde dört alt sekme vardır: **HTML**, **CSS**, **JavaScript** (yalnızca kod düzenleme yetkisi olanda) ve **Slot bindings** (Alan bağlamaları). Sekmenin üstündeki **View Guide** (Rehberi Görüntüle) yer tutucuların ve düğme bağlama örneklerinin kısa kılavuzunu açar; **Load example** (Örneği yükle) mevcut HTML ve CSS'i bir örnekle değiştirir ve önce onay ister. Ürün alanlarının listesi HTML editörünün yanındaki **Token reference** panelindedir; tıklayınca imlecin olduğu yere eklenir.

> **Açık olan editör, yayınlanan karttır**
>
> **Drawn by** (Kartı çizen) anahtarı hem hangi editörün açık olduğunu hem de mağazada neyin çizildiğini belirler; ikisi ayrışamaz. **The designer** (Tasarımcı) seçiliyken kayıtlı HTML ve JavaScript'iniz silinmez ama çizilmez; anahtarın altında bunu söyleyen bir satır çıkar ve **My own code**'a dönünce kodunuz olduğu gibi gelir. **My own code** seçili ama HTML boşsa kart tasarımcıdaki haliyle çizilir. **CSS her iki modda da** uygulanır; tasarımcının altında kendi **Custom CSS** (Özel CSS) kutusu vardır.

## Kim yazabilir

Kodu kod düzenleme yetkisi olan rol (**Admin**) yazar. Yetkisi olmayan rolde **My own code** seçilemez (anahtarın altında nedeni yazar); kart zaten kendi kodunu kullanıyorsa editörde yalnızca **Slot bindings** görünür (başlık **Code & Bindings** olur). Kartlar için kaydetme yetkisi de Admin'dedir. JavaScript ayrıca satın alınan **Custom Card Code** modülüne bağlıdır: hesapta modül yoksa yeni ya da değiştirilmiş script kaydı API'de 402 verir ve panel sizi hesap yöneticinize yönlendirir; var olan bir script'li kartı yeniden adlandırmak gibi script'e dokunmayan bir kayıt hâlâ çalışır. HTML ve CSS için modül gerekmez. Seçili kanal bir uygulama kanalıysa kod alanının üstünde **This code does not run on an app channel** uyarısı çıkar: özel CSS ve JavaScript SDK'ya iletilir ama çalışmaz, çünkü uygulama yüzeyleri kendi bileşenleriyle çizer; kod web kanallarınızda etkin kalır (bkz. [Uygulama Kanalları](/docs/channels/app-channels)).

## Yer tutucular

HTML içinde ürün verisine yer tutucularla erişirsiniz. İki yazım da çalışır: `${title}` ve `{{title}}`.

```html
<div class="kart">
  <a href="${url}">
    <img src="${imageUrl}" alt="${name}" />
    <span class="marka">${brand}</span>
    <h4>${name}</h4>
  </a>
  <div class="fiyat">
    <span class="guncel">${formattedPrice}</span>
    <span class="eski">${formattedOldPrice}</span>
  </div>
  <button type="button" ${addToCartAttrs}>Sepete ekle</button>
</div>
```

Değerler HTML'e güvenli yerleştirilir: üründeki özel karakterler kaçırılır; besleme verisi sayfanıza kod enjekte edemez. Değer yoksa boş metin basılır.

| Grup | Yer tutucular | Çıktı |
|---|---|---|
| Kimlik | `id`, `productId`, `itemCode`, `sku` | Metin. `itemCode` boşsa `id` kullanılır |
| Metin | `name`, `title`, `description`, `shortDescription`, `shortDesc` | Metin |
| Görsel ve bağlantı | `image`, `imageUrl`, `url`, `link` | Adres |
| Fiyat | `price`, `oldPrice`, `originalPrice` | Ham sayı, para birimi yok: `899.9` |
| Biçimli fiyat | `formattedPrice`, `formattedOldPrice` | Para birimiyle biçimli; biçim ziyaretçinin tarayıcı diline göre |
| İndirim | `discountRate`, `discount` | Yüzde sayısı: `25` (işaret ve `%` yok) |
| Sınıflandırma | `brand`, `category`, `categories` | Metin |
| Stok | `stock` | Adet; bilinmiyorsa boş |
| Değerlendirme | `rating`, `reviewCount` | Sayı; yoksa boş |
| İşaretler | `inStock`, `isSale`, `isNew`, `isBestseller` | `true` ya da `false` |
| Bağlam | `widgetId`, `source` | Kartı çizen öneri ya da arama yüzeyinin kimliği; `recommendation`, `search` ya da `preview` |
| Eylem bağlayıcıları | `addToCartAttrs`, `reviewAttrs`, `quickViewAttrs`, `linkAttrs`, `actionAttrs`, `variantSelector` | HTML öznitelik parçası (aşağıda) |

`isSale` yalnızca liste fiyatı satış fiyatından büyükse `true` olur. `inStock` stok bilgisi yoksa `true` kabul edilir.

## Sepete ekleme ve diğer eylemler

Kartta sepete ekleme düğmesi istiyorsanız kendi `onclick` kodunuzu yazmayın; eylem bağlayıcısını **açılış etiketinin içine** koyun:

```html
<button type="button" ${addToCartAttrs}>Sepete ekle</button>
```

Bu, `data-selwise-action="add-to-cart"` ve ürünün `data-product-id` değerini üretir; sepet entegrasyonu bunlara bağlanır. Diğer bağlayıcılar: `reviewAttrs` (ürün sayfasına/yorumlara git), `quickViewAttrs` (hızlı bakış), `linkAttrs` (ürün sayfası), `actionAttrs` (kartın ayarlarındaki varsayılan eylem). `actionAttrs` kartın o anki etkin eylemini izler: kanalın sepet entegrasyonu yoksa sepete ekleme yerine ürün sayfasına gitmeye düşer. `variantSelector` beden/varyant seçicinin yerini belirler; kartın **Seçenek seçici** ayarı **Gösterme** iken ya da seçici sunmayan yüzeylerde boş kalır. Seçicinin kutucuk mu açılır liste mi olacağı da o ayardır. Sepet entegrasyonu: [Sepete Ekleme](/docs/recommendations/add-to-cart).

## İzin verilen HTML

Kart HTML'i mağazaya girmeden önce temizlenir. Kalanlar: yapı ve metin etiketleri, listeler, tablolar, `a`, `img`, `picture`, `video`, `audio`, `figure`, `button`, `label` ve satır içi `svg` şekilleri (simgeler için); `id`, `class`, **`style` özniteliği**, `href`, `src`, `data-` ve `aria-` öznitelikleri. Silinenler: `<script>`, `<style>`, `form`, `input`, `select`, `iframe` ve `onclick` gibi olay öznitelikleri. CSS'i `<style>` ile değil CSS alt sekmesine yazın.

## CSS

CSS alt sekmesindeki kurallar yalnızca bu karta sınırlanır, sayfanın kalanına ulaşamaz. Renkleri sabit yazmak yerine marka değişkenlerini okuyun:

```css
.kart {
  background: var(--selwise-surface, #fff);
  border: 1px solid var(--selwise-border, #e5e5e5);
  border-radius: var(--selwise-radius, 8px);
  font-family: var(--selwise-font, inherit);
}
.kart .guncel { color: var(--selwise-price, #111); }
.kart .eski   { color: var(--selwise-text-muted, #888); text-decoration: line-through; }
.kart .marka:empty { display: none; }
```

Değişken listesi: [Marka Teması](/docs/brand/theme). Kartı tasarımcıyla yaptıysanız CSS'in öğeleri nasıl hedeflediği için: [Kart Stili](/docs/product-cards/styling).

## JavaScript

**JavaScript** alt sekmesi:

1. **Enable Runtime JavaScript** (Runtime JavaScript'i Etkinleştir) kutusunu işaretleyin. İşaretli ama kod boşsa uyarı çıkar ve kayıt reddedilir.
2. Kodu yazın. Kod **kart başına bir kez** çalışır ve şunlar hazırdır: `product` (kartın ürün verisi, örneğin `product.title`), `container` (kartın elemanı) ve `widget` (`widgetId`, `source`). Sorgularınızı `container.querySelector` ile kartın içinde yapın, tüm sayfada değil.
3. **Execution Timing** (Çalıştırma Zamanı) seçin: **Immediate (with HTML)** (HTML ile birlikte), **After DOM Ready** (DOM hazır olduktan sonra) ya da **On Custom Event** (özel olayda). Özel olayı seçtiyseniz olay adı zorunludur (en fazla 100 karakter, varsayılan `selwise:product-card-refresh`) ve şöyle tetiklenir: `document.dispatchEvent(new CustomEvent('olay-adı'))`.

Kod kayıt öncesi derlenir (çalıştırılmaz); söz dizimi hatası kaydı reddeder. Satır içi `onclick` gibi öznitelikler temizlenir; davranışı `addEventListener` ile bağlayın. JavaScript yalnızca **My own code** modunda çalışır.

## Alan bağlamaları

**Slot bindings** (Alan bağlamaları), kendi yer tutucu adlarınızı bir ürün alanına bağlar. **Structured** (satır satır) ve **Raw JSON** görünümü vardır. Her bağlama dört şey taşıyabilir: `productField` (bağlanacak ürün alanı), `format` (`{value}` içeren bir şablon, örneğin `{value} TL`, ya da biçimli fiyat için `price`), `raw` (değeri HTML kaçırmadan bas; yalnızca güvendiğiniz değer için) ve `fallback` (alan boşsa basılacak metin).

```json
{
  "kampanya": { "productField": "brand", "format": "Marka: {value}", "fallback": "Marka yok" }
}
```

Bu bağlamadan sonra HTML'de `${kampanya}` yazabilirsiniz. Yer tutucu adı harfle ya da alt çizgiyle başlamalı, yalnızca harf, rakam, `_`, `:` ve `-` içerebilir; iki satır aynı adı kullanamaz. Bağlama, aynı ada sahip hazır bir yer tutucunun yerine geçer. Bağlanabilir alanlar: [Kart Alanları](/docs/product-cards/fields).

## Yapay zekâ ve şablon

HTML editörünün üstündeki **Generate with AI** düğmesi kartı yer tutucularla yazar ya da mevcut kodu düzenler; **AI Studio** modülü açık hesaplarda görünür. **Templates** düğmesi Kütüphane'den ürün kartı şablonu uygular. Bkz. [Yapay Zekâ ile Üretim](/docs/ai-studio/overview) ve [Kütüphane](/docs/library/overview).

## Ne zaman koda geçmeli

| Durum | Mod |
|---|---|
| Öğeleri, koşulları, animasyonları tasarımcıyla kurabiliyorum | **The designer** |
| Özel bir düzen (iç içe bindirmeler, sitenin kart yapısı) | **My own code** |
| Sitenizin mevcut ürün kartı HTML'ini birebir eşlemek | **My own code** |
| Yalnızca küçük bir stil farkı | Tasarımcı artı **CSS** alt sekmesi |
