Neden Başka Bir CMS?
Neden Başka Bir CMS?
Her geliştirme aracı, bir hedefle ortaya çıkar: geliştirme verimliliği. LindenCMS bunun dışında değildir. Misyonu, dinamik içeriği yapılandırmanın en verimli yolunu bulmaktır.
Web siteleri geliştirirken sıkça karşılaşılan bir görev ile karşılaşırsınız — sitenize yeni bir bölüm veya sayfa eklemek.
Geleneksel bir CMS kullanıyorsanız, migrations oluşturur, kaynak dosyalarını düzenler veya ek eklentiler kurarsınız. Kodu manuel yazıyorsanız, migrations, validation kuralları, kaynaklar ve view dosyaları arasında gidip geliyorsunuz. Uygulamanızda dağınık değişiklikler.
Neden tek bir sınıf bildirimi her şeyi — migrations, validation, admin UI ve API’yi — yönetemez?
İşte LindenCMS’nin sağladığı fikir tam olarak budur.
Görev: Bir Spor Salonu Web Sitesine Üyelikler Ekleme
Görev: Bir Spor Salonu Web Sitesine Üyelikler Ekleme
LindenCMS ile bir spor salonu web sitesi inşa ettik. Bu bir demo projesidir — gerçek üretim sitesi değil, ancak keşfedebileceğiniz tamamen işlevsel bir vitrin. Daha fazla bilgi için demo deposuna göz atabilirsiniz.
Şimdi müşteri yeni bir sayfa istiyor — Üyelikler — ziyaretçilerin mevcut planlarını görebileceği bir yer.
Tasarım şöyle:
Veri yapısı basit:
- title (string)
- price (float)
- is popular flag (boolean)
- access list (string[])
Sayfa şu özellikleri taşımalıdır:
- Tüm aktif üyelikleri listelemek
- Yönetim paneli aracılığıyla yönetilebilir olmak
İş Akışı
İş Akışı
LindenCMS bu görevi baştan sona şöyle yönetir.
Adım 1: Düğümü Tanımla
Adım 1: Düğümü Tanımla
namespace App\Nodes;
use LindenCMS\Cms\Attributes\Validation;
use LindenCMS\Cms\Attributes\View;
use LindenCMS\Core\Attributes\Collection;
use LindenCMS\Cms\Nodes\_Bool;
use LindenCMS\Cms\Nodes\_Float;
use LindenCMS\Cms\Nodes\_String;
use LindenCMS\Cms\Nodes\AppNode;
use LindenCMS\Cms\Nodes\AppNodeCollection;
#[View(
label: 'Membership',
labelMany: 'Memberships',
icon: 'mdi:wallet-membership',
index: ['title', 'price', 'created_at', 'updated_at'],
filterable: ['id', 'title', 'price', 'created_at'],
sortable: ['id', 'title', 'price', 'created_at'],
)]
class Membership extends AppNode
{
#[View(label: 'title', asOption: true)]
#[Validation('required')]
public _String $title;
public _Float $price;
public _Bool $is_popular;
#[Collection(Access::class)]
public AppNodeCollection $access;
}
Burada neler oluyor:
- AppNode — tüm içerik varlıkları için temel sınıf
- _String, _Float, _Bool — veri tutan tipli özellikler
- AppNodeCollection – tipli koleksiyon
- #[View] — bunu admin panelde nasıl görüntüleyeceğini bildirir
- #[Validation] — doğrulama kurallarını tanımlar
Her üyeliğin birden fazla erişim öğesi olabilir — “7/24 Spor Salonu Erişimi”, “Havuz Erişimi” veya “Kişisel Antrenman” gibi. Erişim sınıfı bu listedeki tek bir öğeyi temsil eder:
namespace App\Nodes;
use LindenCMS\Cms\Nodes\_String;
use LindenCMS\Cms\Nodes\AppNode;
class Access extends AppNode
{
public _String $title;
}
Şu anda basit — sadece bir başlık. Ancak daha sonra bunu kolayca genişletebilirsiniz:
class Access extends AppNode
{
public _String $title;
public _String $icon; // Yeni alan
public _Bool $is_available; // Diğer bir alan
}
Adım 2: Düğümü Kaydet
Adım 2: Düğümü Kaydet
Bunu config/lindencms.php dosyasına ekleyin:
'nodes' => [
'memberships' => App\Nodes\Membership::class,
],
Adım 3: Senkronizasyonu Çalıştır
Adım 3: Senkronizasyonu Çalıştır
php artisan lindencms:sync
Bu komut, veritabanınızı mevcut düğüm durumuna göç edecektir.
Adım 4: Yönetim Paneli Hazır
Adım 4: Yönetim Paneli Hazır
/lindencms adresine gidin ve Üyelikler bölümünü göreceksiniz, tam CRUD işlevselliği ile.
Ekstra bir kod gerekmiyor.
Adım 5: Kamu Sayfası
Adım 5: Kamu Sayfası
app/Nodes/Pages/MembershipsPage.php dosyasını oluşturun:
namespace App\Nodes\Pages;
use App\Nodes\Membership;
use LindenCMS\Cms\Attributes\Load;
use LindenCMS\Core\Attributes\Collection;
use LindenCMS\Cms\Nodes\AppNodeCollection;
use LindenCMS\Cms\Nodes\Page;
class MembershipsPage extends Page
{
#[Load(static function (AppNodeCollection $node) {
$node->context('db.read')->read()
})]
#[Collection(type: Membership::class)]
public AppNodeCollection $memberships;
}
Rotalari routes/web.php dosyasına ekleyin:
Route::get('/memberships', MembershipsPage::class);
View oluşturun — resources/views/pages/memberships-page.blade.php:
class="memberships">
@foreach ($page->memberships as $membership)
class="membership-card">
{{ $membership->title }}
${{ $membership->price }}/ay
@if ($membership->is_popular)
class="badge">Popüler
@endif
@foreach ($membership->access as $item)
{{ $item->title }}
@endforeach
@endforeach
şablon kasıtlı olarak basit tutulmuş olup depo sürümünden farklı olabilir
MembershipsPage, Membership::class‘ın bir listesini tutuyor; ancak — erişim koleksiyonu gibi, projeden herhangi başka düğümleri kolayca ekleyebiliriz:
class MembershipsPage extends Page
{
#[Load(static function (AppNodeCollection $node) {
$node->context('db.read')->read()
})]
#[Collection(type: Membership::class)]
public AppNodeCollection $memberships;
#[Load(static function (About $node) {
$node->context('db.read-first');
})]
public About $about;
}
Adım 6: Sonuç
Sayfa artık canlı. Tüm üyelikler görüntüleniyor, popüler planlar vurgulanıyor ve admin her şeyi panel aracılığıyla yönetebiliyor.
LindenCMS Yaklaşımı Bize Ne Sağlar?
LindenCMS Yaklaşımı Bize Ne Sağlar?
Tek Sınıf, Tam Kontrol
Tek Sınıf, Tam Kontrol
Membership Node, tek gerçeklik kaynağıdır. Diğer her şey ondan türetilir — veritabanı şeması, yönetim paneli, API uç noktaları. Yazılacak migrations yok. İnşa edilecek controller’lar yok. Tasarlanacak ADMIN görünümleri yok.
Bileşim Yoluyla Kod Yeniden Kullanımı
Bileşim Yoluyla Kod Yeniden Kullanımı
Erişim sınıfı mükemmel bir örnektir. Birden fazla bağlamda yeniden kullanılabilen basit bir Node:
// Üyelikler içinde
#[Collection(Access::class)]
public AppNodeCollection $access;
// Başka bir Node içinde
#[Collection(Access::class)]
public AppNodeCollection $benefits;
// Veya tek bir ilişki olarak
public Access $main_feature;
Trait-Tabanlı Organizasyon
Trait-Tabanlı Organizasyon
İlgili alanları ve davranışları maksimum yeniden kullanım için trait’lerde gruplayın:
// app/Nodes/Traits/HasSeo.php
trait HasSeo
{
#[View(label: 'Meta Title')]
public _String $meta_title;
#[View(label: 'Meta Description')]
public _Text $meta_description;
}
// app/Nodes/Traits/HasSlug.php
trait HasSlug
{
#[View(label: 'Slug')]
#[Validation('required|unique')]
public _Slug $slug;
}
// app/Nodes/Traits/HasGallery.php
trait HasGallery
{
#[Collection(Image::class)]
public AppNodeCollection $gallery;
}
Artık trait’leri birleştirerek Nodes oluşturabilirsiniz:
class Product extends AppNode
{
use HasSeo, HasSlug, HasGallery;
public _String $title;
public _Text $description;
public _Float $price;
}
class Article extends AppNode
{
use HasSeo, HasSlug;
public _String $headline;
public _RichText $content;
}
class Page extends AppNode
{
use HasSeo, HasGallery;
public _String $title;
public _String $subtitle;
}
Yerel PHP Paketleri Organizasyonu
Yerel PHP Paketleri Organizasyonu
Her şey sadece PHP sınıfları olduğu için, kodu yerel PHP paketlerine organize edebilirsiniz — herhangi bir PHP projesini yapılandırdığınız şekilde. Özel dizinler veya özel otomatik yükleme kuralları olmadan. Sadece standart PHP ad alanları ve Composer paketleri.
Esnek Veri Dağıtımı — Seçim Sizde
Esnek Veri Dağıtımı — Seçim Sizde
LindenCMS sizi verileri halka ulaşmak için tek bir spesifik yaklaşıma zorlamaz. Projenize uyan yöntemi seçersiniz:
Seçenek 1: Monolitik Sayfalar ile
Bu makalede gösterildiği gibi Sayfa sistemini kullanın — gerekli veri bildirin ve LindenCMS otomatik olarak bu verileri Blade görünümlerine yükler.
Seçenek 2: Geleneksel Laravel
LindenCMS, veritabanı şemalarını normalleştirilmiş bir biçimde ürettiğinden, tamamen Node sistemini atlayabilir ve standart Laravel Eloquent modelleri kullanabilirsiniz:
$memberships = DB::table('memberships')
->where('is_active', true)
->get();
Seçenek 3: Headless CMS (Yolda)
API oluşturma şu anda geliştirilmekte ve gelecekteki sürümler için planlanmaktadır. LindenCMS’i tamamen headless bir CMS olarak kullanabileceksiniz, otomatik REST uç noktaları ile.
Sonuç
Sonuç
LindenCMS henüz erken beta aşamasındadır. Test ve geri bildirim için stabil, ancak üretim projeleri için önerilmez. Temel mimarisi sağlamdır — aktif olarak geliştiriyoruz ve geri bildiriminizi duymak isteriz.
Faydalı Bağlantılar:
Kişisel iletişimi mi tercih ediyorsunuz?
Okuduğunuz için teşekkürler — düşüncelerinizi duymak isteriz.
Kaynak: Orijinal Makale
- Neden Başka Bir CMS?
- Görev: Bir Spor Salonu Web Sitesine Üyelikler Ekleme
- İş Akışı
- Adım 1: Düğümü Tanımla
- Adım 2: Düğümü Kaydet
- Adım 3: Senkronizasyonu Çalıştır
- Adım 4: Yönetim Paneli Hazır
- Adım 5: Kamu Sayfası
- {{ $membership->title }} ${{ $membership->price }}/ay @if ($membership->is_popular) class="badge">Popüler @endif @foreach ($membership->access as $item) {{ $item->title }} @endforeach @endforeach şablon kasıtlı olarak basit tutulmuş olup depo sürümünden farklı olabilir MembershipsPage, Membership::class‘ın bir listesini tutuyor; ancak — erişim koleksiyonu gibi, projeden herhangi başka düğümleri kolayca ekleyebiliriz: class MembershipsPage extends Page { #[Load(static function (AppNodeCollection $node) { $node->context('db.read')->read() })] # public AppNodeCollection $memberships; #[Load(static function (About $node) { $node->context('db.read-first'); })] public About $about; } Adım 6: Sonuç
- LindenCMS Yaklaşımı Bize Ne Sağlar?
- Tek Sınıf, Tam Kontrol
- Bileşim Yoluyla Kod Yeniden Kullanımı
- Trait-Tabanlı Organizasyon
- Yerel PHP Paketleri Organizasyonu
- Esnek Veri Dağıtımı — Seçim Sizde
- Sonuç




