HTML neden tek başına 'include' işlevini destekleyemiyor?
(frontendmasters.com)- Aynı header’ı birden çok sayfada tekrarlamama ihtiyacı temel bir gereksinim olsa da HTML’de bunu doğrudan ele alan yerel bir include etiketi yok
- Geliştiriciler aynı sorunu JavaScript
fetch, sunucu yönergeleri, statik site oluşturucular, şablon dilleri, backend dilleri ve Web Components gibi dolaylı çözümlerle çözüyor <iframe>saf HTML’e yakın bir yöntem olsa da performans, erişilebilirlik ve kullanılabilirlik açısından bu kullanım için uygun değil ve genel olarak eğreti duruyor- CSS, CSS’i import edebiliyor; JavaScript, JavaScript’i import edebiliyor. HTML’in HTML’i import edememesi ise web platformunun tutarlılığını zedeliyor gibi görünüyor
- preload scanner etkisi, asenkron yüklemenin neden olduğu layout kaymaları, iç içe/döngüsel include’lar, istek sayısının artması, domain kısıtları ve talep eksikliği gibi konular standardizasyon engelleri olarak duruyor
Tekrarlanan HTML parçalarını yeniden kullanmaya yönelik temel ihtiyaç
index.html,about.html,contact.htmladlı üç sayfaya aynı header’ı koymak gerektiğinde sorun ortaya çıkıyor- Aynı kodu üç kez kopyalamak yerine header’ı bir kez oluşturup birden fazla sayfada include etmek istemek doğal
- Sayfa sayısı binlere çıktığında bu, basit bir kolaylık değil kod tekrarını önleme meselesi hâline geliyor
Hâlihazırda var olan çeşitli çözümler
- HTML parçalarını alıp yerleştirme yöntemi zaten pek çok araç ve katmanda mümkün
- JavaScript, HTML’i
fetchile alıpinsertAdjacentElementile ekleyebilir - Eski bir web sunucusu yönergesi olan Server Side Includes da var
- Jekyll include gibi statik site oluşturucu özellikleriyle çözülebilir
- gulp-include gibi task runner’lar da kullanılabilir
- Handlebars partials gibi şablon dilleri genellikle include işlevi sunar
- PHP’nin
includefonksiyonunda olduğu gibi backend dilleri HTML’i dinamik olarak üretebilir - Include’a özel Web Component yaklaşımları da mevcut
- JavaScript, HTML’i
<iframe>teknik olarak yalnızca saf HTML ile başka bir HTML’i getirmenin bir yolu olsa da bu kullanımda performans, erişilebilirlik ve kullanılabilirlik sorunları büyük- Güçlü bul/değiştir özelliklerine güvenip include kullanmamayı seçmek de bir seçenek
Ama HTML’in kendisinde yok
- Yukarıdaki yöntemlerin hiçbiri “tek bir HTML etiketiyle HTML’i getir ve bu konuma yerleştir” yaklaşımı değil
<img>etiketinin bir görseli alıp ilgili konuma koyması gibi, HTML’de “bu HTML’i al ve buraya koy” diyen doğrudan deklaratif bir etiket yok- ShopTalk Show’da da Jake Archibald ve Dave Rupert benzer sorular etrafında tartışmayı sürdürdü
Web platformunun mevcut gidişatıyla çelişen nokta
- Web standartları ve tarayıcılar çoğu zaman geliştiricilerin tekrar tekrar çözdüğü işleri platform özelliği olarak bünyesine katıyor
- Tarih işlemleri için üçüncü taraf JavaScript kullanımının yaygın olduğu akışta Temporal ortaya çıktı
- Framework’lerle ele alınan sayfa geçişi ihtiyacına View Transition API yanıt verdi
- Öğeleri güvenli şekilde konumlandırmak için kullanılan kütüphanelerin alanına CSS anchor positioning girdi
- Neredeyse tüm web sitelerinin HTML parçalarını yeniden kullanmaya ihtiyaç duyduğu ve herkesin farklı standart dışı araçlar kullandığı bir ortamda, HTML include’un yokluğu olağandışı bir boşluk gibi görünüyor
HTML include’un standart hâline gelmesinin zor olmasının nedenleri
- Tarayıcılar ve ekosistem açısından HTML include çeşitli yükler getiriyor
- preload scanner’ı bozarak web performansını olumsuz etkileyebilir
- Asenkron olmak zorundaysa yükleme sırasında ekranda kayma veya zıplama hissi oluşabilir
- HTML’in sadeliğini ya da saflığını zedeleyen bir karmaşıklık doğurabilir
- İç içe include’ları ve döngüsel include’ları ele almak zor olabilir
- Web hosting şirketleri istek sayısının artmasını gerekçe göstererek karşı çıkabilir
- Görsel, CSS ve JavaScript’ten farklı olarak HTML’in başka domain’lerden alınırken daha sıkı kısıtlara ihtiyaç duyması mümkün
- Bu listede yer almayan başka sorunlar olabilir
- Aslında bu özelliğe yönelik talep o kadar büyük olmayabilir
- Kesin bir yanıttan çok, HTML’in neden HTML’i doğrudan include edemediğini irdeleyen bir neden arayışı niteliğinde
1 yorum
Hacker News görüşleri
HTML tarihsel olarak SGML’in bir uygulamasıydı ve SGML’de include mümkündü.
Yeni bir “entity” tanımlanabiliyor, “system” entity oluşturulduğunda daha sonra referans verilerek yerine konması sağlanabiliyordu. SGML karmaşık olduğu için HTML’i basitleştirmeye yönelik çeşitli girişimler oldu ve bu süreçte bu özellik de çıkarıldı.
İlgili etiket başka HTML sayfalarını dahil ediyor veya embed ediyormuş gibi görünüyor. Embed edilen HTML sayfası: https://www.w3schools.com/tags/tag_object.asp
https://en.wikipedia.org/wiki/Billion_laughs_attack
90’ların sonunda içine düştüğüm bir tavşan deliğiydi ve hâlâ çıkabilmiş değilim.
Analog Science Fiction web sitesinin webmaster’ıydım; aynı header ve sidebar’a sahip bir sürü statik sayfa oluşturmak zorunda kalınca delirme noktasına gelmiştim. Araştırırken Apache server-side include’larını keşfettim ve DRY terimini öğrenmeden önce bile DRY bir yapı kurabildim. iframe’in yeterli olduğu söyleniyor ama yeterli değil. iframe içerik boyutuna göre genişleyip uzamıyor, sunucu tarafı çözümler ise sunucu gerektiriyor. Neden basit bir istemci tarafı yöntemin olmaması gerektiğini bilmiyorum; web geliştirmedeki pek çok can sıkıcı şeyi düzelttiğimiz şu dönemde düşünmeye değer bir soru.
90’ların ortasında bir arkadaşla “web işleri” yapmaya başladığımızda DRY kavramı zaten doğal olarak anlaşılır gelmişti. O dönemde çevirmeli bağlantı ISP’miz kullanıcı web alanında
.htaccesskullanımını engellemediği için server-side include’ları açabiliyorduk; daha sonra CGI’yi de nasıl açacağımızı bulduk. Web sunucusu kutusunu keşfetmek için Perl ile ilkel bir web shell bile yazmıştım.Statik HTML’e dinamik import gibi temel bir özelliği ekleyen 10 KB’lık küçük bir kütüphane.
https://caniuse.com/iframe-seamless
Frame’lerde beni hep rahatsız eden şey, fazla akıllı davranmalarıydı. Sağ tıklayıp yenile dediğimde yalnızca frame HTML’inin yeniden yüklenmesini istemiyordum. Ayrı ayrı cache’leme niyetini anlıyorum ama frame’ler ve cache farklı sorunları çözmeli; ikisini karıştırınca ikisi de muğlaklaştı. Bence HTML include mümkün olduğunca aptalca çalışmalı. Include konumuna include metnini yapıştırıp tarayıcının ortaya çıkan metni alması yeterli. Her sayfadaki aynı navigasyonu ayrıca cache’lemek istiyorsanız bir cache özelliği ekleyip o sorunu bağımsız çözebilirsiniz. Include’un daha fazlasını yapması gerektiğine beni ikna edebilirsiniz, ama aptalca davranış bir hata değil, bir özelliktir.
Bu özellik önerisinin adı HTML Imports idi ve Web Components çalışmalarının parçası olarak oluşturuldu.
“HTML Imports are a way to include and reuse HTML documents in other HTML documents” şeklinde bir açıklaması vardı; plan belgesi https://www.w3.org/TR/html-imports/ adresinde.
Ancak bu gerekçeler, gerçekte hiçbir şeyi açıklamayan gerekçe olmayan şeylere yakın. Bu özellik 20 yıl boyunca sürekli istendi ve script’lerle ya da backend engine’lerle yapılmış türlü shim uygulamaları var; talebin düşük olduğuna inanmak zor. Vendor reddi de, halihazırda var olan implementasyonu bile geri alacak kadar neden reddedildiğini açıklamıyor. “Güvenlik etkileri” de tuhaf; çünkü zaten script etiketiyle cross-origin HTML getirip
document.write()yapılabiliyor. Script’indocument.write()yapması sorun değilken aynı işi yapan bir HTML etiketinin neden büyük sorun olduğunu merak ediyorum. Google ana sayfasını anında klonlamak gibi şeylerin engellenmesi gerektiğine dair güvenlik kaygısını anlıyorum, ama bu CORS ile kolayca çözülebilir gibi görünüyor.[1] https://frontendmasters.com/blog/seeking-an-answer-why-cant-...
HTML’in belgenin belirli bir konumuna import edilip gösterilmesi gerekiyor; HTML Imports ise JavaScript olmadan bunu yapamıyordu. Ayrıntılar için bkz. https://github.com/whatwg/html/issues/2791#issuecomment-3112...
Hatırladığım kadarıyla import ettikten sonra template’i JavaScript ile örneklemek gerekiyordu; sadece basit tek bir etiketle çalışan bir yöntem değildi.
Netscape 4’te bu özellik inflow layer olarak vardı
https://web.archive.org/web/19970630074729fw_/http://develop...
https://web.archive.org/web/19970630094813fw_/http://develop...
SRCözniteliğini değiştirme davranışı oldukça kolay çöküyordu ve özellik de kısa süre sonra kaldırıldıBetada kurcaladığımı hatırlıyorum, ama kararlı sürümde kaybolmuştu
Bu özelliğin adı transclusion
https://en.wikipedia.org/wiki/Transclusion
Project Xanadu’nun bir parçasıydı ve başlangıçta hipermetnin önemli bir özelliği olarak görülüyordu. Özellikle MediaWiki transclusion’ı kapsamlı biçimde kullanır; bazen wiki’ler hipermetnin en saf biçimiymiş gibi geliyor
https://en.wikipedia.org/wiki/Federated_Wiki
Ama tam anlamıyla tutmadı
Xanadu’da bir belgenin yalnızca belirli bir alıntı bölümü başka bir belgeye transclude edilebiliyordu. Bunu HTML’de yapmak için CSS’e dair bir yanıta ihtiyaç var. Belirli durumlarda, ana belge, konuk belge ve ana belgenin içine gömülü konuk arasında hangi özelliklerin tutarlı tutulacağına karar verip çözüm üretilebilir; ancak genel durumda bu belirsizdir. Basit bir etiket yaklaşımında, konuk belgenin ana belgenin sağladığı CSS ortamı içinde yaşayacak şekilde tasarlanması gerekir. Bir başka basit yanıt da Shadow DOM’dur; genel olarak konuğun belgenin geri kalanını etkilemeden kendi stilini uygulamasını sağlar. Bu durumda bile ana belgenin konuğu düzeltmek için bazı stiller ekleyebileceğini düşünüyorum
Uzun zaman önce düzgün bir frameset’in yapmaya çalıştığı şey bu değil miydi diye düşünüyorum. iframe değil, HTML 4 dönemindeki frameset’ten bahsediyorum
En azından otomatik boyut büyütme iyi çalışıyordu ve kullanıcı da istediği boyuta ayarlayabiliyordu. Frame’lere yönelik çok eleştiri vardı [1], ama Java API belgeleri [2] gibi yararlı yerlerde başarıyla kullanıldı. Sonunda ortadan kalkmasının nedeninin tasarımcılar için fazla esneklikten yoksun olması olduğunu düşünüyorum. Bilgi sayfaları için yeterliydi, ama kaba kaydırma çubukları ve sınırlı ekran bölme seçenekleri tasarımcıların ihtiyaçlarını karşılamıyordu. Bugün mobilde olduğu hâliyle frameset iyi çalışmayacağı için onu geri getirmek için çok geç
[1] <https://www.nngroup.com/articles/why-frames-suck-most-of-the...> - Buradaki içeriğin büyük bölümünün artık geçerli olmaması ve frame’lerde işaret edilen tüm sorunların günümüz web’inde daha da dağınık biçimlerde var olması ilginç
[2] <https://www.eeng.dcu.ie/~ee553/ee402notes/html/figures/JavaD...>
Derin bağlantı mümkün değildi; bu yüzden yer imlerinden, Google’dan ya da ondan önceki arama motorlarından gelen kişiler gezinme olmayan bir sayfaya düşüyordu. Bunu JavaScript ile aşmaya çalıştılar, ama iyi bir deneyim yaratmadı
“include” işlevinin sunucu tarafında, yani web tarayıcısının dışında işlendiği kabul edilir
HTML istemci tarafındadır ve aslında bir programlama dili değil, bir işaretleme söz dizimidir. Yazıda söylendiği gibi bu sorun zaten çözülmüş bir sorundur. Web tasarımı öğrencilerinin PHP öğrenirken ilk karşılaştığı şey include’dur; çoğu CMS’te de include, template partial hâline gelir ve belgenin başlarında açıklanır. Yalnızca HTML ile include’u mümkün kılmaya pek gerek yoktur. HTML bir ifade biçimidir; CSS ve JS olmadan ilginç şeyler yapmaz
Aslında HTML’de bunun daha kötü sürümleri olan frames ve iframes zaten var. Server-side include’un istemci tarafındaki karşılığı, insanların HTML ile yaptığı işlere doğal biçimde uyar
Muhtemelen özel öğelerle kodlanabilir; GitHub’da buna benzer bir depo yoksa asıl buna şaşırırım
Görseller veya ekranın alt kısmındaki içerikler gibi zaten asenkron yüklenen içerikler de var. “HTML programlama dili değil, işaretleme söz dizimidir” sözü flamebait’e yakın; tarayıcı motorları tarafından yorumlanan bildirimsel bir dildir
Stil vermekten bahsediyorsan ifade kısmını CSS üstlenir
İki seçenek var. Birincisi, HTML ayrıştırma zamanında, yani DOM oluşturulmadan önce işlemek; fakat include için sunucuya senkron istek gerektirdiğinden bu istenmez. İkincisi, DOM oluşturulduktan sonra belirli bir öğenin DOM’da görünmesi, parçanın asenkron yüklenmesi ve ardından o DOM öğesinin dış parçayla değiştirilmesidir; bu da mevcut DOM yapısı doğrulama mekanizmasını etkisizleştirir. Yine de Sciter motorunda birinci stratejiyle uygulanmış. Sciter’ın HTML’i genellikle yerel uygulama kaynaklarından veya dosya sisteminden geldiği için ek parça isteğinin maliyeti ihmal edilebilir düzeydedir
https://docs.sciter.com/docs/HTML/html-include
Başkalarının da söylediği gibi HTML include’da çeşitli sorunlar var
main.html,child/include1.htmldosyasını dahil ediyorsa vechild/include1.htmliçindesrc="include2.html"bağlantısı varsa, kullanıcı tıkladığında nereye gitmeli?include2.htmle giderse, adından da anlaşılacağı üzere include için hazırlanmış bir sayfa olduğundan geri kalanı eksik olur;main.htmle giderse bu kezinclude1.htmlyerineinclude2.htmlkullanması gerektiği nasıl belirtilecek? Tersinearticle1.html,article2.html,article3.htmldosyalarının her birineheader.html,footer.html,navi.htmldahil ettirebilirsin; ama o zaman tüm makale yapısını genel olarak değiştirmek için tüm makaleleri düzenlemek gerekir. Tüm makalelerecomments.htmleklemek istersen sonunda sayfaları yeniden bir şablonla üretmek istersin ve o noktada tarayıcı include’una gerek kalmaz. Başlığın sayfa başlığını bilmesi veya altbilginin önceki/sonraki bağlantıları bilmesi gibi sorunlar da ortaya çıkar; include’lar arasında bilgi aktarmanın bir yoluna ihtiyaç duyulur ve sonunda yine sayfa üretimine dönülür. Düşününce HTML include’un çoğu kullanım için pratikte işe yaramama olasılığı yüksektirBurada iki farklı kullanım durumu karışmış durumda. Biri parça yeniden kullanımı, diğeri gömülebilir bağımsız adacık. İkincisini iframe zaten hallediyor; dolayısıyla yalnızca birincisini çözmek yeterli
include2.htmlin geri kalanını kaybettiği include mantığı, diğer include’lara da aynen uygulanırKullanıcı
src="include.css"bağlantısına tıklarsa işler karışır. Statik veri, görsel, CSS ve statik HTML içeriği için uygun olabilirWHATWG’de bununla ilgili açık bir issue var. Blog yazısının yorum bölümünde de bahsedilmiş
HTML için istemci tarafı include özelliği
https://github.com/whatwg/html/issues/2791
HTML’de include vardı ve popülerliğini yitirdi
Asıl “include” terimi bir XML özelliğidir ve yazının istediği de bu işlevdir. HTML’de XML’den önce ortaya çıkan başka bir yaklaşım vardı; o da frames idi. Frames, XML include’dan çok daha fazla şey yaptığı için HTML bu özelliği ayrıca edinmedi. Frames; kötüye kullanım, güvenlik, erişilebilirlik gibi çeşitli sorunlar nedeniyle gözden düştü
Ara sıra kullanmayı hâlâ seviyorum, ama bunu kullanıcıya veya tarayıcıya vermeden önce değerlendiren bir derleme aşaması gerekiyor