1 Mimari genel bakış
Frotan çok kiracılı bir SaaS'tır: tek kod tabanı, kiracı başına ayrı veritabanı. İstek gelen host'tan (subdomain ya da müşteri özel alan adı) kiracı çözülür; aktif temanın dosyaları basılır.
- Tema =
temalar/{ad}/klasörü. İçinde en azindex.php(sayfa iskeleti) vetema.json(üst-veri) olur. Klasörü eklemek yeterli — DB kaydı gerekmez, tüm mağazalarda otomatik listelenir. - Vitrin modülleri =
temalar/{ad}/modul/{sayfa}.php(anasayfa, urunler, urun, kategori, sepet, iletisim…). Router hangi modülü basacağını çözer. - Görünüm token'ları = renk/font, CSS değişkenleriyle (
var(--renk-*)). Mağaza sahibi panelden değiştirir; tema gömme hex kullanmaz. - Komponentler (bileşenler) =
bilesenler/{slot}/{varyant}.php. Temadan bağımsız, token tabanlı parçalar (hero, navbar, ürün kartı…). Mağaza sahibi varyant seçer. - Stüdyo = mağaza sahibinin panelden renk/font/komponent seçtiği ve (v2) blok-tabanlı sayfa kurduğu görsel editör.
2 Hızlı başlangıç — 5 dakikada yeni tema
En küçük çalışır tema iki dosyadır. temalar/ altında yeni klasör aç (ad: küçük harf+rakam, örn. tema9):
temalar/tema9/
├─ tema.json # üst-veri (ad, destekler, varsayılanlar)
└─ index.php # sayfa iskeleti (head + header + <main> + footer)tema.json (statik, en basit):
{
"ad": "Tema 9 - Örnek",
"aciklama": "Örnek başlangıç teması",
"versiyon": "1.0.0",
"yazar": "adiniz"
}index.php (iskelet — modülü <main> içine basar):
<!doctype html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo e($site_title ?? '') . e($ayarlar['title'] ?? 'Mağaza'); ?></title>
<?php require_once 'config/gorunum.php'; echo gorunumRootCss($db); // token + font (güncellenebilir tema) ?>
<link rel="stylesheet" href="<?php echo $dizin_limit . TEMA_YOLU; ?>assets/tailwind.css">
</head>
<body>
<header><!-- navbar: logo, menü, arama, sepet --></header>
<main>
<?php require $modFilePath; // router seçtiği modül ?>
</main>
<footer><!-- iletişim, bağlantılar, telif --></footer>
</body>
</html>Kaydet → bu tema tüm mağazaların Stüdyo → Temalar listesinde anında görünür. Mağaza sahibi seçip Yayınla'ya basınca aktif olur.
Önizleme görseli için temalar/images/tema9.png koy (16:10 önerilir).
3 Önerilen dosya yapısı
temalar/tema9/
├─ tema.json # üst-veri + destek bildirimi
├─ index.php # <head> + header + <main>(modül) + footer
├─ modul/ # sayfa gövdeleri (router '{mod}.php' arar)
│ ├─ anasayfa.php
│ ├─ urunler.php # ürün listesi
│ ├─ urun.php # ürün detay (sepete ekle)
│ ├─ kategori.php
│ ├─ sepet.php
│ └─ iletisim.php
├─ layout/ # ortak parçalar (header, footer, head, product-card…)
│ ├─ head.php
│ ├─ header.php
│ ├─ footer.php
│ └─ product-card.php
└─ assets/
├─ tailwind.css # DERLENMİŞ (derleme/ ile üretilir — KVKK: CDN yok)
└─ theme.js # slider, sepet, drawer vb. (opsiyonel)Router, istenen sayfaya göre TEMA_YOLU . "modul/{mod}.php" dosyasını <main> içinde require eder. Modül yoksa 404.php.
Modül dosyalarında hazır değişkenler bulunur: $db (kiracı DB), $ayarlar (mağaza ayarları), $dizin_limit (base URL), $kategoriler, $kampanyalar, $ikonlar vb.
4 tema.json sözleşmesi
Temanın kimliği ve neleri desteklediği burada bildirilir. Tüm alanlar:
| Alan | Tip | Ne işe yarar |
|---|---|---|
ad | metin | Stüdyoda görünen tema adı |
aciklama | metin | Kısa tanıtım |
versiyon, yazar | metin | Sürüm / geliştirici |
onizleme | metin | Önizleme görseli yolu (yoksa temalar/images/{ad}.png) |
sira | sayı | Listede sıralama (küçük önce) |
gorunum | dizi | Hangi görsel özelleştirmeyi destekler: ["renk","font","ozel_css"]. Boş/yoksa → renk/font kapalı (statik). |
bilesen | dizi | Hangi slotlarda parça değişimi var: ["navbar","hero","urun-kart",...]. Modüllerde bu slotlar için bilesenDevral kancası olmalı. |
varsayilan | nesne | Token varsayılanları: renk_birincil, renk_koyu, renk_zemin, renk_metin, font_baslik, font_metin. |
ozel | dizi | Varsa tema "müşteriye özel"dir (bespoke): yalnız sahibine görünür. İçi subdomain listesi (panelden de atanır). Bkz §8. |
Güncellenebilir bir temanın tam örneği:
{
"ad": "Tema 9 - Modern",
"aciklama": "Tailwind tabanlı, renk/font/parça özelleştirmeli modern tema",
"versiyon": "1.0.0",
"yazar": "adiniz",
"onizleme": "assets/images/onizleme.jpg",
"gorunum": ["renk", "font", "ozel_css"],
"bilesen": ["navbar", "hero", "urun-kart", "footer", "duyuru-bandi",
"kategori-vitrin", "yorumlar", "bulten", "guvence"],
"varsayilan": {
"renk_birincil": "#2f6bd8",
"renk_koyu": "#0e1b3c",
"renk_zemin": "#f5f7fb",
"renk_metin": "#1f2937",
"font_baslik": "Montserrat",
"font_metin": "Inter"
}
}bilesen dolu VEYA gorunum içinde renk/font var. Aksi halde statik listelenir.5 Görünüm token'ları (renk & font)
Mağaza sahibi panelden marka rengi / yazı tipi seçer. Bu, kiracı başına ayrı bir CSS derlemesi GEREKTİRMEZ: tek bir
:root bloğu basılır, tema renkleri hep CSS değişkeninden okur. Böylece özelleştirme = 1 küçük <style>.
Temanın <head>'inde
Güncellenebilir tema, head'inde gorunumRootCss($db) çağırır — bu, Google Fonts linkini + :root token'larını + mağazanın özel CSS'ini basar:
<?php require_once 'config/gorunum.php'; echo gorunumRootCss($db); ?>Üretilen token'lar (tema bunları kullanır):
| Değişken | Anlam |
|---|---|
--renk-birincil / --renk-birincil-koyu | Marka rengi + hover/koyu türevi (otomatik) |
--renk-koyu | Kontrast blok/şerit zemini |
--renk-zemin / --renk-zemin-sicak / --renk-panel | Sayfa zemini + türevleri |
--renk-metin | Gövde metni |
--font-baslik / --font-metin | Başlık / metin yazı tipi |
Tema tarafında kullanım
Tailwind config'inde renkler bu değişkenlere bağlanır; HTML'de utility sınıf kullanırsın (gömme hex yok):
// derleme/tailwind.tema9.config.js
colors: {
brand: { DEFAULT: 'var(--renk-birincil)', dark: 'var(--renk-birincil-koyu)' },
navy: 'var(--renk-koyu)',
cream: { DEFAULT: 'var(--renk-zemin)', warm: 'var(--renk-zemin-sicak)' },
ink: 'var(--renk-metin)'
},
fontFamily: { sans: ['var(--font-metin)','sans-serif'], serif: ['var(--font-baslik)','serif'] }<button class="bg-brand text-white hover:bg-brand-dark">Sepete Ekle</button>
<!-- ya da doğrudan: -->
<h2 style="color:var(--renk-koyu);font-family:var(--font-baslik),serif">Başlık</h2>cron/fontlari-yerellestir.php). gorunumRootCss yerel kopya varsa Google'a hiç istek atmaz.6 Komponent sistemi (bileşen)
Bir komponent (parça) = bilesenler/{slot}/{varyant}.php. Temadan bağımsızdır; yalnız Tailwind utility + görünüm token'larıyla yazılır.
Veri sözleşmesini dosya başındaki yorum bildirir. Mağaza sahibi her slot için varyant seçer (gorunum tablosunda bilesen_{slot}).
Üç fonksiyon
| Fonksiyon | Ne yapar |
|---|---|
bilesen($slot, $veri, $varyant) | bilesenler/{slot}/{varyant}.php'yi $veri açılmış halde basar. |
bilesenVaryant($slot) | Mağazanın o slot için seçtiği varyantı döner ('tema' = temanın kendi parçası). |
bilesenDevral($slot, $veri) | Tema parçasının en üstünde çağrılır: seçim bir varyantsa onu basıp true döner (tema kendi çıktısını atlar); 'tema' ise false. |
Tema modülünde devralma kancası
Temanın kendi parçası, en üstte devralmayı dener. Mağaza farklı varyant seçmişse o basılır; "Temanın Kendisi" seçiliyse aşağıdaki özgün tasarım çalışır:
<?php
require_once 'bilesenler/bilesen.php';
// $heroVeri: komponentin beklediği veri sözleşmesi
if (!bilesenDevral('hero', $heroVeri)) {
// seçim 'tema' → temanın kendi hero'su:
?>
<section class="bg-cream"> ... temanın özgün hero'su ... </section>
<?php
}Mevcut slotlar ve varyantları config/gorunum.php → gorunumBilesenMeta()'da tanımlı: duyuru-bandi, hero, navbar, urun-kart, footer, kategori-vitrin, yorumlar, bulten, guvence. Her birinin diskteki varyantları bilesenler/{slot}/ altında.
7 Bir komponent nasıl tasarlanır
Örnek: hero slotuna "bolunmus" varyantı ekleyelim (solda metin, sağda görsel).
1) Varyant dosyası
İlk satırda veri sözleşmesini yorumla bildir. Yalnız token + Tailwind kullan. Kök elemana data-bilesen="slot/varyant" koy (Stüdyo önizlemesi bunu bulur):
<?php
/**
* Hero — "bolunmus": solda başlık+açıklama+CTA, sağda görsel.
* Veri sözleşmesi: $site_adi, $aciklama, $slaytlar[] (resim,baslik,link), $dizin_limit.
*/
if (!isset($site_adi)) return;
$ilk = $slaytlar[0] ?? null;
?>
<section class="bg-[var(--renk-zemin)]" data-bilesen="hero/bolunmus"
style="font-family:var(--font-metin),sans-serif">
<div class="mx-auto grid max-w-[1320px] items-center gap-8 px-6 py-16 md:grid-cols-2">
<div>
<h1 class="text-4xl font-semibold text-[var(--renk-metin)]"
style="font-family:var(--font-baslik),serif"><?php echo e($site_adi); ?></h1>
<p class="mt-4 text-[var(--renk-metin)]/75"><?php echo e($aciklama); ?></p>
<a href="<?php echo e($ilk['link'] ?? ($dizin_limit.'urunler')); ?>"
class="mt-7 inline-block rounded-full bg-[var(--renk-birincil)] px-7 py-3
font-semibold text-white hover:bg-[var(--renk-birincil-koyu)]">Alışverişe Başla</a>
</div>
<div class="overflow-hidden rounded-2xl">
<?php if (!empty($ilk['resim'])) { ?>
<img src="<?php echo htmlspecialchars($ilk['resim']); ?>" alt="" class="w-full object-cover">
<?php } else { ?>
<div class="aspect-[4/3]" style="background:linear-gradient(135deg,var(--renk-birincil),var(--renk-koyu))"></div>
<?php } ?>
</div>
</div>
</section>2) Stüdyoya tanıt (etiket + mini önizleme)
config/gorunum.php → gorunumBilesenMeta() içinde slot ve varyant etiketini ekle; gorunumMiniOnizleme()'ye küçük şematik çizimi ekle (Stüdyo kartında görünür).
3) Tailwind'i derle
Varyantta daha önce hiç kullanılmamış bir Tailwind sınıfı varsa CSS'i yeniden derle (config zaten bilesenler/** tarar):
npx -y tailwindcss@3.4.17 -c derleme/tailwind.tema9.config.js \
-i derleme/tailwind-giris.css -o temalar/tema9/assets/tailwind.css --minifybilesenDevral onu basar. Tema kodu değişmez.Veri gerektiren (ürün/kampanya çeken) komponentler ve bunları Stüdyo v2 bloklarına tanıtma için: §9 ve docs/STUDYO-V2.md.
8 Tema türleri
STATİK Statik tema
Sabit görünümlü, özelleştirmesiz tema. tema.json'da gorunum ve bilesen yoktur (ya da boş). Renk/font/parça seçimi kapalıdır; Stüdyo "Bu statik bir temadır" der.
- Ne zaman: piksel-tam, markaya özel, oynanmasını istemediğin tasarımlar.
- Nasıl: §2'deki iki dosya yeter. Gömme renk/font kullanabilirsin (token zorunlu değil).
gorunumRootCssçağırmana gerek yok.
{ "ad": "Butik Siyah", "aciklama": "Sabit siyah-beyaz butik", "versiyon": "1.0.0" }GÜNCELLENEBİLİR Güncellenebilir tema
Mağaza sahibinin renk/font seçtiği ve parça (komponent) değiştirebildiği tema. En çok tercih edileni budur.
Gerekenler (TEMA-KONTRATI):
tema.json'agorunum: ["renk","font","ozel_css"]ve desteklediğinbilesenslotlarını yaz;varsayilantoken'larını ver.head'deecho gorunumRootCss($db);çağır.- Tema boyunca gömme hex yerine
var(--renk-*)/var(--font-*)(ya da bunlara bağlı Tailwind sınıfları) kullan. - Değiştirilebilir olmasını istediğin her parçanın tema dosyasının en üstünde
bilesenDevral('{slot}', $veri)kancasını koy.
Böylece mağaza sahibi Stüdyo'dan renk/font ve her slot için varyant seçebilir; yayınlayınca tüm ziyaretçiler görür.
temalar/tema3/ (Artisan). Birebir örnek olarak incele.★ ÖZEL Müşteriye özel (bespoke) tema
Belirli bir mağazaya özel tasarlanan, yalnız o mağazanın sahibine görünen tema. Başka hiçbir mağaza listede göremez/seçemez.
İki yoldan biriyle "özel" işaretlenir:
- Kod ile:
tema.json'a"ozel"anahtarını ekle. Varlığı yeter (boş dizi bile) — sahipleri subdomain olarak yazılır:
{
"ad": "Acme'ye Özel",
"gorunum": ["renk", "font"],
"bilesen": ["navbar", "hero", "urun-kart", "footer"],
"ozel": ["acme"] // yalnız acme.frotan.com.tr görür/seçebilir
}- Panelden: Süper-admin, Kiracılar / Müşteriler sekmesinden bir temayı bir mağazaya atar (
frotan_ana.ozel_temalar). tema.json'a dokunmadan da özel yapılabilir; ikisi birleşir.
- "ozel" anahtarı olmayan tema herkese açıktır — asla gizlenmez.
- "ozel" olan ama hiç sahibi atanmamış tema kimseye görünmez (yanlışlıkla sızmaz).
- Özel tema, güncellenebilir de olabilir (içinde
gorunum/bilesen) — sahibi yine renk/parça değiştirir.
İlgili fonksiyonlar: gorunumTemaOzelMi(), gorunumTemaOzelSahipler(), gorunumKuruluTemalar() (özel temalar listelemede sahibi dışındakilere gizlenir).
9 Stüdyo v2 — blok-tabanlı sayfa oluşturucu
Stüdyo v2'de bir sayfa = sıralı blok listesi. Mağaza sahibi blok ekler/çıkarır/sürükler/sıralar; her blok bir komponenttir. Yeni bir komponenti bloklara tanıtmak editör koduna dokunmadan 3 adımdır:
bilesenler/{tur}/{varyant}.phpdosyası (token tabanlı — §7 gibi).config/komponent-kayit.php→komponentDefteri()'ye kayıt + ayar şeması (editör sağ panelini otomatik çizer).- Tailwind'i yeniden derle.
'duyuru-kutu' => [
'ad' => 'Duyuru Kutusu', 'kategori' => 'icerik', 'aile' => 'icerik',
'ikon' => '<rect x="3" y="5" width="18" height="14" rx="2"/>',
'aciklama' => 'Vurgulu bilgi kutusu.',
'varyantlar' => [], // çok varyantlıysa ['kutulu','sade']
'ayarlar' => [
'baslik' => ['tur'=>'metin', 'etiket'=>'Başlık', 'vars'=>''],
'metin' => ['tur'=>'metin-alan', 'etiket'=>'Metin', 'vars'=>''],
],
],Ayar alan türleri: metin, metin-alan, sayi, secim, anahtar, renk, gorsel, baglanti, liste, urun-kaynagi. Fonksiyonel sayfalarda (ürün listesi/detay) işlevsel çekirdek temada kalır; bloklar çevresine eklenir ("çekirdek sabit + çevresi serbest").
docs/STUDYO-V2.md — veri modeli (sayfa_duzen), sayfaBas() renderer, veri komponentleri, şablonlar.10 Tailwind — yerel derleme (KVKK)
Frotan ziyaretçi IP'sini üçüncü tarafa sızdırmaz: cdn.tailwindcss.com kullanılmaz, CSS yerel derlenir. Her tema için bir config:
// derleme/tailwind.tema9.config.js
module.exports = {
content: ['./temalar/tema9/**/*.php', './temalar/tema9/assets/*.js', './bilesenler/**/*.php'],
theme: { extend: {
colors: { brand: { DEFAULT:'var(--renk-birincil)', dark:'var(--renk-birincil-koyu)' },
navy:'var(--renk-koyu)', cream:{ DEFAULT:'var(--renk-zemin)' }, ink:'var(--renk-metin)' },
fontFamily: { sans:['var(--font-metin)','sans-serif'], serif:['var(--font-baslik)','serif'] }
} }
};npx -y tailwindcss@3.4.17 -c derleme/tailwind.tema9.config.js \
-i derleme/tailwind-giris.css -o temalar/tema9/assets/tailwind.css --minifycontent hem temayı hem bilesenler/**'i tarar → komponent sınıfları da derlemeye girer. Yeni utility sınıfı eklediğinde yeniden derle.
11 Teslim kontrol listesi
- ✓
temalar/{ad}/klasörü:index.php+tema.jsonvar. - ✓ Önizleme görseli (
temalar/images/{ad}.png, 16:10). - ✓ Güncellenebilir ise:
head'degorunumRootCss($db), token kullanımı,bilesenDevralkancaları,tema.json'dagorunum+bilesen+varsayilan. - ✓ Tailwind derlenmiş (
assets/tailwind.css), CDN yok. - ✓ Tüm sayfa modülleri (anasayfa, urunler, urun, kategori, sepet, iletisim) + 404.
- ✓ Mobil uyumlu; görseller
loading="lazy". - ✓ Test: farklı renk/font + farklı varyant seçildiğinde bozulmuyor (Stüdyo önizleme).
docs/TEMA-KONTRATI.md, docs/EKLEME-REHBERI.md, docs/STUDYO-V2.md ve örnek tema temalar/tema3/.Sorular için: info@frotan.com.tr