Anasayfa / Moda / Leziz bir sayfalama menüsü

Leziz bir sayfalama menüsü

Webde adettir, bir listenin uzunluğu tek sayfa için çok uzun kaçıyorsa, insanlar kaydırma çubuğu ile uğraşıp yorulmasın diye liste sayfalara bölünür. Mesela Google’da arama yaparsınız, bilmem kaç milyon netice bulduğunu söyler ama ilk on tanesini gösterir. Diğerlerini görmek için sonraki sayfaları açmanız gerekir. Bulunduğunuz sayfadan diğerlerine geçmek için, sayfa numaraları ile link verilir. Bu linklere topluca sayfalama menüsü diyebiliriz.


PHP ile sayfalama (pagination) işleminin nasıl yapıldığını anlatan yüzlerce kaynak bulabilirsiniz. Ama sayfalama menüsünde hangi rakamların gösterileceğinin seçilmesini anlatan kaynak pek bulunmaz. Eğer listemiz sayfalara bölündüğünde 5-10 sayfa oluşuyorsa problem yoktur. Bütün sayfalara birden link verebiliriz. Ama sayfa sayısı arttıkça, her sayfanın altında biriken yüzlerce link, görüntü kirliliği oluşturmaya başlar.

Bu durumda ziyaretçinin bütün sayfalara en hızlı erişebileceği bir sayfalama menüsü oluşturmak, bir matematik problemine dönüşür. Ekseriyetle programcılar kolay yollara kaçar, “ilk sayfa, son sayfa, önceki sayfa ve sonraki sayfa” gibi dört linkle işi kotarmaya çalışırlar.


Gelgelelim, örnekteki gibi bir durumda, eğer bininci sayfaya gitmek istersek ya 499 defa “sonraki sayfa” linkine tıklamamız yahut önce “son sayfa” linkine tıklayıp, ardından 816 defa “önceki sayfa” linkine tıklamamız gerekmektedir. Aklı başında bir insan, eğer bir nebze web programlama bulaşığı varsa, gidip adres çubuğundan ilgili parametreyi değiştirmeyi tercih edecektir.

Zannediyorum problemi tanımladık. Şimdi gelelim çözüme...

Bulunduğumuz sayfadan önceki ve sonraki iki sayfaya link vermemiz, kolayca ileri geri gezinmeyi sağlar. İlk ve son sayfalara da link vermemiz gerekir ki bir seferde başa sona gidilebilsin. Bunlar cepte. Esas bulunduğumuz sayfa ile, ilk sayfa ve son sayfa arasında kalan çok miktarda sayfayı bir sayı doğrusu gibi düşünüp eşit aralıklara bölsek ve aralardan bazı sayfalara da link versek çok iyi olur değil mi? Şüphesiz.

Fakat şöyle bir problemimiz var. Diyelim ki 112. sayfadayız ve 1. sayfa ile 112. sayfa arasından 3 tanesine link vermek istiyoruz. Araya üç link ilave edebilmek için aralığı 4’e bölmemiz lazım.

112 / 4 = 28
28 x 2 = 56
28 x 3 = 84

Bu durumda 28, 56 ve 84. sayfalara link vereceğimizi buluyoruz. Peki sizce böyle küsuratlı sayfalara link vermemiz tuhaf gözükmez miydi?

1 28 56 84 110 111 112 113 114 ...

Demek ki bu küsuratlı rakamları yuvarlamamız lazım. Mesela 30, 60 ve 80 gibi.

1 30 60 80 110 111 112 113 114 ...

İşte oldu, algoritmamızı çıkarttık. Tabii kabaca. Şimdi bunu koda dökmemiz lazım. Ama burada yapılmışı var:) Evet kodu uzun açıklamaya üşendim. Evet maalesef satır satır anlama kısmı size kaldı...

