Pagination. Sayfalandırma. İsteğimiz her post için ‘önceki’ ve ‘sonraki’ postlara gidecek birer link oluşturmak ve bunu herhangi bir plugin kullanmadan yapmak.
Aslında, postları tarihe göre sıralayıp önceki ve sonraki postlar için birer link ekleyeceğiz. Olduça basit bir iş. Hatta jekyll daha da basitleştirmiş ve bizim için önceden tanımlı birkaç değişken eklemiş.
post.previous
ile önceki postu, post.next
bir sonraki postu elde edebiliriz.
<a href="{{page.previous.url}}">{{page.previous.title}}</a>
<a href="{{page.next.url}}">{{page.next.title}}</a>
Yalnız burada herhangi bir filtreleme yok. Mevcut koleksiyon site.posts
içinde tarihe göre önceki ve sonraki yazıyı veriyor. Ben aynı sayfalandırmayı aynı kategori içerisinde sınırlandırmak istiyorum. Diğer bir deyişle, ‘jekyll’ kategorisinden bir yazı okurken önceki ve sonraki postların da yine ‘jekyll’ kategorisinden olmasını istiyorum.
Aşağıdaki gibi bir yapı kullanarak sayfalandırmanın (pagination) kategoriler arası geçişini engelleyebiliriz.
<div class="PageNavigation">
{% assign posts = site.posts | where:'category', page.category | sort:'date'%}
{% for post in posts %}
{% if post.title == page.title %}
{% assign previous_index = forloop.index0 | minus: 1 %}
{% assign next_index = forloop.index0 | plus: 1 %}
{% if previous_index >= 0 and posts[previous_index].url %}
<a href="{{posts[previous_index].url}}">{{posts[previous_index].title}}</a>
{% else %}
{% assign last = posts | last %}
<a href="{{last.url}}">{{last.title}}</a>
{% endif %}
{% if posts[next_index].url %}
<a href="{{posts[next_index].url}}">{{posts[next_index].title}}</a>
{% else %}
{% assign first = posts | first %}
<a href="{{first.url}}">{{first.title}}</a>
{% endif %}
{% break %}
{% endif %}
{% endfor %}
</div>
Post’ların front-matter’ında aşağıdaki satırlar mevcut olmalıdır.
---
title: test_title
category: test_category
---
Gelelim yukarıdaki kodun mantığına;
- Mevcut sayfanın category’sine göre sitedeki tüm postları filtrelenir ve date’e göre sıralanır. Bu diziye “posts” adı atanır.
Bu dizi içerisinde istediğimiz indexi (mevcut sayfa) bulmalı ve onu kullanarak bir önceki ile bir sonraki indexleri elde etmeliyiz. Tabii ki .IndexOf(object)
yapamayacağımız için;
- Posts içindeki herbir post için döngü döner ve title değişkenlerinin eşit olduğu yerde
forloop.index0
değişkenini kullanarak mevcut index elde edilir. [1] - Mevcut index üzerinden
previous_index
venext_index
değerleri elde edilir. - Linkleri oluşturmadan önce mevcut olup olmadıklarını
if posts[index].url
ile kontrol edilir. break
ile döngünün boşuna dönmeye devam etmemesi gerektiğini söylenir ve bitirilir.
[1] burada şuna dikkat etmeliyiz; eğer ki aynı başlığa sahip birden fazla post var ise kod istediğimiz gibi çalışmayacaktır. Onun için burada title özelliği herbir post için unique bir değer olmalıdır. Eğer aynı başlıkta postlar yazma ihtimaliniz var ise yine front-matter kısmına bir çeşit unique identifier ekleyip aynı mantık ile devam edebilirsiniz.
Aynı işi yapan, yani bir kategori içerisinde önceki ve sonraki postları veren, bir plugin ile karşılaştım. Denemedim ama büyük ihtimalle çok daha verimli çalışıyordur, yukarıdaki koddan. Link aşağıda.
İlgili bağlantılar: