"Make" kullanarak statik site oluşturucu (2022)
(karl.berlin)- Statik siteler barındırması kolay, hızlı ve bakımı az olduğu için, basit bir siteyi ayrı bir oluşturucu öğrenmeden birkaç satırlık Makefile ile yapmak yeterli olabilir
- Temel yapı,
sourceiçindeki dosya düzenini koruyup HTML dosyalarınaheader.htmleklemek, diğer dosyaları isebuildiçine olduğu gibi kopyalamak üzerine kurulu make build,find source -type fvepatsubstile girdi·çıktı dosyalarını eşleştirir;.htmlve diğer dosyalara farklı make kuralları uygular- Geçerli sayfayı vurgulama, Markdown dönüşümü, yerel sunucu, değişiklik algılayıp yeniden derleme ve GitHub Pages dağıtımı gerektiğinde ek hedefler olarak eklenebilir
- Bağımlılıkları az ve değiştirilecek yerleri net olduğu için, gereksinimleri küçük sitelerde genel amaçlı oluşturuculardan ziyade kendi yaptığınız derleme akışı daha hızlı olabilir
Yalnızca Makefile ile temel bir statik site yapmak
- Statik site oluşturucularının çıktısı barındırması kolaydır, hızlıdır ve bakım yükü çok küçüktür
- Basit bir site için mevcut site oluşturucuları öğrenip onlara uyum sağlamaktansa doğrudan betik yazmak daha hızlı ve tatmin edici olabilir
- Otomatik güncellenen zaman damgaları veya RSS akışı olmayan sıradan bir site için, blog betiklerinden daha basit bir yapı yeterlidir
-
Temel gereksinimler
- Tüm girdi dosyalarını
sourcedizinine koyun ve çıktıda da aynı dizin yapısını koruyun - Tüm HTML dosyalarının başına
header.htmlekleyin - HTML olmayan dosyaları değişiklik yapmadan
builddizinine kopyalayın
- Tüm girdi dosyalarını
-
Makefile kuralları
buildhedefi,sourcealtındaki tüm dosyalarıbuildaltındaki çıktı dosyalarına eşleyen bağımlılıklara sahiptir- Kendi başına iş yapmaz, ancak her dosyaya uygun kuralın uygulanması için giriş noktası görevi görür
build/%.htmlkuralısource/%.html,header.htmlveMakefiledosyalarına bağımlıdırmkdir -p $(dir $@)ile çıktı dizinini oluşturur,cat header.html $< > $@ile başlık dosyasını ve girdi HTML’ini birleştirip çıktı üretirbuild/%kuralı, HTML olmayan dosyalarıcp $< $@ile olduğu gibi kopyalar- Bu
header.htmlve kurallar olduğu sürecemake buildçalıştırıldığında, yerelde açılabilecek veya bir web sunucusuna yüklenebilecek birbuilddizini oluşur
Genişletme örnekleri ve yardımcı hedefler
-
Geçerli sayfayı gösterme
- Gezinmede geçerli sayfayı vurgulamak, ziyaretçinin site içindeki konumunu bir bakışta görmesini sağlar
- Örnekte gezinme bağlantısı bulunup
currentsınıfı eklenir sed -E 's|(href="$(subst source,,$<))|class="current" \1|' header.html | cat - $< > $@- Gerçek değiştirme yöntemi, kullandığınız işaretleme yapısına göre değişmelidir
-
Markdown’dan HTML üretme
- HTML’i doğrudan yazmak istemiyorsanız veya mevcut içerik Markdown biçimindeyse bir Markdown-to-HTML dönüştürücüsünü pipe ile bağlayabilirsiniz
- Örnekte smu kullanılır
smu $< | cat header.html - > $@- Varsayılan kural hâlâ
build/foo.htmldosyasınınsource/foo.htmldosyasından üretildiğini varsayar - Markdown dosyalarında da
.htmlsonekini korumalı veya girdi olarak.mddosyalarını bulacak şekilde kuralları değiştirmelisiniz
-
Yerel önizleme
- Bazı sitelerde yerel dosyayı tarayıcıda doğrudan açınca doğru önizleme yapmak zordur; yaygın nedenlerden biri göreli bağlantılar yerine mutlak bağlantılar kullanılmasıdır
- Python birçok sistemde zaten kurulu gelir ve bu kullanım için uygun bir web sunucusu içerir
servehedefi:python -m http.server -d build
-
Değişiklikte otomatik yeniden derleme
- Site üzerinde çalışırken her seferinde elle yeniden derlemek zahmetlidir
entrkullanırsanızsource,header.htmlveMakefiledeğiştiğinde otomatik olarakmake buildçalıştırabilirsinizwatchhedefi:find source header.html Makefile | entr make build- Bağımlılıktan kaçınmak isterseniz
inotifywaitde kullanabilirsiniz
-
GitHub Pages dağıtımı
- GitHub’da bir deponuz varsa sonuç HTML’ini GitHub Pages ile barındırmak doğal bir seçenektir
- git ayrıntılarıyla uğraşmamak için dağıtım komutunu ayarlamak biraz zahmetli olabilir, ancak
git worktreeile çözülebilir - Yöntem Sangsoo Nam’ın yazısına dayanır
gh-pagesdalınıpublic_htmlçalışma ağacı olarak ekleyinbuild/*dosyalarınıpublic_htmliçine kopyalayıngit add --all,git commit -m "Deploy to github pages",git push origin gh-pageskomutlarını çalıştırın- Son olarak
git worktree remove public_htmlile çalışma ağacını kaldırın
-
Gerçek örnek
- Bu yaklaşımla yapılmış bir sayfayı karlb/astridbartel.de üzerinde görebilirsiniz
- Tam bir statik site oluşturucu Makefile’ın altı satırıyla başlayabilir; alışılmadık bağımlılıklar veya bakım yükü olmadan ihtiyaca göre hızla değiştirilebilir
1 yorum
Hacker News yorumları
Daha sonra haberler ve RSS akışı, araştırma makaleleri ve ders materyallerinin otomatik listeleri, etiketlere göre filtrelenebilen kitap listesi gibi özellikler ekledi. Hâlâ Makefile kullanıyor ama Makefile’ın kendisi aksine biraz daha basitleşti; bunun yerine HTML’i satır satır işlemek için harika xml2 ve 2xml yardımcı araçlarını kullanan Bash betiklerini çağırıyor. Ağırlıklı olarak
grepvesedgibi temel yardımcı araçlardan yararlanıyor.Buna, gerektiğinde otomatik olarak
makeçağıran birkaç git hook’u da ekledi; özellikle web sitesinin barındırıldığı uzak sunucuda, depoya push yapıldığında herkese açık sürüm yeniden derleniyor.Yıllardır çok iyi çalışıyor ve git geçmişi 2009’a kadar gidiyor. İlk commit’lere bakınca
beccad7 (FIRST_VERSION) Initial commit,d1cc6d7 adding link to Google Reader shared items,6ccfd0c fix typo,d337959 adding link to Identi.ca accountgörünüyor; gerçekten 15 yıl geçmiş.xml2ve2xmlyardımcı araçları biraz terk edilmiş proje gibi görünüyor.https://github.com/cryptorick/xml2
https://manpages.debian.org/unstable/xml2/2xml.1.en.html
source/içinden bir dosyayı silseniz bilebuild/içinden silinmemesi.Kendi projelerimde tüm siteyi yeniden derlemek yeterince hızlı olduğundan, yeniden derlemeden önce build klasörünün tamamını silmeyi tercih ediyorum.
https://github.com/jez/jez.github.io/blob/source/Makefile#L1...
Bu, bir derleme sistemi kullanmanın büyük nedenlerinden biri olan artımlı derlemeyi büyük ölçüde etkisiz bırakıyor; yine de yeniden oluşturmak istediğiniz sayfayı biliyorsanız doğrudan yalnızca o dosya için
makeçalıştırabilirsiniz.Makefile’da bu tür bir desen için yaygın bir geçici çözüm varsa bilmek isterim.
GNU Make’in
shellfonksiyonuyla dosyaları listeliyor,filter-outfonksiyonuyla “beklenen” çıktıları ayıklıyorum. Çirkin bir hack ama komutushellfonksiyonu üzerinden değişken genişletmesinin bir parçası olarak çalıştırıp her seferinde çalışmasını garanti ediyor.Makefile bağlantısı: https://github.com/jaredkrinke/make-blog/blob/main/Makefile
make cleangibi nükleer seçeneklerin yanı sıra, silme ve ad değiştirme için özel Make hedefleri (target) koyabilirsiniz. Örneğinmake rm sourcefileveyamake mv sourcefile newsourcefilekomutlarının hem kaynak hem de üretilen hedefin silinmesini/adının değiştirilmesini birlikte işlemesini sağlamak gibi.Aslında oldukça büyük bloglarda veya çevrimiçi projelerde bile
make clean/make alldöngüsü genelde yeterince hızlıdır ve şablonları ya da site tasarım öğelerini düzeltirken sıkça gerekir. Yeniden derleme süresi dert olacak kadar büyük bir ölçekse, kaynakları veritabanında yöneten ve istemci eriştiğinde dinamik olarak oluşturan gerçek bir CMS kullanmak daha doğru olabilir.make cleanyeterli olmaz mı?rm/%.html:@rm -f source/%.html build/%.htmlÇalıştırmak için
$ make rm/page.htmldenir.pruneözelliği var.http://neilmitchell.blogspot.com/2015/04/cleaning-stale-file...
Ama
makeile de işe yarayan en iyi çözümün, çıktının nihai.tar.gzarşivini oluşturan birmake disthedefi eklemek olduğunu düşünüyorum. Kurallar doğru yazılırsa içine eski dosyalar girmez. Büyük projelerde yavaş olabilir, ama geliştirme sırasında zaten kullanmanız gerekmez; yalnızca yayın sırasında kullanırsınız. Artımlı derleme hâlâ mümkün olur, sadece son.tar.gzbaştan oluşturulur.blog.shshell betiği çalışmasından doğrudan ilham aldım.Onu alıp elden geçirerek kendi minimal statik site üreticim olan
barfı yaptım. Karl harika çalışmasını yayımlamamış olsaydı bu da var olmazdı.[0]: https://github.com/karlb/karl.berlin/blob/master/blog.sh
[1]: https://barf.bt.ht
shitediyorum ve sitemi onunla oluşturuyorum. Adı, yazılım kalitesine gönderme yapıyor :)En sevdiğim yanı, şimdiye kadar hiçbir şeyi yükseltmem gerekmemiş olması ve bundan sonra da gerekecek gibi görünmemesi. Bir sonraki güzel yanı ise JavaScript olmadan hot reload yapabilmesi.
[1] https://github.com/adityaathalye/shite
[2] https://evalapply.org
m4karıştırırsanız aynı iskelet yaklaşımı koruyup biraz daha esneklik elde edebilirsiniz.Yaklaşık 20 yıl önce böyle bir yöntemle yapılmış küçük bir web sitesini bakımını üstlenmiştim. Ama kişisel web siteleri dışında bu modelin günümüzde ne kadar uyacağını bilmiyorum. Çünkü bu yöntem özünde Web 1.0 rolünü dayatıyor. Katkıda bulunan tüm kullanıcıların HTML’e hâkim olması gerekiyor ya da birinin “webmaster” angaryasını üstlenmesi gerekiyor
[1] https://en.wikipedia.org/wiki/M4_(computer_language)
m4” diye bir şey yokturTemiz bir projeye başlar ve bu kez
m4ye dokunmayacağına yemin edersin. Sonra tekrar eden kodu azaltmak için küçük birm4çağrısı eklersinBir yıl sonra web sitesinde “cat” kelimesinin neden sessizce kaybolduğunu bulmak için 5 kat makro genişletmesini deşersin ve sonunda junior geliştiricinin for döngüsünü kılavuzdan kopyalamayıp kendi yazmaya çalışırken tırnakları bozduğunu keşfedersin
O anki sorunu çözdükten sonra DSL hata ayıklamasının çok zor olduğuna karar verip her projeye kopyalayıp durduğun M4 makro dosyasını getirirsin. Ardından çıktıya yorum ekleyip stack trace üreten betiğin çalışmasını sağlayan makro üreten makrolarla tüm
definekullanımlarını değiştirmek için bir gün harcarsınBir sonraki projede kesin bir kural koyacaksın.
m4yasak! Tabii belki o tek yer için bir istisna olabilirm4ya daperlgibi genel metin ikamesine bel bağlamak yerine, HTML ve XML’in temeli ve ortak üst kümesi olan SGML kullanmayı öneririmSGML, kolay tip denetimli metin makrolarını, yani entity genişletmeyi yerleşik olarak sunar; ayrıca tipi bilen parametreli makro genişletmesi de mümkündür. Buradaki tip, işaretleme öğesinin genel içerik tipi, yani izin verilen alt öğeler ve sıraları anlamına gelir; öznitelik, CDATA, RCDATA gibi bağlamlara genişletme ya da escape etme de hesaba katılır
Potansiyel olarak kötü niyetli kullanıcı yorumlarını uygun şekilde genişletip escape ederken, örneğin satır içi düzeyde işaretlemeye izin verip
scriptöğesini yasaklayan kullanıcı kurallarını uygulama işini ancak SGML düzgün biçimde yapabilir. Markdown ya da wiki sözdizimini HTML’e genişletmek, dış/sindikasyon HTML içeriklerini içeri almak, RSS ve gezinme için outline oluşturmak gibi işler de mümkündür. Komut satırında epey karmaşık statik site hazırlama işleri için uygundur[1]: https://sgmljs.net/docs/producing-html-tutorial/producing-ht...
[2]: https://sgmljs.net/docs/sgmlproc-manual.html
m4ya dasedile bul-değiştir yerineenvsubstdenemen iyi olabilirBash tarzı değişken başvurularını, örneğin
$TITLEı ortam değişkeni değeriyle değiştiren bir programdırexport CURRENT="..."cat page.html | envsubtm4” mü, lütfen kesinlikle hayırm4, obfuscated programming dili olarak bile pek iyi değilsendmail’de çalışmış olması tek başına herhangi bir şeyi meşrulaştırmaya yetmez
Burada ilginç bir yazı okuduğum her seferinde feed’e abone oluyorum. Wordpress sitesi olsun, Bear Blog olsun, Micro.blog olsun, Havenweb blogu olsun, elde yapılmış bir sitenin feed’i olsun, Hey Homepage’in
Really Social Sitesmodülüne ekliyorumNihayetinde Kagi’nin Small Web girişiminde yaptığı gibi bu blog listesini herkese açmak istiyorum. Ancak kalite katmak için kürasyon kilit unsur ve kürasyonu düşününce bir tür çevrimiçi dergi başlatmak doğal görünüyor
İnsanlar başkalarıyla paylaşmaya hakları olduğu yönündeki, iyi anlamda “hak görme” duygusunu nereden alıyor? Başkalarının benim üzerinde çalıştığım şeylerle ilgileneceğini neden varsaydıklarını merak ediyorum. Bazen rekabet gibi geliyor. “Blogda beğeni ya da görünürlük almak için olabildiğince havalı bir şey yapmalısın” gibi
İşbirliği elbette iyi ve bunun mümkün olması için her şeyin açık olması gerekiyor. Ama “havalı göründüğü için bunu yapıyorum” ile “tepki almak için bunu başkalarıyla paylaşmaya çalışıyorum” arasındaki sınırı pek bilmiyorum
Tek bir test dosyasını değiştirsen bile tek bir komutla testleri çalıştırma ve grafik üretme dahil tüm makaleyi yeniden üretebildiğini söylemişti
https://pages.github.com/
Benimki JavaScript’siz hot reload istediğim için biraz fazla tasarlandı ve keyifli bir yak shaving oldu
Temel fikir aynı. Şablonlarda heredoc kullanıyorum, düz metni HTML’e çeviren bir derleyici kullanıyorum; benim durumumda bu
pandoc. İndeks üretimi için ara CSV kullanıyorum ve front matter’ı çıkarmaya yarayan kullanışlı birsedtekniği de var. Klasik ve güzel[1] https://github.com/karlb/karl.berlin/blob/master/blog.sh
[2] https://github.com/adityaathalye/shite
[3] Benim yöntemim: https://github.com/adityaathalye/shite/blob/master/bin/templ...
Ancak bazı sınırlamaları var. Ben yazıları namespace’lere göre düzenliyorum ve URL’ye tarih koyuyorum;
makebunu doğrudan pek iyi işleyemiyormake’in avantajı, yavaş bir derleyiciyle derlenen büyük programlarda küçük değişiklikler olduğunda artımlı yeniden derlemeyi çok daha hızlı hale getirmesiTam yeniden derlemesi 40 dakika sürecek bir iş yaklaşık 3 saniyede bitebilir
Statik bir site, ortak bir header ile birkaç yüz HTML dosyasını
catetmekten ibaretse ve baştan 1 saniyenin altında oluşturulabiliyorsa, betik yerinemakekullanmanın bir avantajı yoktur. Sadece bağımlılık hataları yüzünden eksik bir build yapma riski doğar.phonyolarak işaretlemek yeterlidirYine de
make buildilemake pushgibi ayrımlara sahip olabilirsinizBaşka küçük projelerde geçici bir bundler olarak çok küçük bir shell betiği kullandım. CSS ve JS’yi HTML’nin içine gömüyordu; amaç, build edilmemiş dosyaların da yerelde sunulabilmesini sağlamaktı