published on 03.07.2018

Bu yazıda daha önce yazdığım Etiketlere Göre İlgili Yazılar konusundaki yapıyı eleştirip iyileştireceğiz. En azından başlangınçta öyle düşünüyordum.

Kısaca hatırlayalım, ne yaptığımızı:

Amaç: Tüm postlar arasından (all_posts) mevcut sayfanın etiketlerinden (page.tags) en az birine sahip olan postları elde etmek.

Bu doğrultuda yazıları tarihe göre sıralayıp en az bir ortak etikete sahip olanları “ilgili yazılar” başlığı altında sıralamıştık.

Pekâlâ, bu yaklaşımın kusuru nedir?

  • Zamana göre sıraladığımız için, ortak en az bir etiket olması koşuluyla, her zaman son yazılan 4 post listelenecek. Diğer bir deyişle, yeni yazılara öncelik vermiş oluyoruz, önceden yazdığımız yazıları ikinci plana atıyoruz.

Belki de en mantıklı çözüm, aynı koleksiyon içerisindeki yazıları listelemek olacaktır. Böylece hem gereksiz yere diğer koleksiyonları birleştirip iş yükünü arttırmamış oluruz hem de zaten aynı koleksiyondaki yazılar birbirleriyle ilgili oldukları için istediğimize yakın bir sonuç almış oluruz.

Benzer yazıyı Pagination Filtered by Category başlığı altında önceden paylaşmıştım. Aynı koleksiyonda bir önceki ve bir sonraki yazıyı verecek kod ise basitçe aşağıdaki gibi yazılabilir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{% assign this_collection = site[page.collection] | sort: 'date'%}
  {% for item in this_collection %}
  {% if item.url == page.url %}
    {% if item.previous.url %}
        <a href="{{item.previous.url}}">{{item.previous.title}}</a>
    {% endif %}
    {% if item.next.url %}
        <a href="{{item.next.url}}">{{item.next.title}}</a>
    {% endif %}
  {% endif %}
{% endfor %}

Yine de bununla yetinmeyeceğiz! Gelelim, önceki yazıdaki kodu nasıl iyileştireceğimize. Örnek vererek açıklayalım.

(0) Okuduğumuz sayfa [jekyll, liquid, pagination, tags] etiketlerine sahip.

(1) Bu koleksiyondaki bir önceki yazı, tamamen aynı [jekyll, liquid, pagination, tags] etiketlere sahip.

(2) Bir başka sayfa ise [jekyll, mathjax, LaTeX] etiketlerine sahip.

Mevcut durumda, bizim için (1) ve (2), (0) ile ilişkili sayfa çünkü en azından bir adet etiket ortak. Kaç adet etiketin ortak olmasına dikkat etmiyoruz.

İstediğim yapı ise herbir post için 0 ile 1 arasında bir ilişki değeri üretecek ve o değere göre sıralayacak, tarihe göre değil! Örneğin, (1) numaralı yazı 4 etikete de sahip olduğu için ilişki değeri = 1 olacaktır. (2) ise sadece 1 etikete sahip olduğu için ilişki değeri = 0.25 olacaktır.

Evet, istediğim yapı bu. Peki ama sadece liquid syntaxı kullanılarak bu yapıyı kurmak mümkün mü? Değişkenlerim nesne değiller. Direkt item’ı saklamak istemedim. İstediğim yapı için hem item.title hem item.url hem de ilişki değeri’ni saklamalıyım ve üçü birbirine senkronize bir şekilde ilişki değerine göre sıralanmalı.

Teknik anlamda kolay olması gereken bu olay, burada imkansıza yakındır. Aklıma ilk gelen yapı, dictionary olmuştu. Tabii ki aradığımı bulamadım. Daha sonra kendi 2 boyutlu arrayimi oluşturayım dedim. Yine mümkün olmadığını gördüm. Üç ayrı array’i aynı döngü içinde döndürmekten başka çare ne yazık ki bulamadım.

Önceki yazı için büyük olasılıkla build time’ı kötü etkileyeceğini uzun ve karışık bir kod olduğunu söylemiştim; ancak asıl bu yazıda paylaşacağım kod bu niteliklere sahip. Kendileri uzun, karışık ve kesinlikle gereksiz ama yine de yazdım. Saçma bir inattı aslında, ilk günden beri çok basit, eksik ve ilkel bulduğum bu syntax ile bir nevi mücadeleye girdim bugün. Sonunda istediğim sonucu elde ettim.

