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 Looker 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.