📖 Site Rehberi · 🔐 Supabase Sistemi · 🍴 Fork Kurulumu
📖 Site Rehberi — Hangi Dosya Ne İşe Yarar, Neyi Nerede Değiştiririm?
Bu dosya, siteyi bir daha açtığında (“bunu nereye koymuştum?”) hızlıca yön bulman için var. Her bölüm bir dosyayı/özelliği anlatıyor: ne işe yarıyor, hangi satırı değiştirirsen ne olur.
0. Klasör yapısı — sayfalar neden alt klasörlerde?
Kök dizinin GitHub’da (dosya listesinde, commit geçmişinde) karışık
görünmemesi için tek tek sayfalar (Jekyll’in “pages” dediği .md
dosyaları) konularına göre 4 klasöre ayrılmıştır:
| Klasör | İçerik | Örnek URL |
|---|---|---|
hesap/ |
Giriş, kayıt, şifre sıfırlama akışı | /hesap/giris.html |
panel/ |
Oturum açmış kullanıcı sayfaları (panel, admin, GitHub içerik yönetimi, özel içerik) | /panel/panel.html |
icerik/ |
Herkese açık içerik listeleri (blog, akademik projeler, izlediklerim, okuduklarim) | /icerik/blog.html |
kurumsal/ |
İletişim, gizlilik politikası | /kurumsal/iletisim.html |
Önemli: Bu, sadece bu sayfaların repo’daki kaynak dosya konumu.
Her sayfanın front-matter’ında (permalink: alanı yoksa Jekyll klasör
yapısından otomatik üretir, buradaki sayfalarda URL klasör adını
birebir yansıtır — örn. panel/panel.md → /panel/panel.html) URL’ler
klasör yapısıyla tutarlıdır. Bir sayfayı bulmak istediğinde: URL’in ilk
parçası (/panel/..., /hesap/... vb.) hangi klasörde olduğunu
doğrudan söyler.
index.md, index-bakim.md, _config.yml, _headers, Gemfile,
README.md, robots.txt, feed.xml gibi Jekyll’in kökte durmasını
beklediği ya da tüm siteyi ilgilendiren dosyalar kökte kalmaya devam
eder — sadece “tek bir sayfaya ait” .md dosyaları klasörlere ayrılmıştır.
Bir sayfanın URL’ini değiştirmek istersen: ilgili dosyanın
front-matter’ındaki permalink: satırını değiştirmen yeterli, dosyayı
taşımana gerek yok. Ama URL’i değiştirirsen, o sayfaya link veren tüm
yerleri (nav menüsü _layouts/default.html, assets/js/nav-auth.js,
auth-guard.js, auth-pages.js içindeki Supabase redirect URL’leri,
ilgili diğer .md sayfalarındaki iç linkler) da elle güncellemen
gerekir — aksi halde kırık link veya (giriş/şifre sıfırlama söz konusuysa)
sessizce çalışmayan bir akış ile karşılaşırsın.
1. _config.yml — Sitenin ana ayar dosyası
Jekyll build’inde her sayfaya site.XXX olarak erişilebilen tüm genel
değerler burada. En sık dokunacağın dosya.
| Alan | Ne işe yarar |
|---|---|
title |
Site başlığı, sekme adı, header’daki logo yazısı |
description |
SEO açıklaması, sosyal medya paylaşım kartlarında görünür |
url |
Sitenin birincil adresi (Cloudflare Pages domainin) |
github_username |
GitHub kullanıcı adın |
kutuphane_repo |
İzlediklerim/okuduklarım verisinin tutulduğu ayrı repo |
izleme_projects_url / okuma_projects_url |
GitHub Projects panolarının linkleri |
substack_url / substack_feed |
Substack blog adresin ve RSS feed’i |
google_analytics_id |
Google Analytics ölçüm kimliği |
profile_image |
Profil fotoğrafın (assets/e yükleyip yolunu buraya yaz) |
cloudflare_worker_url |
İzleme/okuma verisini çeken Worker’ın adresi |
mirror_site_url |
Yedek/ikincil site adresin (GitHub Pages) |
giscus: altındaki alanlar |
Yorum sistemi (giscus.app’ten alınır) — category için “Announcements” tipi bir kategori seçmen önerilir, böylece yorum başlığını sadece sen/giscus botu açabilir |
social: altındaki linkler |
GitHub, LinkedIn, X/Twitter, Instagram, YouTube, n-sosyal, ORCID, Academia, ResearchGate, 1000Kitap, Play Store |
future |
true kalmalı — zamanlanmış/gizli yazıların çalışması buna bağlı, bkz. bölüm 9 |
2. _config_cloudflare.yml — Sadece Cloudflare build’ine özel ek ayarlar
Cloudflare Pages build komutunda --config _config.yml,_config_cloudflare.yml
ile birlikte okunur; buradaki anahtarlar _config.yml‘deki aynı isimli
anahtarların üzerine yazar. Şu an sadece google_analytics_id burada —
Cloudflare build’i için ayrı bir Analytics ID istersen kullan, aynı ID’yi
kullanacaksan bu dosyaya dokunmana gerek yok.
3. _headers — Cloudflare Pages güvenlik header’ları
Kök dizinde duran bu dosya, Cloudflare Pages tarafından otomatik okunur
(bir ayar paneline eklemene gerek yok — dosyanın repo’da olması yeterli).
Her sayfaya X-Frame-Options, X-Content-Type-Options, Referrer-Policy,
Permissions-Policy, Strict-Transport-Security header’larını ekler.
Sadece Cloudflare Pages’te çalışır — GitHub Pages özel HTTP header
ayarlamayı desteklemiyor, o yüzden mirror sitede bu korumalar yok.
Değiştirmek isteyebileceğin tek yer: Permissions-Policy satırındaki
camera=(), microphone=(), geolocation=(), payment=() — ileride bu
API’lerden birini gerçekten kullanacaksan (örn. bir harita gömersen ve
konum istersen), ilgili parantezin içine (self) yazman gerekir.
4. kurumsal/iletisim.md — İletişim formu
src="FORM-EMBED-LINKINI-BURAYA-YAPISTIR" satırındaki placeholder’ı,
Google Forms’tan aldığın gerçek embed linkiyle değiştir (Forms’ta
Gönder > <> ikonu > src= değerini kopyala).
5. cloudflare-worker/worker.js — İzlediklerim/Okuduklarım verisini çeken Worker
Bu dosya Cloudflare Dashboard’a ayrıca yapıştırılıp deploy edilmesi gereken ayrı bir kod — repo’daki kopyası sadece kaynak/yedek, canlıya otomatik yansımaz. Değiştirdiğinde Cloudflare Dashboard’da “Save and Deploy” yapman gerekir.
| Ne | Nerede | Nasıl değiştirilir |
|---|---|---|
| GitHub kullanıcı adı | GITHUB_LOGIN sabiti (dosyanın başı) |
Tırnak içindeki değeri kendi kullanıcı adınla değiştir |
| Proje numaraları | PROJECTS objesi içinde number: |
GitHub Projects panosunun URL’indeki /projects/N/ sayısı |
| Sütun sırası | PROJECTS objesi içinde her projenin sutunSirasi: dizisi |
Panoda sütunları sürükleyip yer değiştirdiğinde site OTOMATİK güncellenmez (GitHub API view-sırasını döndürmüyor) — panodaki güncel sırayı, sütun adlarını BİREBİR yazımla (büyük/küçük harf dahil), soldan sağa bu diziye elle yaz. Listede unuttuğun bir alan otomatik sona eklenir, kaybolmaz. sutunSirasi: [] bırakırsan GitHub’daki field oluşturma sırası kullanılır. |
| Gizlenen “yerleşik” sütunlar | YERLESIK_ALANLAR seti |
GitHub’ın otomatik eklediği sistem alanları (Assignees, Labels, Reviewers, Created, Updated, vb.) burada listeleniyor ve tabloya hiç girmiyor. GitHub ileride yeni bir sistem alanı eklerse ve sitede gereksiz bir sütun görürsen, o alanın adını (BİREBİR yazımla) bu sete ekle. |
GITHUB_TOKEN |
Kodun içinde YOK | Cloudflare Dashboard > Settings > Variables and Secrets kısmından secret olarak eklenir. Asla dosyaya yazma. |
6. robots.txt
Sitemap: satırındaki adres, _config.yml‘deki url ile aynı domaini
göstermeli.
7. _includes/hakkimda-icerik.md ve _includes/hakkimda-kutusu.md
Anasayfada görünen “hakkımda” metni ve kutusu — biyografini, unvanını, tanıtım yazını buraya serbest metin olarak yaz.
8. İçerik ekleme — blog yazıları ve akademik projeler
- Blog yazısı:
_posts/klasörüneYIL-AY-GUN-baslik.mdformatında yeni bir dosya ekle (örn._posts/2026-09-01-yeni-yazi.md).icerik/blog.mdsayfasına hiç dokunmana gerek yok, otomatik listelenir. - Akademik proje:
_projects/klasörüne aynı mantıkla yeni bir.mddosyası ekle (örn._projects/2026-yeni-proje.md). Kullanılabilecek front-matter alanları için_projects/2025-ornek-proje.mddosyasındaki örneğe bak (title,date,venue,status,summary,link,link_label).
9. Zamanlanmış ve gizli yazılar/projeler
Bir yazıyı ya da akademik projeyi GitHub’a hemen ekleyip, sitede istediğin tarihe kadar veya sen izin verene kadar görünmemesini sağlayabilirsin.
Nasıl çalışır?
“yayinda” ve “date” artık birbirine bağlı çalışıyor. Bir yazı/proje sitede görünmek için iki şartı BİRDEN sağlamalı:
yayinda: falseYAZILMAMIŞ olmalı (alan yoksa veyatrueise sorun yok).datealanındaki tarih gelmiş veya geçmiş olmalı (gelecekteyse gösterilmez).
Yani:
yayinda: true+dateileri bir tarih → tarih gelene kadar gösterilmez, tarih geldiği an (bir sonraki build’de) otomatik görünür.yayinda: true+datebugün veya geçmiş → hemen görünür.yayinda: false+dategeçmiş bir tarih olsa bile → yine de gösterilmez, sen elleyayinda: trueyapmadan asla görünmez.yayinda: falseher zamanyayinda: true‘dan önceliklidir — yanidatene olursa olsunyayinda: falsevarsa sayfa gizlidir.
Front-matter’a şu iki alanı ekle:
---
title: "Yazı Başlığı"
date: 2026-09-01
yayinda: true
sitemap: false
permalink: /blog/on-izleme-RASTGELE-BIR-DIZI/
---
sitemap: false, gizli/zamanlanmış her yazıyla HER ZAMAN birlikte yazılmalı (yayinda: falseolsun ya da ileri tarihli olsun fark etmez). Bu,jekyll-sitemapeklentisinin kendi tanıdığı resmi bir alan — sadece bunu görürse sayfayısitemap.xml‘den çıkarıyor, bizim uydurduğumuzyayinda/datemantığını tanımıyor. Yazmazsan sayfa blog listesinde görünmez ama sitemap’te görünmeye devam eder.- Görünürlük şartları sağlanmadığı sürece yazı: blog listesinde
(
icerik/blog.md), akademik projeler listesinde (icerik/akademik-projeler.md) ve RSS feed’inde (feed.xml) görünmez.sitemap: falsede site haritasından (sitemap.xml) çıkarır. Arama motorlarına ayrıcanoindexsinyali gönderilir (sayfa ziyaret edilse bile indekslenmez) — bu artık hemyayinda: falsehem de “date henüz gelmedi” durumunda otomatik devreye giriyor. - Sayfanın kendisi yine de var olur —
permalinkalanında yazdığın adresi bilen biri doğrudan girip okuyabilir. Bu senin “manuel paylaşım” yöntemin: linki kimseyle paylaşmazsan kimse bulamaz; paylaştığın anda o kişi (ve linkin gittiği herkes) okuyabilir. permalinkMUTLAKA tahmin edilemez, rastgele bir dizi içermeli —/blog/on-izleme-x7k2p9qz/gibi./blog/yeni-yazi/gibi tahmin edilebilir bir adres KULLANMA, güvenlik tamamen bu adresin gizli kalmasına dayanıyor. Rastgele bir dizi üretmek için:- Tarayıcının adres çubuğuna
javascript:alert(crypto.randomUUID())yazıp Enter’a basabilirsin (bazı tarayıcılarjavascript:yapıştırmayı engeller, o zaman DevTools > Console’acrypto.randomUUID()yaz). - Ya da terminalde:
openssl rand -hex 8
- Tarayıcının adres çubuğuna
sitemap: false, görünürlük şartlarından TAMAMEN bağımsız çalışır. Yani front-matter’a ellesitemap: falseyazmazsan,yayinda/datene olursa olsun sayfa sitemap.xml’e girer. Zamanlanmış/gizli her yazıda bunu yazmayı unutma —noindexyine indekslenmesini engeller, ama URL’in kendisi sitemap üzerinden “keşfedilebilir” hale gelir.permalinkalanını silersen Jekyll dosya adından otomatik bir adres üretir (örn./blog/2026/09/01/yazi-basligi.html) — bu tahmin edilebilir bir adres olduğu için SADECE normal, açık yazılardapermalink‘i silmelisin. Gizli/zamanlanmış bir yazıdapermalink‘i silmek, gizlilik amacını tamamen ortadan kaldırır.- Erken yayınlamak istersen (tarih gelmeden görünsün istersen):
date‘i geçmişe çek ya da bugüne eşitle. - Bir yazıyı süresiz gizli tutmak istersen:
yayinda: falseyaz,date‘i hiç düşünme —yayinda: falseher zaman kazanır. - “Belirli bir tarihte otomatik yayınlansın” istersen:
date:alanını istediğin tarihe ayarlaman veyayinda: true(ya da alanı hiç yazmaman) artık tek başına yeterli — ama bunun gerçekten “otomatik” olması için Cloudflare Pages’in o tarihte YENİ BİR BUILD alması gerekiyor, çünkü statik site build zamanındaki tarihe göre üretiliyor. Bunun için repo’ya bir GitHub Actions workflow’u eklendi:.github/workflows/zamanlanmis-yayin.yml. Bu workflow her gün otomatik çalışıp Cloudflare Pages’te yeni bir build tetikliyor. Kurulumu (bir kereye mahsus):- Cloudflare Pages projenin ayarlarından Deploy Hooks (Dağıtım Kancaları) bölümüne git, yeni bir Deploy Hook URL oluştur.
- GitHub reponda Settings → Secrets and variables → Actions →
New repository secret ile
CLOUDFLARE_DEPLOY_HOOK_URLadında bir secret oluştur, değerine az önce kopyaladığın URL’i yapıştır. - Bu kadar — workflow her gün otomatik çalışacak. İstersen GitHub’da Actions sekmesinden “Run workflow” ile elle de tetikleyebilirsin (örneğin tarihi tam geçtiği an hemen yayınlanmasını istiyorsan).
- Cron saatini değiştirmek istersen workflow dosyasındaki
cron:satırını düzenle (yorum satırında açıklama var).
- Örnek bir taslak dosya için
_posts/2026-08-15-ornek-zamanlanmis-yazi.mddosyasına bak — aynı desen_projects/için de birebir çalışır (örnek alanlar_projects/2025-ornek-proje.mdiçinde yorum satırı olarak var).
Nerede tanımlı (teknik detay, dokunmana gerek yok ama bilgi için)
_config.yml→future: true— sayfanın gelecek tarihli olsa da build edilmesini sağlıyor (linkin çalışabilmesi için şart).icerik/blog.md,icerik/akademik-projeler.md,feed.xml→ listeleme döngülerindewhere_exp: "p", "p.yayinda != false" | where_exp: "p", "p.date <= site.time"filtre zinciri —yayindavedateşartlarını art arda iki ayrıwhere_expile kontrol ediyor (GitHub Pages’in kullandığı Liquid sürümü, tek birwhere_expiçineandile yazılmış birleşik ifadeleri her zaman doğru parse edemiyor; iki ayrı filtre zincirlemek hem GitHub Pages hem Cloudflare/yerel Jekyll’de güvenilir çalışıyor).sitemap.xml→jekyll-sitemapeklentisi tarafından otomatik üretiliyor, front-matter’daki resmisitemap: falsealanına kendisi bakıyor (bizimyayinda/datemantığımızdan habersiz, o yüzden ayrı yazılması gerekiyor).feed.xmldosyasının kendisi kökte elle yazılmış durumda — Jekyll’in otomatikjekyll-feedeklentisi BİLEREK kapatıldı (_config.ymlveGemfile‘den çıkarıldı) çünkü o eklentinin kendi “published: false” alanı sayfayı build’den tamamen siliyor, bu da gizli linki kırıyordu._layouts/default.html→page.yayinda == falseVEYApage.datehenüz gelmemişse<meta name="robots" content="noindex, nofollow">ekliyor._layouts/post.html,_layouts/project.html→ aynı iki durumda (gizli ya da henüz zamanı gelmemiş) sayfanın üstünde uygun bir uyarı gösteriyor..github/workflows/zamanlanmis-yayin.yml→ günlük otomatik Cloudflare Pages build tetikleyicisi (yukarıdaki kurulum adımlarına bak).
10. panel/github-yonetim.md — GitHub Pages için tarayıcı içi içerik yönetim paneli (mini CMS)
Bölüm 8 ve 9’da anlatılan işi (yeni _posts//_projects/ dosyası
oluşturma, yayinda/sitemap/permalink alanlarını elle yazma) artık
elle dosya oluşturup GitHub’a push etmeden, doğrudan tarayıcıdan
yapabileceğin bir panel var: /panel/github-yonetim.html. Netlify/Decap CMS
gibi 3. parti bir servise ihtiyaç duymaz — doğrudan GitHub REST API’sine
(contents endpoint’i) istek atıp commit oluşturur, tamamen GitHub
Pages’in kendisiyle çalışır.
Bu panel, sitenin Supabase tabanlı /panel/admin.html panelinden TAMAMEN
BAĞIMSIZDIR. /panel/admin.html Supabase’teki üye/rol/özel içerik sistemini
yönetir; /panel/github-yonetim.html ise bu deponun kendi statik Jekyll
içeriğini (blog yazıları, akademik projeler, profil fotoğrafı) yönetir.
Aralarındaki tek ortak nokta: bu sayfaya erişim de aynı
requireAuth({ role: 'admin' }) mekanizmasıyla korunur (bkz.
assets/js/auth-guard.js), yani sadece Supabase’te role: 'admin' olan
hesaplar görebilir. Header’daki “Hesabım ▾” menüsünde, adminsen
“Admin Paneli” linkinin hemen altında “GitHub İçerik Yönetimi” olarak
görünür (bkz. assets/js/nav-auth.js).
Paketteki dosyalar
panel/github-yonetim.md <- Jekyll sayfası (_layouts/default.html'i kullanır, admin-only)
assets/js/github-yonetim.js <- Panelin tüm mantığı
assets/css/github-yonetim.css <- Bu sayfaya özel ek stiller (auth.css'in üzerine eklenir)
Neler yapabilirsin
- Blog yazısı / Akademik proje ekle veya düzenle — içerik türünü
seçtiğinde form alanları otomatik değişir (proje seçilince
venue,status,summary,link,link_labelalanları da görünür). Dosya adı (slug) boş bırakılırsa başlıktan otomatik üretilir (Türkçe karakterler sadeleştirilir). - “Yayında” anahtarını kapatırsan (modern bir toggle switch; klasik
onay kutusu değil) panel otomatik olarak
yayinda: false,sitemap: falseyazar ve 8 karakterlik rastgele bir kodla (crypto.getRandomValuesile üretilir, tahmin edilemez) gizli bir ön izleme linki oluşturur (/blog/on-izleme-XXXXXXXX/veya/projects/on-izleme-XXXXXXXX/) — bkz. yukarıdaki Bölüm 9’daki mantığın aynısı, sadece elle yazmak yerine panel yazıyor. Bu link tek seferlik değildir ve düzenlenebilir: anahtarı kapatır kapatmaz, dosyayı hiç kaydetmeden önce bile ekranda görünür — kodu olduğu gibi kullanabilir, kutuya kendi kodunu elle yazabilir (örn./blog/on-izleme-taslak-v2/) veya “🎲 Yenile” butonuyla yeni bir rastgele kod üretebilirsin. Kaydettikten sonra da ekranda kalır, anahtarı kapatıp açtığında anında görünür/gizlenir, “Mevcut İçerikler” listesinden aynı yazıyı tekrar “Düzenle”ye açtığında da aynı link otomatik olarak yeniden gösterilir — panel bunu dosyanınpermalinkalanından okur. Link, sen bilerek değiştirmediğin sürece her düzenlemede aynı kalır, böylece daha önce birine gönderdiğin bir ön izleme linki içeriği güncellesen bile kırılmaz. Panel, aynı türde (blog/proje) başka bir içeriğin zaten kullandığı bir kodu tekrar kaydetmene izin vermez (çakışma kontrolü) — böyle bir durumda hata mesajıyla uyarır. Yazının/projenin kendi sayfasında da (görüntülerken) “henüz yayında değil” uyarısı görünür (bkz._layouts/post.html/_layouts/project.html), böylece linke sahip olan biri içeriği görüntülerken durumundan haberdar olur. - Hafif bir Markdown editörü — kalın, italik, başlık ve bağlantı eklemek için metin alanının üstünde küçük araç çubuğu butonları var.
- Mevcut İçerikler sekmesi —
_posts/ve_projects/klasörlerindeki tüm dosyaları listeler (yayında/gizli durumunu rozetle gösterir), “Düzenle” ile formu doldurup güncelleyebilir, “Sil” ile GitHub’dan kalıcı olarak silebilirsin. İçerik sayısı arttıkça listede kaybolmamak için üstte bir arama kutusu (başlık, dosya yolu ve özet içinde arar, eşleşen kısmı vurgular) ve iki grup filtre sekmesi var: içerik türüne göre (Tümü / Blog / Projeler) ve yayın durumuna göre (Tümü / Yayında / Gizli) — ikisi birlikte kullanılabilir, sonuç yoksa bunu ayrıca belirten bir mesaj gösterilir. - Profil Fotoğrafı Yönetimi sekmesi —
assets/profil.jpgdosyasının var olup olmadığını GitHub API üzerinden kontrol edip önizlemesini gösterir; yeni bir görsel seçip “Yükle/Değiştir” ile değiştirebilir, “Profil Fotoğrafını Sil” ile tamamen kaldırabilirsin.
GitHub bağlantısı ve token güvenliği
Panelin üstündeki “GitHub Bağlantısı” sekmesinden şunları girmen gerekir:
- GitHub Kullanıcı Adı ve Repository Adı — gizli bilgi olmadığı
için kolaylık amacıyla tarayıcının
localStorage‘ında hatırlanır. - Branch (opsiyonel) — boş bırakırsan reponun varsayılan branch’i kullanılır.
- GitHub Personal Access Token (PAT) — SADECE sekme açıkken tarayıcı belleğinde tutulur, hiçbir yerde (localStorage dahil) kalıcı olarak saklanmaz. Sayfayı yenilediğinde veya sekmeyi kapattığında token kaybolur, bir sonraki girişte yeniden yapıştırman gerekir. Bu bilinçli bir tercih: localStorage’a yazmak daha kullanışlı olurdu ama bir XSS açığında token’ın kalıcı olarak sızdırılması riskini taşır.
- Fine-grained bir token oluştur ve sadece bu repo için
Contents: Read and writeiznini ver — tüm hesaba erişen “classic” bir token kullanmaktan çok daha güvenlidir. (token oluşturma sayfası) - “Bağlantıyı Doğrula” butonu, token’ın gerçekten yazma iznine sahip
olup olmadığını (
permissions.push) kontrol eder ve sonucu gösterir.
Teknik detay (dokunmana gerek yok ama bilgi için)
- İçerik, GitHub’ın
contentsAPI’siyle (PUT/DELETE /repos/{owner}/{repo}/contents/{path}) base64 kodlanmış olarak gönderilir; Türkçe karakterler içinencodeURIComponent+btoa/atobtabanlı bir UTF-8 güvenli base64 dönüşümü kullanılır. Profil fotoğrafı gibi ikili (binary) dosyalar içinFileReader. readAsDataURLile üretilen base64 doğrudan kullanılır. - Var olan bir dosyayı güncellerken GitHub API’nin zorunlu kıldığı
shaparametresi otomatik olarak önce birGETisteğiyle alınır. Düzenleme sırasında dosya adını/tarihini değiştirirsen (dosya yolu değişirse) panel önce yeni yola yazar, sonra eski dosyayı siler (yeniden adlandırma simülasyonu) — GitHub API’de doğrudan bir “rename” uç noktası yoktur. - “Mevcut İçerikler” listesi front-matter’ı panelin kendi ürettiği sınırlı alan setine göre basit bir regex ile okur; elle çok farklı bir YAML yapısı yazılmış dosyalarda (örn. çok satırlı değerler) güvenilir çalışmayabilir — bu durumda dosyayı GitHub üzerinden elle düzenlemen daha güvenlidir.
- Bu panel de, tıpkı Bölüm 9’daki gibi, sitenin görünürlük mantığına
(
yayinda/date/sitemap) aynen uyar — ürettiği dosyalar mevcuticerik/blog.md,icerik/akademik-projeler.md,feed.xmlvesitemap.xmlile sorunsuz çalışır.
🎨 Tema Anahtarı (Koyu/Açık Mod)
Header’daki kayan switch — ☀️/🌙 ikonları sabit iki uçta, ortadaki topuz aktif temaya göre kayıyor, yanında “Açık mod”/”Koyu mod” yazan bir etiket var.
| Ne | Nerede |
|---|---|
| Yapı (HTML) | _layouts/default.html içinde #theme-toggle butonu |
| Davranış (JS) | Aynı dosyanın altındaki <script> bloğu — data-theme özniteliğini değiştirip localStorage‘a kaydediyor |
| Görünüm (CSS) | assets/style.css içinde .theme-toggle, .theme-toggle-track, .theme-toggle-thumb, .theme-toggle-icon, .theme-toggle-label sınıfları |
| Mobil davranış | 640px altında metin etiketi gizleniyor, sadece anahtar+ikonlar kalıyor (bkz. style.css‘teki @media bloğu) |
| Giscus (yorumlar) senkronizasyonu | _layouts/default.html‘deki aynı script bloğunda bir MutationObserver — data-theme her değiştiğinde, o an DOM’da bir giscus yorum kutusu varsa ona postMessage ile “temanı değiştir” mesajı gönderiyor. Giscus’un iframe’i geç yüklendiği (data-loading="lazy", kullanıcı yorumlara kaydırana kadar açılmıyor) için bunu tek seferlik değil, sürekli izleyerek yapıyoruz. |
💬 Yorumlar (Giscus)
| Dosya | Ne işe yarar |
|---|---|
_includes/comments.html |
Giscus widget’ını yükleyen kod. site.giscus.* ayarları _config.yml‘den geliyor (bkz. bölüm 1). |
assets/style.css içinde #giscus-container / iframe.giscus-frame |
Yorum kutusunun tam genişlik kullanmasını sağlayan kurallar. Kutu daralmış/küçülmüş görünürse önce burayı kontrol et. |
| Tema senkronizasyonu | Yukarıdaki “Tema Anahtarı” bölümüne bak — giscus’un koyu/açık modu sitenin temasıyla senkron kalması bu mekanizmaya bağlı. |
Giscus’un kendi ayarları (repo, kategori, tema rengi vb.) giscus.app
üzerinden alınıp _config.yml‘e yapıştırılıyor — orta bir değişiklik
yapmak istersen (örn. tepki emojilerini kapatmak) giscus.app’te yeni
ayarı oluşturup _includes/comments.html içindeki ilgili
data-* satırını güncellemen yeterli.
🗂️ İzlediklerim / Okuduklarım Tablosu
| Dosya | Ne işe yarar |
|---|---|
assets/js/koleksiyon-tablo.js |
GitHub Projects verisini Worker’dan çekip tabloyu (arama, tür filtresi, sayfalama dahil) oluşturan ortak kod. Hem icerik/izlediklerim.md hem icerik/okuduklarim.md bunu kullanıyor. |
icerik/izlediklerim.md, icerik/okuduklarim.md |
Sayfanın kendisi — koleksiyonTablosuOlustur({...}) çağrısındaki dataUrl, containerId gibi parametreler hangi projeye (?project=izleme / ?project=okuma) bağlanacağını belirliyor. |
| Sütun sırası/gizlenen sütunlar | Bkz. yukarıdaki bölüm 5 (cloudflare-worker/worker.js) — tablonun kendisi değil, worker’ın döndürdüğü veri bu sırayı belirliyor. |
👤 Header’daki “Hesabım” Menüsü
| Dosya | Ne işe yarar |
|---|---|
_layouts/default.html içinde #auth-nav |
Nav’daki tek kapsayıcı — JS yüklenmeden önce görünen statik “Giriş Yap” linkini içerir (progressive enhancement / no-JS yedeği). |
assets/js/nav-auth.js |
Sayfa açılışında oturumu kontrol edip #auth-nav‘ın içeriğini dolduran script. Çıkış yapmışken tek bir “Giriş Yap” linki, giriş yapmışken “Hesabım ▾” açılır menüsü (Panelim, adminse Admin Paneli ve GitHub İçerik Yönetimi, Çıkış Yap) gösterir. Başka bir sekmede oturum açılıp kapandığında onAuthStateChange ile kendini günceller. |
assets/style.css içinde .auth-nav* sınıfları |
Açılır menünün görünümü — mevcut nav a stiliyle aynı renk değişkenlerini kullanır, açık/koyu temayla otomatik uyumludur. |
Bu menü, sitenin Supabase kullanıcı sistemine bağlıdır — bkz. aşağıdaki “🔐 Supabase Kullanıcı Sistemi” bölümü. O sistemi tamamen kaldırırsan (bkz. “Bölüm 3 — Silme” altındaki “Supabase kullanıcı sistemini kaldırmak istersen”), bu menüyü de kaldırman gerekir.
🔒 Güvenlik Notları (bilmen faydalı olur)
- CSP (
_layouts/default.html,<meta http-equiv="Content-Security-Policy">): sayfanın hangi domain’lerden script/frame/bağlantı yükleyebileceğini sınırlıyor. Yeni bir üçüncü parti servis (örn. yeni bir embed) eklersen ve site “kırık” görünürse, önce burada o servisin domain’ininconnect-src/frame-src/script-src‘e eklenmesi gerekip gerekmediğine bak. guvenliLinkfonksiyonu (assets/js/koleksiyon-tablo.jsveicerik/blog.mdiçinde, aynı isimle iki ayrı yerde) — GitHub/RSS’ten gelen linklerinhttp(s)://ile başladığını ve içinde boşluk/kontrol karakteri olmadığını doğruluyor, öyle değilse linki#‘e çeviriyor.escapeHtmlfonksiyonu — tabloya/listeye basılan her metin (başlıklar, alan adları) HTML’e yazılmadan önce buradan geçiyor, bu yüzden GitHub tarafında biri kötü niyetli bir field adı/değeri girse bile sitede çalışan koda dönüşemiyor.- Substack RSS’i (
icerik/blog.md) üçüncü parti bir proxy’den (api.allorigins.win) geçiyor çünkü tarayıcılar farklı bir domain’den ham RSS çekmeye (CORS) izin vermiyor. Bu servis kontrolün dışında — ileride kendi Worker’ın üzerinden proxy’lemek istersen (daha güvenli ama kurulumu daha uzun), ayrı bir adım olarak yapılabilir.
📖 Site Rehberi · 🔐 Supabase Sistemi · 🍴 Fork Kurulumu