Eğer okumadıysanız, Liquid: Dizi Operasyonları ve Hileler adlı yazıma kesinlikle bakmalısınız. Çünkü aşağıda acayip olaylar olacak.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
 {% assign constant_limit = 4 %}

    {% assign num_tags = page.tags | size | times: 1.0 %}
    {% assign tag_value = 1 | divided_by: num_tags %}

    {% for collection in site.collections %}
        {% assign name = collection.label %}
        {% assign all_posts = all_posts | concat: site[name] %}
    {% endfor %}

    {% assign url_array = '' | split: '' %}
    {% assign val_array = '' | split: '' %}
    {% assign title_array = '' | split: '' %}

    {% for item in all_posts %}

    {% assign rel_value = 0 %}
    {% assign arraysize = val_array | size %}

    {% if item.url == page.url %}
        {% continue %}
    {% endif %}

    {% for tag in page.tags %}
        {% if item.tags contains tag %}
            {% assign rel_value = rel_value | plus: tag_value %}
        {% endif %}
    {% endfor %}

    {% if rel_value != 0 %}
        {% assign free_slot = constant_limit | minus: arraysize %}

        {% if free_slot > 0 %}
            {% assign tempval = rel_value %}
            {% assign tempval = tempval | split: 'ğ' %}
            {% assign val_array = val_array | concat: tempval %}

            {% assign tempurl = item.url %}
            {% assign tempurl = tempurl | split: 'ğ' %}
            {% assign url_array = url_array | concat: tempurl %}

            {% assign temptitle = item.title %}
            {% assign temptitle = temptitle | split: 'ğçş' %}
            {% assign title_array = title_array | concat: temptitle %}

        {% else %}

        {% assign index = -1 %}

        {% for rv in val_array %}
        {% assign rv_int = rv | times: 1 %}
            {% if rel_value > rv_int %}
                {% assign index = forloop.index0 %}
            {% endif %}
        {% endfor %}

        {% if index != -1 %}

        {% assign tempval_array = '' | split: '' %}
        {% assign tempurl_array = '' | split: '' %}
        {% assign temptitle_array = '' | split: '' %}

        {% assign limit = index | minus: 1%}

        {% for i in (0..limit) %}
            {% assign tempval = val_array[i] %}
            {% assign tempval = tempval | split: 'ğ' %}
            {% assign tempval_array = tempval_array | concat: tempval %}

            {% assign tempurl = url_array[i] %}
            {% assign tempurl = tempurl | split: 'ğ' %}
            {% assign tempurl_array = tempurl_array | concat: tempurl %}

            {% assign temptitle = title_array[i] %}
            {% assign temptitle = temptitle | split: 'ğçş' %}
            {% assign temptitle_array = temptitle_array | concat: temptitle %}
        {% endfor %}

        {% assign tempval = rel_value %}
        {% assign tempval = tempval | split: 'ğ' %}
        {% assign tempval_array = tempval_array | concat: tempval %}

        {% assign tempurl = item.url %}
        {% assign tempurl = tempurl | split: 'ğ' %}
        {% assign tempurl_array = tempurl_array | concat: tempurl %}

        {% assign temptitle = item.title %}
        {% assign temptitle = temptitle | split: 'ğçş' %}
        {% assign temptitle_array = temptitle_array | concat: temptitle %}

        {% assign limit = arraysize | minus: 1 %}
        {% assign start = index | plus: 1 %}

        {% for i in (start..limit) %}
            {% assign tempval = val_array[i] %}
            {% assign tempval = tempval | split: 'ğ' %}
            {% assign tempval_array = tempval_array | concat: tempval %}

            {% assign tempurl = url_array[i] %}
            {% assign tempurl = tempurl | split: 'ğ' %}
            {% assign tempurl_array = tempurl_array | concat: tempurl %}

            {% assign temptitle = title_array[i] %}
            {% assign temptitle = temptitle | split: 'ğçş' %}
            {% assign temptitle_array = temptitle_array | concat: temptitle %}
        {% endfor %}

        {% assign val_array = tempval_array %}
        {% assign url_array = tempurl_array %}
        {% assign title_array = temptitle_array %}
        {% endif %}
        {% endif %}
    {% endif %}
{% endfor %}


