Hepimiz o Controller metodunu yazdık.
Bahsettiğim metoda hepiniz aşinasınız; masumane başlar:
return view('products.index', [
'products' => Product::paginate(10)
]);
Fakat ardından ürün yöneticisinden gelen talepler birikmeye başlar:
- “SKU’ya göre arama yapabilir miyiz?”
- “Stokta yok için bir filtreye ihtiyacımız var.”
- “Oluşturulma tarihine göre sıralama yapabilir miyiz?”
- “Toplu silme düğmesi gerekiyor.”
- “Ve, lütfen Excel’e dışa aktaralım.”
Bir anda, o derli toplu Controller metodunuz 100 satırlık if ($request->has(...)) ifadeleriyle, karışık sorgu yapılandırma mantığıyla ve karmaşık döngülerle dolu bir görünüm dosyasına dönüşür.
Bu kaosa son vermeye karar verdim. Tüm bu parçaları birleştirerek tek ve akıcı bir PHP nesnesi gibi hissettirecek bir çözüm istedim.
Karşınızda TapTable.
Bu kütüphaneyi geliştirmek için yaşadığım baş ağrısının hikayesidir ve neden bileşenleri bir araya getirmek göründüğünden daha zor olduğudur.
Zorluk: “Yapıştırma” Problemi
Bir Veri Tablosu kütüphanesi inşa etmek, yalnızca HTML
“Sütunlar”, “Filtreler” ve “Eylemler” farklı sınıflara veya dizilere ayrıldığında, birbirleriyle iletişim kurmayı durdururlar.
Örneğin, Dışa Aktar butonu mevcut Arama durumunu bilmeye ihtiyaç duyar (yalnızca filtrelenmiş sonuçları dışa aktarmak için).
Toplu Eylem, sayfalar arasında hangi Onay Kutularının seçili olduğunu bilmelidir.
Sıralama Bağlantısı, URL sorgu dizesinde Filtre parametrelerini korumalıdır.
Bu parçaları birleştirmeye çalışmak genellikle karmaşık bir API ile sonuçlanır. TapTable için amacım Geliştirici Deneyimini (DX) kesintisiz hale getirmekti.
Bütünleşik Mimari
Bunu çözmek için, TapTable’ı yalnızca bir Görüntü Oluşturucu olarak değil, aynı zamanda bir Durum Konteyneri olarak ele almam gerekti.
Değişkenleri bir Görüntüye manuel olarak iletmek yerine, tablonun tam yaşam döngüsünü yakalayan akıcı bir sarıcı inşa ettim.
1. Söz Dizimi Hedefi
Kodun İngilizce gibi okunmasını istedim. Hiçbir yapılandırma dizisi, ayrı yapılandırma dosyası yok. Sadece akıcı yöntem zinciri.
İşte nihai sonucunun nasıl göründüğü:
// Hedef: Temiz, Birleşik, Anlamlı
return TapTable::make(Product::query())
->columns([
Column::make('name')->sortable()->searchable(),
Column::make('price')->formatMoney(),
Column::make('status')->badge(),
])
->filters([
SelectFilter::make('category_id', Category::all()),
DateFilter::make('created_at'),
])
->actions([
BulkAction::make('delete')->danger(),
Action::make('edit')->route('products.edit'),
])
->exportable()
->render();
2. “Tam Altında” Karmaşıklığın Yönetimi
Yapmanız gereken en zor kısım, bileşenleri akıllı hale getirmektir.
Örneğin, Column::make('name')->searchable() tanımladığınızda, TapTable yalnızca bir arama girişi render etmekle kalmaz. İstemci ve yanıt arasında bir middleware gibi davranır.
Kendi içimde bir Pipeline Sistemi inşa etmem gerekti:
- Hydrate: İstekten (URL parametreleri) oku.
- Apply Filters: Belirtilen filtreler üzerinden dön ve where koşullarını uygula.
- Apply Search: “searchable” sütunlar üzerinden dön ve dinamik olarak orWhere mantığını uygula.
- Apply Sort: sort_by parametrelerine göre kontrol et.
- Execute: Sorguyu çalıştır (ya da talep edilmişse Dışa Aktarma indirmesini tetikle).
- Render: Nihai koleksiyonu Görüntüye aktar.
Bu tüm işlemler ->render() methodu içinde gerçekleşir. Geliştirici karmaşık mantığı asla görmez.
Toplu Eylem Kâbusu
Bütünleşmenin en karmaşık kısmı etkileşimdir. Toplu Eylemler en kötü suçlulardır.
Standart bir kurulumda, genellikle tablonun etrafında bir <form> olur. Ama ya o formun içinde filtreler varsa? Sayfalama bağlantıları dışarıdaysa ne olur?
Bunu, TapTable’ın tek gerçeklik kaynağı olarak hareket etmesini sağlamakla çözdüm. Kullanıcı bir kutucuğu işaretlediğinde, bu sadece bir DOM öğesini değiştirip bırakmaz; kütüphanenin iç durumunu günceller.
Silme tıklandığında, kütüphane hangi kimliklerin işleneceğini tam olarak bilir ve geliştiricinin controllerda manuel bir foreach döngüsü yazmasına gerek kalmaz.
Neden “TapTable”?
Çünkü “Tıklanabilir” bir şey istedim. Mobil dostu, hızlı ve etkileşimli.
Çoğu veri tablosu kütüphanesi ağırdır. jQuery, DataTables.js ve tonlarca CSS yükler. TapTable, hafif ve PHP yerel olarak tasarlanmıştır. Laravel’in gücünü sunucuda ağır kaldırmak için kullanarak, yalnızca saf HTML/Alpine.js’yi istemciye gönderir.
Sonuç
TapTable’ı inşa etmek, yazılım mühendisliğinin en zor kısmının karmaşık mantık yazmak değil, karmaşık mantığı basit bir arayüzün arkasında saklamak olduğunu öğretti.
Sütunlar, Filtreler, Sorgular ve Kullanıcı Arabirimini tek bir uyumlu pakete birleştirmek zor bir mücadeleydi, ama 100 satırlık bir Controller’ı 10 satırlık TapTable koduna dönüştürdüğümde tüm zorluklarımın karşılığını aldım.
Manuel sayfalama ve filtreleme ile uğraşmaktan bıktıysanız, belki de yığınızı birleştirmenin zamanı gelmiştir.
Şu anda bunu, SaaS projem olan PagoraPOS’ta üretimde kullanıyorum ve bana yüzlerce saat kazandırdı.
Kendi tablolarınız için bir soyutlama mı oluşturdunuz? Yoksa standart Blade görünümlerine mi bağlı kalıyorsunuz? Yorumlarda belirtin!
Kaynak: Orijinal Makale