function sayfa_numaralari ($yer, $toplam, $hane) { if ($hane<10) {$hane=10;} $isaretli=array(1=>true, $toplam=>true); for ($i=$yer-2;$i<$yer+3;$i++) { if ($i<1 || $i>$toplam) {continue;} $isaretli[$i]=true; } $sol=$yer-4; if ($sol<1) {$sol=0;} $sag=$toplam-$yer-3; if ($sag<1) {$sag=0;} $kalan=$hane-count($isaretli); $sol_a=($sol) ? $sol/($sol+$sag)*$kalan : 0; $sag_a=($sag) ? $sag/($sol+$sag)*$kalan : 0; if ($sol_a) { $sol_a=($sol>$sag) ? floor($sol_a) : ceil($sol_a); $sol_a=$sol/($sol_a+1); $us=floor(log10($sol_a)); $yuvarla=(($sol_a/pow(10, $us))<5) ? pow(10, $us) : pow(10, $us+1); for ($i=1;$i<$yer-2;$i+=$sol_a) { $i=round($i/$yuvarla)*$yuvarla; if ($i<1 || $i>$toplam) {continue;} $isaretli[$i]=true; } } if ($sag_a) { $sag_a=($sol>$sag) ? ceil($sag_a) : floor($sag_a); $sag_a=$sag/($sag_a+1); $us=floor(log10($sag_a)); $yuvarla=(($sag_a/pow(10, $us))<5) ? pow(10, $us) : pow(10, $us+1); for ($i=$yer+2;$i<$toplam;$i+=$sag_a) { $i=round($i/$yuvarla)*$yuvarla; if ($i<1 || $i>$toplam) {continue;} $isaretli[$i]=true; } } ksort($isaretli); return array_keys($isaretli); }

Fonksiyonumuz üç parametre alıyor:
İlk parametre: O anda bulunduğumuz sayfanın numarası.
İkinci parametre: Toplam sayfa sayısı
Üçüncü parametre: Menüde yer almasını istediğimiz link sayısı. Fonksiyon bu sayıyı tam tutturamayabiliyor. Mesela 15 link olsun istiyorsunuz; bazen 12, bazen 17 link oluşuyor.

Fonksiyonu çağırdığınız zaman geriye bir array dönüyor. Bu array’in içi, link vermemiz gereken sayfa numaralarıyla dolu durumda. Tabii ki bu linklerin nasıl verileceğini bu yazının kapsamı dışında bırakıyorum. Orasını halledersiniz artık:)

Sırada fonksiyonumuzu test etmek var. Bakalım verdiği sonuçlarda iş var mı?

Diyelim ki 100 sayfanın, 53. sayfasındayız. Fonksiyondan bize 10 link oluşturmasınız istiyoruz:

echo implode(' ', sayfa_numaralari(53, 100, 10));

Yukarıdaki kodla sayfa numaralarını toplu halde ekrana basıyoruz. Çıkışı aşağıdaki gibi oluyor:

1 20 40 51 52 53 54 55 60 70 80 90 100

Bir de 931 sayfanın 253. sayfasını deneyelim. Bu sefer 12 link isteyelim:

echo implode(' ', sayfa_numaralari(253, 931, 12));

Çıkışı aşağıdaki gibi oluyor:

1 100 200 251 252 253 254 255 300 500 700 900 931

Peki son sayfalarada olursak nasıl oluyor? 54 sayfanın 52.si için 10 link oluşturalım:

echo implode(' ', sayfa_numaralari(52, 54, 10));

Sonuç şu şekilde:

1 10 20 30 40 50 51 52 53 54

Son olarak büyük rakamları deneyelim. 4381 sayfanın 2732. sayfası için 15 link:

echo implode(' ', sayfa_numaralari(2732, 4381, 15));

İşte netice:

1 1000 2000 2700 2730 2731 2732 2733 2734 3000 3300 3600 3900 4200 4381

Nasıl, iş var mıymış? Beğendiyseniz bu fonksiyonu dağda bayırda yüke koşabilir, tepe tepe kullanabilirsiniz. Nereden bulduğunuzu soran olursa, doğru kaynağı fısıldayıp reklamımızı yapın yeter.

Sayfalama menüsünü çizerken, bulunduğumuz sayfayı büyük puntoyla, yakın olanları giderek küçülen puntolarla ve diğerlerini sabit küçük bir punto ile basarak balıkgözü efekti de oluşturulabilir. Bu kısmını cengâver CSS üstatlarına bırakıyorum:)

Yorum Yaz
Arkadaşların Burada !
Arkadaşların Burada !
Bu içeriği duvarında Paylaş
  • Bu içeriği arkadaşlarınla paylaş!
  • Yeni içerikler bul!