{% assign title_array = title_array |reverse %}
{% assign url_array = url_array |reverse %}

<ul>
{% for i in url_array %}
    <li><a href="{{url_array[forloop.index0]}}">{{title_array[forloop.index0]}}</a></li>
{% endfor %}
</ul>

Her ne kadar çirkin de dursa kısaca anlatacağım.

  • Mevcut sayfanın tag sayısını kullanarak bir tagin değerini tag_value belirliyoruz.
  • Tüm koleksiyonları birleştiriyoruz.
  • 3 ayrı array oluşturuyoruz. url, val ve title
    • val_array‘inde yukarıda anlattığım ilişki değeri tutulacak. Bu değer 0 ile 1 arasında olabilir, ortak tag sayısı * tag_value
    • Diğer iki array adı ile ifade ediyor kendisini. Bu 3 array hep aynı işlemleri görecek ve böylece url[0] title[0] val[0] aynı sayfaya ait değerleri içerecek.
  • all_posts un içindeki herbir item için for döngüsüne gireceğiz.
    • Eğer page.url == item.url for döngüsünde bu iterasyonu pas geçeceğiz. (continue)
    • Bir sonraki döngü, ortak tag sayısı * tag_value ile rel_value ‘yü hesaplıyor.
    • Eğer ki rel_value 0’dan farklı ise (büyük ise)
      • free_slot hesaplıyoruz. Listeleyeceğimiz max. post sayısı (constant_limit) - mevcut sayı (arraysize)
      • Eğer yer var ise free_slot > 0; 3 array için de ilgili değerleri, kendi dizilerine ekliyoruz.
      • Eğer yer yok ise free_slot == 0; val_array deki değerler ile kıyaslayıp hangi indexe gelmesi gerektiğini hesaplıyoruz ve ilgili indexe atıyoruz.
  • En sonunda arrayleri kullanarak linkleri oluşturup listeliyoruz.

Her ne kadar teoride etiketleri daha iyi kullanarak daha anlamlı sonuçlar üretecek olsa da pratikte lüzumsuz bu yapıyı kurarken syntax ile epey haşır neşir olup bilgi edinmiş oldum. Kesinlikle iyileştirmeye müsait bir halde hâlâ. En azından istediğim çözüme ulaştım.

You are reading the 12nd of 19 episodes in Jekyll.
Published on 03.07.2018 by Mert Bakır with commit 5ebb327.
jekyll
#jekyll #liquid #pagination #tags #web-dev
Next episode:
Tag Cloud in Jekyll
published on 20.01.2019

Tag Cloud. Bloglarda karşımıza çıkan klişe yapı. Wordpress kullananlar automatic generate ediyorlardır, Jekyll için ise belki vardır plugin ama biz kendimiz oluşturacağız. Öncelikle tag-cloud.html adı altında bir include dosyası oluşturalım. Böylece daha sonra arşiv sayfasında, tag ya da post …

published on 20.01.2019

Bir postun altına, sıradaki N adet postun linkini nasıl ekleriz? Pagination, ama previous ile next yerine next N post. N, sizin seçeceğiniz bir sayı. Pagination adlı yazıda, önceki ve sonraki yazıları nasıl elde edeceğimizi anlatmıştım. Bir de uzunca ve build time kötü etkileyecek ama teoride …

published on 21.01.2019

Jekyll’da varsayılan olarak gelen yapıda tüm postları _posts/ klasörü altında tutarız. Post sayısı arttıkça postları gruplama, alt klasörlere bölme ihtiyacı duyabilirz. Jekyll hâlâ postları görecek ve site.posts değişkeni, _posts/ ve altındaki tüm alt dizinlerdeki tüm postları getirecektir. …

published on 01.07.2018

Oldukça uzun, bir o kadar da gerekliliği tartışılır kod parçasını paylaşmak üzereyim. Baştan söyleyelim, biraz döngüler dönecek if statementlar kontrol edilecek. Bunlara bağlı olarak, eğer blogunuzda çok post varsa build time kötü derecede etkilenecek. Ne kadar etkisi olur, 11 postluk blogta şu an …

published on 18.05.2018

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ş. …

published on 29.08.2020

My experience with Hugo has been pretty good so far. It’s fast and flexible. Ever since I started using Hugo, I’ve been improving my website with small tweaks. In this post, I am going to share some tricks and workarounds I’ve found online while working with Hugo. Besides that, …