- कई पेजों पर एक ही header को दोहराने से बचने की जरूरत बुनियादी है, लेकिन HTML में इसे सीधे संभालने वाला native include tag नहीं है
- डेवलपर्स JavaScript
fetch, server directives, static site generators, template languages, backend languages और Web Components जैसे workarounds से इसी समस्या को हल करते आए हैं <iframe>pure HTML के करीब तरीका है, लेकिन performance, accessibility और usability के लिहाज से इस काम के लिए सही नहीं है और कुल मिलाकर अटपटा लगता है- CSS, CSS को import कर सकता है और JavaScript, JavaScript को import कर सकता है, लेकिन HTML, HTML को import नहीं कर पाता, जिससे web platform की consistency डगमगाती हुई दिखती है
- preload scanner पर असर, async loading से layout में हलचल, nested/circular includes, requests बढ़ना, domain restrictions और demand की कमी जैसी चीजें standardization barriers बनी हुई हैं
दोहराए जाने वाले HTML हिस्सों को reuse करने की बुनियादी जरूरत
index.html,about.html,contact.htmlतीन पेजों में एक ही header डालनी हो, तो समस्या सामने आती है- वही code तीन बार copy करने के बजाय header को एक बार बनाकर कई पेजों में include करना स्वाभाविक लगता है
- जब पेज हजारों में बढ़ जाते हैं, तो यह सिर्फ सुविधा नहीं बल्कि code duplication रोकने की समस्या बन जाती है
पहले से मौजूद तरह-तरह के समाधान
- HTML snippets को लाकर insert करने का काम पहले से कई tools और layers में संभव है
- JavaScript
fetchसे HTML ला सकता है औरinsertAdjacentElementसे insert कर सकता है - पुराने web server directive Server Side Includes भी मौजूद हैं
- Jekyll include जैसे static site generator features से इसे संभाला जा सकता है
- gulp-include जैसे task runner का भी इस्तेमाल किया जा सकता है
- Handlebars partials जैसी template languages आम तौर पर include feature देती हैं
- PHP के
includeकी तरह backend language HTML को dynamically generate कर सकती है - include के लिए dedicated Web Component तरीका भी मौजूद है
- JavaScript
<iframe>तकनीकी रूप से सिर्फ pure HTML से दूसरा HTML लाने का तरीका है, लेकिन इस use case में performance, accessibility और usability की समस्याएं बड़ी हैं- powerful find/replace feature पर भरोसा करके include का इस्तेमाल ही न करने का विकल्प भी है
लेकिन HTML में खुद यह नहीं है
- ऊपर के सभी तरीके “एक HTML tag से HTML लाकर इस जगह डाल दो” वाले तरीके नहीं हैं
- जैसे
<img>image लाकर उसी जगह डाल देता है, HTML में “यह HTML लाकर यहां डालो” कहने वाला सीधा declarative tag नहीं है - ShopTalk Show में भी Jake Archibald और Dave Rupert के साथ इसी सवाल पर चर्चा हुई थी
web platform के मौजूदा रुझान से अलग दिखने वाली बात
- web standards और browsers अक्सर उन कामों को platform feature में शामिल कर लेते हैं जिन्हें developers पहले से बार-बार हल कर रहे होते हैं
- तारीखों को handle करने के लिए third-party JavaScript इस्तेमाल करने के trend में Temporal आया
- frameworks से handle की जाने वाली page transition जरूरतों के लिए View Transition API आया
- elements को सुरक्षित तरीके से position करने के लिए इस्तेमाल होने वाली libraries की जगह CSS anchor positioning आया
- जब लगभग हर website को HTML snippets reuse करने की जरूरत होती है और सब अलग-अलग non-standard tools इस्तेमाल करते हैं, तो HTML include की गैरमौजूदगी असामान्य खाली जगह जैसी दिखती है
HTML include को standard बनाना कठिन क्यों है
- browser और ecosystem के नजरिए से HTML include के साथ कई बोझ आते हैं
- यह preload scanner को बिगाड़कर web performance पर बुरा असर डाल सकता है
- अगर यह async तरीके से होना पड़े, तो loading के दौरान screen में हिलना-डुलना या jumpy experience हो सकता है
- HTML की simplicity या purity को नुकसान पहुंचाने वाली complexity पैदा हो सकती है
- nested includes और circular includes को handle करना मुश्किल हो सकता है
- web hosting providers requests की संख्या बढ़ने के कारण विरोध कर सकते हैं
- images, CSS और JavaScript के उलट, HTML को दूसरे domain से लाने पर ज्यादा सख्त restrictions की जरूरत हो सकती है
- इस सूची में न शामिल अन्य समस्याएं भी हो सकती हैं
- असल में इस feature की demand शायद बहुत बड़ी न हो
- यह पक्के जवाब से ज्यादा, इस बात की वजहों की खोज है कि HTML सीधे HTML को include क्यों नहीं कर पाता
1 टिप्पणियां
Hacker News की रायें
HTML ऐतिहासिक रूप से SGML का एक application था, और SGML में include संभव था
आप नई “entity” define कर सकते थे, और “system” entity बनाने पर उसे बाद में reference करके replace कराया जा सकता था। SGML जटिल था, इसलिए HTML को सरल बनाने की कई कोशिशें हुईं, और उसी प्रक्रिया में यह feature भी निकल गया
वह tag किसी दूसरे HTML page को include या embed करता हुआ लगता है। Embedded HTML page: https://www.w3schools.com/tags/tag_object.asp
https://en.wikipedia.org/wiki/Billion_laughs_attack
90 के दशक के आखिर में यह एक rabbit hole था जिसमें मैं उतरा था, और अभी तक बाहर नहीं निकल पाया हूं
मैं Analog Science Fiction website का webmaster था, और एक जैसे header और sidebar वाले ढेरों static pages बनाते-बनाते पागल होने की हालत थी। जांच-पड़ताल करते हुए Apache server-side include मिला, और DRY शब्द जानने से पहले ही चीजों को DRY बना पाया। कुछ लोग कहते हैं कि iframe काफी है, लेकिन वह काफी नहीं है। iframe content size के हिसाब से expand नहीं होता, और server-side समाधान के लिए server चाहिए। समझ नहीं आता कि कोई simple client-side तरीका क्यों नहीं हो सकता, और अब जब web development की कई परेशानियां ठीक की जा रही हैं, तो यह सवाल विचार करने लायक है
90 के दशक के मध्य में जब मैंने एक दोस्त के साथ “web stuff” बनाना शुरू किया था, तब भी DRY concept सहज रूप से समझ में आ गया था। उस समय dial-up ISP user web space में
.htaccessइस्तेमाल करने से नहीं रोकता था, इसलिए server-side include enable कर सकता था, और बाद में CGI enable करने का तरीका भी पता कर लिया। webserver box को explore करने के लिए Perl में एक शुरुआती-सा web shell तक लिखा थायह 10KB की छोटी library है, जो static HTML में dynamic import जैसी core functionality जोड़ देती है
https://caniuse.com/iframe-seamless
frames में जो चीज हमेशा खटकती थी, वह यह थी कि वे जरूरत से ज्यादा smart बनते थे। right-click करके refresh करने पर मैं सिर्फ frame HTML फिर से load नहीं कराना चाहता था। अलग से cache करने की मंशा समझ में आती है, लेकिन frames और cache को अलग-अलग problems solve करनी चाहिए थीं; दोनों को मिला देने से दोनों ही अस्पष्ट हो गए। मेरे हिसाब से HTML include को जितना संभव हो उतना dumb तरीके से काम करना चाहिए। include वाली जगह पर include text paste हो जाए, और browser को वही resulting text मिल जाए। अगर हर page पर same navigation को अलग से cache करना है, तो cache attributes जोड़कर उस problem को स्वतंत्र रूप से solve किया जा सकता है। कोई यह समझा सकता है कि include को और ज्यादा काम करना चाहिए, लेकिन dumb behavior bug नहीं, feature है
इस feature proposal को HTML Imports कहा जाता था, और यह Web Components work के हिस्से के रूप में बनाया गया था
इसमें “HTML Imports are a way to include and reuse HTML documents in other HTML documents” जैसी description थी, और plan document https://www.w3.org/TR/html-imports/ पर है
लेकिन ये वजहें असल में कुछ भी explain नहीं करतीं; ये लगभग non-reasons हैं। यह feature 20 साल से लगातार request किया जा रहा है, और script या backend engine वगैरह से बने हर तरह के shim implementations मौजूद हैं, तो demand कम है यह मानना मुश्किल है। vendor refusal भी यह नहीं समझाता कि उन्होंने पहले से मौजूद implementation तक वापस क्यों हटा दी। “security impact” भी अजीब है, क्योंकि script tag से cross-origin HTML लाकर
document.write()किया जा सकता है। script काdocument.write()करना ठीक है, तो वही काम करने वाला HTML tag बड़ा issue क्यों बनता है, यह जानना चाहूंगा। Google homepage को तुरंत clone करने जैसी चीजों को रोकना चाहिए—यह security concern समझ आता है, लेकिन लगता है कि इसे CORS से आसानी से solve किया जा सकता है[1] https://frontendmasters.com/blog/seeking-an-answer-why-cant-...
HTML को document की किसी specific जगह पर import होकर दिखना चाहिए, लेकिन HTML Imports JavaScript के बिना यह नहीं कर सकता था। details के लिए https://github.com/whatwg/html/issues/2791#issuecomment-3112... देखें
याद है कि import करने के बाद JavaScript से template instantiate करना पड़ता था, और यह सिर्फ एक simple tag से हो जाने वाला तरीका नहीं था
Netscape 4 में यह फीचर inflow layer के रूप में मौजूद था
https://web.archive.org/web/19970630074729fw_/http://develop...
https://web.archive.org/web/19970630094813fw_/http://develop...
SRCattribute बदलने का व्यवहार काफी आसानी से crash करवा देता था, और फीचर भी जल्द ही हटा दिया गयामुझे याद है कि beta में इससे खेला था, लेकिन official version में यह गायब था
इस फीचर का नाम transclusion है
https://en.wikipedia.org/wiki/Transclusion
यह Project Xanadu का हिस्सा था, और मूल रूप से hypertext की एक अहम capability मानी जाती थी। खासकर MediaWiki transclusion का व्यापक इस्तेमाल करता है, और कभी-कभी wiki hypertext का सबसे शुद्ध रूप जैसा महसूस होता है
https://en.wikipedia.org/wiki/Federated_Wiki
लेकिन यह ठीक से लोकप्रिय नहीं हो पाया
Xanadu में किसी एक document के केवल कुछ excerpts को दूसरे document में transclude किया जा सकता था। HTML में ऐसा करने के लिए CSS को लेकर जवाब चाहिए। कुछ स्थितियों में host document, guest document, और host के अंदर embedded guest के बीच कौन-सी properties consistent रखनी हैं, यह तय करके हल निकाला जा सकता है, लेकिन general case साफ नहीं है। अगर यह कोई simple tag-based तरीका हो, तो guest document को इस तरह design करना होगा कि वह host द्वारा दिए गए CSS environment के अंदर रहे। एक और simple जवाब Shadow DOM है, जो आम तौर पर guest को बाकी document पर असर डाले बिना अपनी styling apply करने देता है। इस स्थिति में भी मुझे लगता है कि host guest को adjust करने के लिए कुछ styles डाल सकता है
मुझे लगता है कि बहुत पहले proper frameset भी यही करने की कोशिश कर रहा था। iframe नहीं, HTML 4 दौर वाला frameset
कम से कम size auto-expand करना ठीक से होता था और user अपनी पसंद के size में adjust भी कर सकता था। frames की काफी आलोचना हुई थी [1], लेकिन Java API documentation [2] जैसी उपयोगी जगहों पर इनका सफल इस्तेमाल हुआ। आखिरकार वे इसलिए गायब हुए क्योंकि designers के लिए flexibility बहुत कम थी। information pages के लिए ये काफी थे, लेकिन भद्दे scrollbars और limited screen splitting designers की जरूरतें पूरी नहीं कर पाए। अब mobile पर वैसा-का-वैसा frameset शायद ठीक से काम नहीं करेगा, इसलिए इसे वापस लाने के लिए बहुत देर हो चुकी है
[1] <https://www.nngroup.com/articles/why-frames-suck-most-of-the...> - दिलचस्प है कि इसमें कही गई कई बातें अब लागू नहीं होतीं, और frames के बारे में बताए गए सभी problems आज के web में और भी ज्यादा messy रूप में मौजूद हैं
[2] <https://www.eeng.dcu.ie/~ee553/ee402notes/html/figures/JavaD...>
deep linking संभव नहीं थी, इसलिए bookmark या Google, या उससे पहले के search engines से आने वाले लोग navigation के बिना page पर पहुंच जाते थे, और इसे JavaScript से workaround करने की कोशिश की गई, लेकिन अच्छा experience नहीं बन पाया
“include” फीचर को server-side, यानी web browser के बाहर प्रोसेस होने वाली चीज़ माना जाता है
HTML client-side है, और असल में programming language नहीं बल्कि markup syntax है. लेख में जैसा कहा गया है, यह समस्या पहले ही हल हो चुकी है. Web design के छात्र PHP सीखते समय सबसे पहले include से ही परिचित होते हैं, और ज़्यादातर CMS में include template partial बन जाता है और दस्तावेज़ की शुरुआत में ही समझाया जाता है. सिर्फ HTML से include संभव बनाने की कोई खास ज़रूरत नहीं है. HTML एक presentation format है और CSS व JS के बिना कोई दिलचस्प काम नहीं करता
असल में HTML में frames और iframes के रूप में इसके और भी खराब version पहले से मौजूद हैं. Server-side include का client-side counterpart उन कामों में स्वाभाविक रूप से फिट बैठता है जो लोग HTML से करते हैं
शायद इसे custom elements से code किया जा सकता है, और अगर GitHub पर ऐसा मिलता-जुलता repository न हो तो उल्टा हैरानी होगी
images या पेज के नीचे के content की तरह कुछ content पहले से async load होता है. “HTML programming language नहीं, markup syntax है” कहना flamebait के करीब है; यह browser engines द्वारा interpret की जाने वाली declarative language है
अगर styling की बात है, तो presentation CSS संभालता है
विकल्प दो हैं. पहला, HTML parsing के समय, यानी DOM बनने से पहले process करना; लेकिन include के लिए server को synchronous request करनी पड़ेगी, इसलिए यह अच्छा नहीं है. दूसरा, DOM बनने के बाद कोई खास element DOM में दिखाई दे, फिर fragment को asynchronously load करके उस DOM element को external fragment से replace किया जाए; लेकिन यह मौजूदा DOM structure validation mechanism को निष्प्रभावी कर देता है. हालांकि Sciter engine में इसे पहली strategy से implement किया गया था. Sciter का HTML आमतौर पर local app resources या file system से आता है, इसलिए extra fragment request की लागत नगण्य होती है
https://docs.sciter.com/docs/HTML/html-include
HTML include में, जैसा दूसरों ने कहा, कई समस्याएं हैं
अगर
main.htmlमेंchild/include1.htmlशामिल है, औरchild/include1.htmlके अंदरsrc="include2.html"link है, तो user के click करने पर उसे कहां जाना चाहिए?include2.htmlपर जाए तो नाम से ही वह include के लिए बना page होगा और बाकी हिस्सा गायब होगा;main.htmlपर जाए तो इस बार यह कैसे बताया जाए किinclude1.htmlनहीं बल्किinclude2.htmlइस्तेमाल करना है? उल्टा,article1.html,article2.html,article3.htmlमें हर एकheader.html,footer.html,navi.htmlशामिल कर सकता है, लेकिन तब सभी articles की structure को globally बदलना हो तो हर article को modify करना पड़ेगा. अगर सभी articles मेंcomments.htmlजोड़ना हो, तो अंत में फिर template से pages generate करना चाहेंगे, और उस समय browser include की ज़रूरत नहीं बचेगी. Header को title जानना हो या footer को previous/next links जानने हों जैसी समस्याएं भी पैदा होती हैं, और includes के बीच information पास करने का तरीका चाहिए, जिससे आखिरकार page generation पर ही लौटना पड़ता है. सोचकर देखें तो HTML include ज़्यादातर use cases में व्यावहारिक रूप से बेकार होने की संभावना अधिक हैयहां दो अलग use cases मिले हुए हैं. एक है fragment reuse और दूसरा है embeddable independent island. दूसरे को iframe पहले ही संभालता है, इसलिए सिर्फ पहले को हल करना है
include2.htmlमें बाकी हिस्सा खो जाने वाली include logic दूसरे includes पर भी बिल्कुल वैसे ही लागू होती हैअगर user
src="include.css"link पर click करे तो गड़बड़ हो जाएगी. Static data, images, CSS, static HTML content के लिए यह ठीक हो सकता हैWHATWG में इससे जुड़ा एक open issue है. Blog post के comments section में भी इसका ज़िक्र है
Client side include feature for HTML
https://github.com/whatwg/html/issues/2791
HTML में include था, और उसकी लोकप्रियता खत्म हो गई
असल “include” शब्द XML feature है, और लेख भी वही feature चाहता है. HTML में XML से पहले बना एक अलग approach था, जो frames था. Frames XML include से कहीं ज़्यादा काम करते थे, इसलिए HTML को वह feature अलग से नहीं मिला. Frames misuse, security, accessibility जैसी कई समस्याओं की वजह से लोकप्रियता खो बैठे
कभी-कभी इस्तेमाल करना अभी भी पसंद है, लेकिन इसे users या browser को देने से पहले evaluate करने वाला compile step चाहिए