Grav İçerik URL ve Dizin İşlemleri

.htaccess Condition, Yönlendirme ve Dizin Düzenleme İşlemleri

WordPress içerik yönetim sisteminden Grav geçişinin ardından 2 aya yakın zaman geçti. Bu süreç içerisinde temelde Grav tema geliştirme sürecinde kullanmadığım pek çok konuyu da test etme imkanım oldu. Edindiğim bu bilgileri yeri geldikçe paylaşmaya devam edeceğim. Bu yazının konusu Grav içeriklerinde kullanılan (ön tanımlı olarak tercih edilen diyelim) klasör yapısına nasıl müdahale edebileceğimiz. Kendi karşılaştığım ve çözümlediğim durumu örneklendirerek anlatacağım.

Grav İçerik Yapısı

Grav CMS bir flat-file (dosya tabanlı) içeri yönetim sistemi. İçeriklerinizi klasörler halinde oluşturursunuz. Örneğin, bu yazı aslında pages > posts > 2020 > 10 > grav-directory-structure dizini içerisindeki post.tr.md dosyasından ibaret. Yazı içerisindeki görseller de yine (nasıl planladıysanız) grav-directory-structure içerisinde yer alıyor.

Siteyi ilk oluşurduğumda tüm içerikleri üretildikleri sıra ile pages > posts içerisinde tutuyordum.

01.icerik-adi/post.tr.md
02.icerik-adi/post.tr.md
...

Dizin adının başındaki 01 ve 02 gibi sayıları post ID olarak düşünebilirsiniz. Bu şekilde içerikleri üretildikleri sıraya (sizin belirlediğiniz) göre listeleyebilmektesiniz. Bu durumda içeriklerime /posts/post-directory veya /post-directory ile erişilebilmekteydi.

slug: post-directory
routes:
    default: /post-directory
    canonical: /posts/post-directory

Çoğunlukla içerikleri mobil telefon aracılığı ile ve komut satırı kullanarak düzenlediğimden bahsetmiştim. 500 civarında yazıyı bu şekilde yönetmenin oldukça can sıkıcı olduğu fikrine katılırsınız diye düşünüyorum. Dolayısıyla, içerik dizinindeki ID'leri kaldırmak, içerikleri tarihsel bir klasör yapısına ayırmak ve URL yapısının tüm bu değişikliklerden etkilenmemesini istedim. Evet, kendime iş çıkartmış oldum.

Özetle, yeni URI yapısının aynı kalmasını ancak içerikleri zamansal yoğunluklarına göre dizinlere ayırarak tutmak istedim.

İlk adım YAML satırlarını yeniden ele almaktı.

slug: post-directory
routes:
    default: /post-directory
    canonical: /posts/2020/10/post-directory

Bu aşamada elbette eski içeriklerin de yeniden ele alınması gerekti. İçerikleri yıl-ay olarak klasörlere ayırdım ve yayınladım. Elbette bu güncelleme pek çok 404 hatasını da beraberinde getirdi. Oluşturduğum Google Analytics uyarıları ve Google Data Studio raporu ile günlük olarak alınan hataları log'ladım ve düzenledim.

Bu durumda içeriklerim /post-directory veya /posts/2020/10/post-directory ile erişilebilir hale geldiler.

Grav İle İçeriklerin Listelenmesi

Grav ile bir dizin içerisindeki alt dizinleri ve bu dizinlerde bulunan *.md dosyalarını, genel ifade ile koleksiyonları (collection) ek kriterler de belirleyerek şu şekilde listeleriz.

{%
  set collection = page.collection({
    items: {
      '@page.children': '/'~page.slug
    },
    'limit': 20,
    'order': {
      'by': 'publish_date',
      'dir': 'desc'
    },
    'pagination': true,
    'simplesearch': {
      'route': '/search',
      'template': 'simplesearch_results'
    }
  })
%}

Burada items bizim içerikleri nerede bulacağımızı ifade etmektedir. page.slug sayfaların header alanında belirttiğimiz slug: post-directory değeridir. İçerikleri birden fazla derinliğe sahip klasörlere böldüğümüzde artık bu şekilde içeriklere ulaşamayız. Grav pek çok biçimde tarama yapabilmemize imkan sağlamaktadır1. Bu durumda, yeni yapıda kullanacağımız collection option '@self.descendants': '' oluyor. Böylelikle, ilgili dizinin alt dizinlerini tarayarak bulunan *.md dosyalarını içerik olarak sunuyoruz.

Grav URL Yapısı

Kategori ve etiketler /posts/category:... şeklinde içerik dizini içerisinde filtreleme yapıyorlar. Dolayısıyla /posts/ tanımını kaldırmamam gerekir. Dizin yapıp artık /posts/2020/10/post-directory şeklinde ancak default olarak /post-directory kullanıyorum. Dizin yapısının URL'e yansımasını, analitik araçlarında aynı içeriğe işaret eden farklı URL'ler olmasını ve elbette eski içeriklerin de hata döndürmesini istemiyorum.

İlk olarak .htaccess dosyasını ele aldım ve eğer URL /yil/ay/ içeriyor ise / şeklinde yönlendirilmesini istedim. İkinci olarak, eski içeriklerin de yine aynı şekilde eğer category, tag ve type tanımları içermiyorlarsa (yani sadece içerikler ise) / ile sunulmasını sağladım. Aşağıda kullandığım kod parçacığını görebilirsiniz.

RedirectMatch 301 /tr/posts/([0-9]+)/([0-9]+)/(.*)$ /$3
RedirectMatch 301 /tr/([0-9]+)/([0-9]+)/(.*)$ /$3

RewriteCond %{REQUEST_URI} !category
RewriteCond %{REQUEST_URI} !tag
RewriteCond %{REQUEST_URI} !type
RewriteRule ^tr/posts/(.*)$ /tr/$1 [L,R=301]

Bu işlem daha pratik ve mantıklı şekilde de yürütülebileceğini varsayıyorum, ancak, en azından benim için çözüm sağlanmış oldu. İlgili işlem ile ilgili önerileriniz olursa değerlendirmekten memnuniyet duyarım.

Gelelim bir sonraki sürece. Klasör isimlerindeki rakamları (01, 22, 333, ...) kaldırmak istedim. Elbette bu zorunlu değil, .htaccess işlemi sonrasında asıl amacıma çoktan ulaşmış oldum. Bu aşamada da basit bir bash kod parçacığı oluşturdum.

#!/bin/bash
for d in * ; do
  if [[ -d $d ]] && [[ $d =~ (^[0-9]+.) ]]
  then
    mv ${d} ${d/${BASH_REMATCH[1]}}
  fi
done

Kod parçacığı, ilgili dizin içerisindeki alt dizinleri listeliyor. Eğer dizin adı 01., 22., 333. gibi bir başlangıca sahipse dizin içeriğini bu rakamlar kaldırıldıktan sonra oluşturulan diğer dizine aktarıyor. mv komutu ile ilgili daha önce bir yazı yayınlamadım. Temelde olarak, dosya taşıma ve kopyala-yapıştır işlemleri için bu komuttan faydalanıyoruz. Bu kod parçacığını dosya-adi.sh ismi ile kayıt ettiğinizi varsayalım. Klasör isimlerindeki rakamların silinmesini istediğiniz dizin içerisinden bu dosyayı sh /dosya-yolu/dosya-adi.sh şeklinde çağırmanız yeterli.