Laravel uygulamanızda bir Shopify tarzı sayfa editörü istiyorsanız — sürükleyip bırakma bölümleri, canlı önizleme, çoklu tema desteği ve tamamen Blade görünümleriyle destekleniyor — işte tam olarak bunu inşa ettik.
coderstm/laravel-page-builder, Laravel 11 ve 12 için JSON tabanlı bir sayfa oluşturma sistemidir. Kullanıcılarınıza görsel bir editör sunarken geliştirici iş akışınızı tam olarak istediği gibi tutar: Blade dosyaları, PHP sınıfları ve sıfır sihir.
Problem
Problem
Çoğu Laravel sayfa oluşturucu iki tuzağa düşer:
- Çok fazla sihir — özel DSL’ler, opak işleme yolları veya belirli bir frontend yığınıyla sıkı bağlılık.
- Çok katı — hazır HTML yapıları, tasarım sisteminizden sapmaya başladığınız anda karşıtlık oluşturur.
Laravel’a özgü bir şey istedik: Render için Blade görünümleri, depolama için JSON ve altında temiz bir PHP mimarisi.
Nasıl Çalışır
Nasıl Çalışır
Bölümler ve Bloklar Sadece Blade Görünümleridir
Bölümler ve Bloklar Sadece Blade Görünümleridir
Bir bölüm, @schema() direktifi ile başlayan bir Blade dosyasıdır. Hepsi bu.
@schema([
'name' => 'Hero',
'settings' => [
['id' => 'title', 'type' => 'text', 'label' => 'Title', 'default' => 'Welcome'],
['id' => 'subtitle', 'type' => 'text', 'label' => 'Subtitle', 'default' => 'Build something great'],
['id' => 'bg_color', 'type' => 'color', 'label' => 'Background'],
],
])
editorAttributes() !!} style="background: {{ $section->settings->bg_color }}">
{{ $section->settings->subtitle }}
Bu dosyayı resources/views/sections/hero.blade.php dizinine yerleştirin ve bu bölüm editörde hemen kullanılabilir hale gelecektir. Kayıt, YAML yapılandırması veya artisan generate komutlarına ihtiyaç yoktur — kayıt otomatik olarak taranır.
Bloklar aynı deseni takip eder:
@schema([
'name' => 'Card',
'settings' => [
['id' => 'title', 'type' => 'text', 'label' => 'Title', 'default' => 'Card Title'],
['id' => 'image', 'type' => 'image', 'label' => 'Image'],
],
])
editorAttributes() !!}>
{{ $block->settings->title }}
Konteyner bölümleri @blocks($section) ile bloklar kabul eder:
editorAttributes() !!}>
@blocks($section)
Sayfalar JSON Olarak Depolanır
Sayfalar JSON Olarak Depolanır
Bir editör bir sayfayı kaydettiğinde, diske bir JSON dosyası yazılır:
{
"sections": {
"hero": {
"type": "hero",
"settings": {
"title": "Welcome to Our Store",
"bg_color": "#1a1a2e"
}
},
"features": {
"type": "feature-grid",
"settings": {},
"blocks": {
"card-1": {
"type": "card",
"settings": {
"title": "Fast"
}
},
"card-2": {
"type": "card",
"settings": {
"title": "Reliable"
}
}
},
"order": [ "card-1", "card-2" ]
}
},
"order": [ "hero", "features" ]
}
İçin veri tabanı tabloları yok. Diske JSON kaydetmek, aşağıdaki avantajları sağlar:
- Versiyon kontrol edilebilir sayfa içeriği
- Hızlı okuma, sorgu yükü olmadan
- Kolayca tohumlamak, içe aktarmak veya karşılaştırmak
İşleme Hattı
İşleme Hattı
Mimari, beş katmanlı bir bağımlılık akışını takip eder:
Schema → Registry → Components → Renderer → Services- Schema — Bölüm/blok yapısını tanımlayıcı değişmez
readonlydeğer nesneleri. - Registry — Blade dosyalarından şemaları keşfeden ve önbelleğe alan tekil tarayıcılar.
- Components — JSON + şemadan oluşturulan
SectionveBlockçalışma zamanı nesneleri. - Renderer — Tüm HTML çıktısı için tek giriş noktası; asla atlanmaz.
- Services — Yüksek seviyeli orkestratörler (
PageService,PageStorage,PageRenderer).
Bağımlılıklar yalnızca aşağıya doğru akar. Bir Renderer asla bir Service çağırmaz. Bir Schema asla bir Registry çağırmaz. Bu, kod tabanının izinin sürülmesini ve test edilmesini kolaylaştırır.
Görsel Editör
Görsel Editör
Editör, bir iframe canlı önizleme ile React SPA’dır. Değişiklikler önizleme ile anında senkronize olur — sayfa yenilemesi yok, çıktı görmek için manuel kaydetme yok.
Editör, kutudan çıkan özellikler sunar:
- Sürükle-bırak bölüm ve blok sıralama.
- Ayarlar paneli ile 21+ alan türü: metin, renk, görüntü, simge, zengin metin, seçim, anahtar, aralık kaydırıcı ve daha fazlası.
- Önizleme üzerinde doğrudan metin düzenleme.
- Medya kütüphanesi pluggable depolama arka uçları (yerel, S3, Cloudflare R2, DigitalOcean Spaces).
- SEO paneli — sayfa başlığı, açıklaması, anahtar kelimeler.
- Tema ayarları — kenar boşlukları, renkler, yazı tipleri gibi global CSS değişkenleri yan panelde düzenlenebilir.
Editör, tek bir yol üzerinden enjekte edilir ve yalnızca ?pb-editor=1 mevcut olduğunda etkinleşir. Üretimde, $section->editorAttributes() boş bir dize döner — sıfır yük.
JSON Şablonları — Shopify Tarzı Yedekler
JSON Şablonları — Shopify Tarzı Yedekler
Her sayfanın özel bir yerleşime ihtiyacı yoktur. Şablonlar, kendine ait JSON veya Blade görünümü olmayan sayfalar için varsayılan yapıları tanımlamanızı sağlar:
{
"layout": "page",
"wrapper": "main#page-main.container",
"sections": {
"hero": {
"type": "hero",
"settings": {
"title": "{{ $page->title }}"
}
},
"content": {
"type": "page-content"
}
},
"order": [ "hero", "content" ]
}
Bunu resources/views/templates/default.json dizinine ekleyin, $page->template="default" atayın ve bu şablonu kullanan her sayfa, ayarlar sayfa modelinden önceden doldurulmuş yapıyla aynı yapıda işlenir.
wrapper anahtarı, bir CSS seçicisini kabul eder: main#id.class[attr=value]. İşleyici, bunu otomatik olarak saran elementi oluşturur.
Çoklu Tema Desteği
Çoklu Tema Desteği
Paket, qirolab/laravel-themer ile entegre olur. Her tema:
- Kendi bölümlerini ve bloklarını
themes/{name}/views/sections/veblocks/dizininden kaydedebilir. - Şablonları gölgeleyerek uygulama şablonlarını geçersiz kılabilir:
templates/{name}.json. - CSS değişkenlerine (renkler, yazı tipleri, aralıklar) gidip gelen global ayarlar şemalarını tanımlayabilir.
Bölümler, @theme joker karakterini kullanarak herhangi bir tema bloğu kabul edebilir:
@schema([
'name' => 'Content Row',
'blocks' => [
['type' => '@theme'], // etkin temadan herhangi bir kayıtlı bloğu kabul eder
],
])
Temalar, değiştirmeden gölgelenebilir. Eğer bir tema hero.blade.php gönderiyorsa, bu, uygulamanın hero.blade.php dosyasının üzerinde öncelik taşır — uygulama üzerinde değişiklik gerektirmez.
Yeniden Kullanılabilir Blok Yuvalama
Yeniden Kullanılabilir Blok Yuvalama
Bloklar her derinliğe kadar iç içe geçebilir. Bir row bloğu, column bloklarını içerebilir, bu da card bloklarını içerebilir, bu da icon bloklarını içerebilir. İşleyici, ağacı yeniden geçerek düzenler ve editör her seviyede iç içe sürükle-bırak kulplarını render eder.
Bir bölüm şemasındaki blok referansları üç şekilde çalışır:
| Girdi | Çözüldü olarak |
|---|---|
['type' => 'row'] | Temalı blok — BlockRegistry üzerinden aranır |
['type' => '@theme'] | Joker karakter — her kayıtlı blok |
['type' => 'item', 'name' => 'Custom Item'] | Yerel tanım — olduğu gibi kullanılır |
Ayrım önemlidir: bir name anahtarı eklemek, referansı yerel tanıma değiştirir.
Sayfa Başına Yerleşim Bölgeleri
Sayfa Başına Yerleşim Bölgeleri
Sayfalar, ana sıralanabilir içeriğin dışına render edilen başlık ve alt bölümleri tanımlayabilir:
{
"header": {
"sections": {
"nav": {
"type": "navigation"
}
},
"order": [ "nav" ]
},
"sections": {
"hero": {
"type": "hero"
}
},
"order": [ "hero" ]
}
Blade yerleşiminde @sections('header') ile render edilir. Editörler, özel bir panelde bunları yapılandırır — ana sürükle-bırak listesinde görünmezler.
Yeni Bir Alan Türü Ekleme
Yeni Bir Alan Türü Ekleme
21 yerleşik tür çoğu ihtiyacı karşılar ancak özel bir tür eklemek, çekirdek motoru etkilemez. resources/js/components/settings/ altında bir React bileşeni oluşturun, bunu FieldRegistry.ts içinde kaydedin ve bu, herhangi bir bölümün @schema() tanımında kullanılabilir.
Kurulum
Kurulum
composer require coderstm/laravel-page-builder
php artisan pagebuilder:install
Ardından ilk bölümünüzü resources/views/sections/hero.blade.php dizininde oluşturun ve uygulamanızda /page-builder adresine gidin.
Sırada Ne Var
Sırada Ne Var
Aktif olarak üzerinde çalıştığımız şeyler:
- Revizyon geçmişi ile karşılaştırma görünümü.
- Daha fazla yerleşik bölüm türü (fiyatlandırma, referanslar, SSS).
- Başsız mod — ayrılmış ön uçlar için JSON çıktısı.
Bağlantılar
Bağlantılar
Eğer bunun üzerine bir şey inşa ettiyseniz veya mimari hakkında sorularınız varsa, yorumlarda bırakın. Sistemlerin herhangi bir katmanı hakkında derinlemesine tartışmaktan memnuniyet duyarım.
Kaynak: Orijinal Makale
- Problem
- Nasıl Çalışır
- Bölümler ve Bloklar Sadece Blade Görünümleridir
- {{ $block->settings->title }}
- Sayfalar JSON Olarak Depolanır
- İşleme Hattı
- Görsel Editör
- JSON Şablonları — Shopify Tarzı Yedekler
- Çoklu Tema Desteği
- Yeniden Kullanılabilir Blok Yuvalama
- Sayfa Başına Yerleşim Bölgeleri
- Yeni Bir Alan Türü Ekleme
- Kurulum
- Sırada Ne Var
- Bağlantılar


