Es ist für mich extrem überraschend, dass HTML nie eine Möglichkeit hatte, andere HTML-Dateien darin einzubinden. Auch scheint nichts am Horizont zu sein, das dies adressiert. Ich spreche von geradlinigen Includes, wie das Nehmen eines HTML-Abschnitts und das Einfügen direkt in einen anderen. Zum Beispiel der Anwendungsfall für einen Großteil des gesamten Internets, ein eingebundener Header und Footer für alle Seiten
...
<body>
<include src="./header.html"></include>
Content
<include src="./footer.html"></include>
</body>
...
Das ist übrigens nicht real. Ich wünschte nur, es wäre es.
Die Leute greifen schon ewig auf andere Sprachen zurück, um dieses Problem für sich zu lösen. Es ist sozusagen HTML-Preprocessing. Lange bevor wir unser CSS vorverarbeiten, haben wir Werkzeuge zur Manipulation unseres HTML verwendet. Und das tun wir immer noch, denn die Idee von Includes ist auf so ziemlich jeder Website der Welt nützlich.
PHP verwenden
Kannst du stattdessen PHP verwenden?
...
<body>
<?php include "./header.html" ?>
Content
<?php include "./footer.html" ?>
</body>
...
Dies wird den Include auf Serverebene durchführen, sodass die Anfrage auf Dateisystemebene auf dem Server erfolgt. Das sollte also weitaus schneller sein als eine clientseitige Lösung.
Gulp verwenden
Was ist noch schneller als ein serverseitiger Include? Wenn der Include vorverarbeitet wird, bevor er überhaupt auf dem Server ist. Gulp hat eine Vielzahl von Prozessoren, die das tun können. Einer davon ist gulp-file-include.
Das würde so aussehen
...
<body>
@@include('./header.html')
Content
@@include('./footer.html')
</body>
...
Und du würdest es so verarbeiten:
var fileinclude = require('gulp-file-include'),
gulp = require('gulp');
gulp.task('fileinclude', function() {
gulp.src(['index.html'])
.pipe(fileinclude({
prefix: '@@',
basepath: '@file'
}))
.pipe(gulp.dest('./'));
});
Dieses spezielle Plugin scheint schicke Funktionen zu haben, bei denen du Variablen an die Includes übergeben kannst, was es ermöglicht, kleine datengesteuerte Komponenten zu erstellen.
Grunt verwenden
Das macht das grunt-bake Plugin. Du würdest Grunt so konfigurieren, dass es dein HTML verarbeitet
grunt.initConfig({
bake: {
your_target: {
files: {
"dist/index.html": "app/index.html",
}
}
}
});
Dann kann dein HTML diese spezielle Syntax für Includes verwenden
...
<body>
<!--(bake header.html)-->
Content
<!--(bake footer.html)-->
</body>
...
Handlebars verwenden
Handlebars hat Partials.
Du registrierst sie
Handlebars.registerPartial('myPartial', '{{name}}')
Dann verwendest du sie
{{> myPartial }}
Es gibt auch schicke Funktionen, die Auswertung und Datenübergabe ermöglichen. Du brauchst aber immer noch einen Prozessor, um es auszuführen, wahrscheinlich etwas wie gulp-handlebars.
Apropos Vorlagensprachen, die geschweifte Klammern verwenden… Mustache haben sie auch.
Pug verwenden
Pug ist ein HTML-Präprozessor, der eine ganz neue Syntax für HTML hat, die etwas kürzer ist. Es hat aber Includes.
...
body
include ./header.html"
p Content
include ./footer.html"
...
Dann führst du es mit etwas wie gulp-pug aus.
Nunjucks verwenden
Ich liebe Nunjucks! Nunjucks hat Includes. Das würdest du so machen:
...
<body>
{% include "./header.html" %}
Content
{% include "./footer.html" %}
</body>
...
Wenn du das in eine Datei namens index.njk packst, könntest du es mit einem einfachen Node-Skript in index.html so verarbeiten:
const nunjucks = require("nunjucks");
const fs = require("fs");
fs.writeFile("index.html", nunjucks.render("index.njk"), function(err, data) {
if (err) console.log(err);
console.log("Compiled the Nunjucks, captain.");
});
Oder mit etwas wie gulp-nunjucks verarbeiten.
11ty hat Nunjucks integriert, zusammen mit vielen der anderen genannten. Könnte gut für dich sein, wenn du tatsächlich eine kleine Website baust.
AJAX verwenden
Angenommen, du hättest…
<body>
<header></header>
Content.
<footer></footer>
</body>
Du könntest die Inhalte für Header und Footer aus entsprechenden Dateien abrufen und die Inhalte einfügen.
fetch("./header.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("header").innerHTML = data;
});
fetch("./footer.html")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("footer").innerHTML = data;
});
Apropos JavaScript… Wenn du deine Website mit einem JavaScript-Framework jeglicher Art baust, ist der Aufbau über Komponenten eigentlich das Hauptthema, und das Aufteilen von Teilen, die du in anderen Dateien einbinden möchtest, sollte kein Problem sein. Eine Art von import Header from "./header.js"; und <Header /> wäre das, was du im React-Bereich tun würdest.
IFrames verwenden
Du könntest das tun:
<body>
<iframe src="./header.html"></iframe>
Content.
<iframe src="./footer.html"></iframe>
</body>
Aber der Inhalt dieser iframes teilt sich nicht den gleichen DOM, daher ist es etwas seltsam, ganz zu schweigen von langsam und umständlich zu stylen (da iframes die Höhen ihrer Inhalte nicht kennen).
Scott Jehl hat eine coole Idee dokumentiert: Du kannst den iframe den Inhalt seiner selbst auf die Elterseite injizieren lassen und sich dann entfernen.
<body>
<iframe src="header.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"></iframe>
Content.
<iframe src="footer.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"></iframe>
</body>
Kolya Korruptis schrieb mit dieser Anpassung, die mehr als das erste Kind des Körpers einbeziehen wird, falls Ihre HTML-Datei das hat
<iframe src="included.html" onload="this.insertAdjacentHTML('afterend', (this.contentDocument.body||this.contentDocument).innerHTML);this.remove()"></iframe>
Jekyll verwenden
Jekyll ist ein Ruby-basierter statischer Site-Generator mit Includes. Du behältst deine Includes im /_includes/ Ordner, dann
<body>
{% include header.html %}
Content.
{% include footer.html %}
</body>
Jekyll ist ein großer, daher hebe ich ihn hier hervor, aber es gibt eine Menge statischer Site-Generatoren und ich würde wetten, dass jeder von ihnen Includes kann.
Sergey verwenden
OK, ich nenne noch einen SSG nennenswert, weil er neu und super fokussiert ist. Sergey hat ein Web-Komponenten-Stil-Format
<body>
<sergey-import src="header" />
Content.
<sergey-import src="footer" />
</body>
Du würdest die Dateien header.html und footer.html benennen und sie in /includes/ legen und dann wird eine Build mit den verarbeiteten Includes erstellt, wenn du das npm-Skript ausführst, das sie dir vorgeben.
Apache SSI verwenden
Apache, ein superduper gängiger Webserver, kann Includes. Das machst du so:
<body>
<!--#include file="./header.html" -->
Content
<!--#include file="./footer.html" -->
</body>
Aber du brauchst die richtige Apache-Konfiguration, um Dinge zuzulassen. Ich habe mein Bestes getan, um eine funktionierende Demo zu erstellen, hatte aber wenig Erfolg.
Ich habe versucht, .htaccess in einem Ordner auf einem Apache-Server zu verwenden und die richtigen Dinge einzuschalten
Options +Includes
AddType text/html .html
AddOutputFilter INCLUDES .html
Ich bin sicher, es gibt einen Weg, es zum Laufen zu bringen, und wenn du es schaffst, ist es irgendwie nett, dass es keine zusätzlichen Abhängigkeiten braucht.
CodeKit verwenden
Nur für Mac, aber CodeKit hat eine spezielle Sprache namens Kit, die es verarbeitet, und deren Zweck zu 90% HTML-Includes sind. Es verwendet spezielle HTML-Kommentare
...
<body>
<!-- @import "./header.html" -->
Content
<!-- @import "./footer.html" -->
</body>
...
Dreamweaver verwenden
Lol, kleiner Scherz. Aber es ist wirklich eine Sache. DWTs, Baby.
Heiliger Bimbam
Das sind viele Wege, oder?
Wie ich oben sagte, ist es für mich sehr überraschend, dass HTML dies nicht direkt adressiert hat. Nicht, dass ich denke, es wäre eine großartige Idee für die Performance, <include>-Anweisungen zu haben, die Netzwerkanfragen über unseren gesamten Code auslösen, aber es scheint im Einklang mit der Plattform zu sein. Das direkte Importieren von ES6-Imports ohne Bündelung ist auch nicht immer eine gute Idee, aber wir haben sie. CSS innerhalb von CSS zu importieren ist auch nicht immer eine gute Idee, aber wir haben es. Wenn die Plattform eine native Syntax hätte, würden sich vielleicht andere Werkzeuge daran orientieren, ähnlich wie JavaScript-Bundler das ES6-Importformat unterstützen.
Wie sieht es mit dem Webpack HTML Plugin aus? Ich benutze es für mein Portfolio und es macht einen ziemlich soliden Job in Bezug auf Variablen und Includes!
Lachen Sie, aber Dreamweaver-Vorlagen sind das Einzige, was ich an der Webentwicklung um 2001 am meisten vermisse. Tot einfach, flexibel, WYSIWYG-Vorschauen und keine brüchigen Abhängigkeiten oder seltsamen Build-Fehler.
Um der Vollständigkeit halber zu erwähnen, ich habe das schon mal mit jQuery gemacht. (Ich bin sicher, es zählt als 'AJAX verwenden', aber trotzdem.)
Woa, Dreamweaver hat es auf die Liste geschafft, aber kein SHTML, traurig.
Man könnte auch pHTML verwenden, wenn man es nativ haben möchte.
https://github.com/phtmlorg/phtml-include
Erfordert Apache SSI nicht, dass die HTML-Dateien eine .shtml-Erweiterung haben?
Die Standarderweiterung ist .shtml, aber du kannst diese Zeile in deine .htaccess-Datei einfügen, wenn du lieber bei .html bleibst:
AddHandler server-parsed .html
SSI: Server Side Include
Server Side Includes (SSIs) sind PERL-sprachbasierte Befehle, die es ermöglichen, Informationen vom Server zu sammeln. PERL und CGI gibt es seit der Entstehung des Internets und all diese anderen High-Level-Sprachen basieren auf den Fähigkeiten von PERL.
Das Konzept ist, den Server zur Sammlung und Veröffentlichung von Informationen zu nutzen. Auf diese Weise hast du keine Probleme mit Browserversionen. Das Eingefügte wird eingefügt, bevor es den Browser erreicht, sodass Versionen nie eine Rolle spielen.
Die meisten UNIX-Server sind für SSI eingerichtet. Diejenigen auf WindowsNT-basierten Servern müssen möglicherweise auf ASP zurückgreifen, um viele dieser Effekte zu erzielen, aber überprüfe zuerst, bevor du entscheidest, dass du diese Befehle nicht ausführen kannst. Vielleicht kannst du es.
Für weitere Informationen siehe
https://www.htmlgoodies.com/beyond/webmaster/article.php/3473341/SSI-The-Include-Command.htm
SSI war lange Zeit mein Favorit. Ich habe es mit Apache, IIS und Nginx verwendet. Du brauchst wirklich Kontrolle über den Server, um die Konfiguration zu garantieren. Später in den Grunt-Tagen habe ich Bake und Nunjucks verwendet. Heutzutage ist alles React. Man fragt sich, ob React eine Sache wäre, wenn dein Include-Tag von Anfang an existiert hätte...
NHTML-Imports sollten der ursprüngliche Weg sein, um dies zu regeln. Imports waren Teil des Web-Components-Vorschlags, aber Browser implementierten den Standard nicht.
https://www.html5rocks.com/tutorials/webcomponents/imports/
Tatsächlich ist das erste Beispiel, das du gepostet hast, *fast* echt. Ich habe diese exakte Syntax in einem Projekt verwendet, das Parcel als Bundler nutzt. Es ist super einfach einzurichten und alles, was du tun musst, ist
parcel build index.htmlund du bist fertig.Du kannst die serverseitigen Includes zum Laufen bringen, indem du
include virtualanstelle voninclude fileverwendest.Hier ist ein Artikel, den ich dazu geschrieben habe:
https://www.chromestatus.com/feature/5144752345317376 es existiert tatsächlich, wird aber in Chrome im Juni ausgelöscht, weil es nie volle Unterstützung bekam. Prost.
HTML-Imports sind sehr cool und ich weiß, dass sie viele Leute traurig machen, dass sie praktisch tot sind.
Aber ich bin mir auch zu 99% sicher, dass sie nie dazu gedacht waren, einfach nur einen HTML-Block in ein anderes HTML-Dokument einzufügen, wie es ein Include tut.
Wenn du E-Mails machst, benutze MJML. https://mjml.io/documentation/#mj-include
Imports erhielten keine volle Unterstützung von Mozilla, weil die Spezifikation Probleme hatte.
Eines der größten Probleme war, dass man immer noch JavaScript schreiben musste, um sie zum Laufen zu bringen – und an dem Punkt, an dem man JavaScript benutzt, könnte man genauso gut seinen eigenen Import-Component polyfillen. Mozilla fand, dass es angesichts der Tatsache, dass Imports mit JavaScript ziemlich einfach zu machen sind, und angesichts der Tatsache, dass es Uneinigkeit in der Community darüber gibt, was der "beste" Weg ist, sie zu tun, besser war, einen progressiven Web-Ansatz zu wählen und abzuwarten, wie sich die Community entwickelt.
Ich denke, es war absolut die richtige Entscheidung, sie abzulehnen. Was Chris anspricht, ist etwas viel Einfacheres und Transparenteres, das ohne den Einstieg in Webkomponenten verwendet werden kann.
Wenn du einen Cache-Server wie Varnish betreibst, kannst du ESI verwenden. Mit ESI kannst du deine Webseiten nicht nur als Komponenten erstellen, sondern die Komponenten können auch auf verschiedenen Servern liegen.
Wow, es war toll zu sehen, dass es so viele Wege gibt, Dateien einzubinden… Besonders die iframe-Option mit Selbstzerstörung.
Schon mal von Frames, Frameset gehört?
Du hast "mit Web Components" verpasst: https://www.github.com/gustafnk/h-include
Auch
https://github.com/github/include-fragment-element
Ja, es gibt viele Wege, dies auf dem Server zu vorverarbeiten. Aber leider gibt es keine HTML-Standardmethode, die in die Sprache selbst integriert ist. Und das ist das eigentliche Problem. Sicher, du kannst es in einem Server-Framework tun, sicher, du kannst es mit AJAX tun, sicher, du kannst es über einen Apache-Hack tun – aber das Richtige fehlt immer noch. Du hast keinen nativen HTML-Import in der HTML-Sprache. Es gibt keine Möglichkeit, zwei Seiten zu einer zu komponieren. Und das ist traurig.
Ich habe neulich darüber nachgedacht und wie wichtig das in der komponentengetriebenen Welt der Frontend-Frameworks wäre. Es würde zur Wiederverwendbarkeit und Modularisierung beitragen, und das alles nativ. Wie interessant wäre das denn?
Gut. Es lohnt sich wahrscheinlich hinzuzufügen, dass die PHP-Option auch als clientseitige Technik ähnlich wie Grunt/Gulp etc. verwendet werden kann.
Nach meinen Erinnerungen sollten HTML-Imports die Aufgabe erfüllen und sie sterben tatsächlich den Tod der Verdeprecation…
Ich bin mir ziemlich sicher, dass Jekylls
includeMagie dank Liquid ist, sodass du nicht den gesamten Generator brauchst, wenn das alles ist, was du willst.Eine weitere coole Methode sind Web Components.
Definiere ein benutzerdefiniertes Element, z.B.
<my-header>Schreibe den Vorlagencode und füge das JavaScript hinzu.
Ich mag sie wirklich
Wow, cool!
Ich habe in den letzten Jahren gerne file-include in meinen NPM-Skripten verwendet, bin aber kürzlich ein Fan von Handlebars mit Panini geworden, wie es Foundation in seinen erweiterten Build-Optionen verwendet.
Gibt es Gespräche in den Arbeitsgruppen oder bei Herstellern darüber, warum es keine native Lösung gibt?
Für Codekit Kit-Sprach-Includes unterstützt Prepros dies auf Mac und Windows.
Eine weitere Möglichkeit, HTML mit Gulp oder Grunt einzubinden, ist das Plugin processhtml. Die Syntax verwendet HTML-Kommentare
Es hat auch den Vorteil, unterschiedliche Dateien für verschiedene Umgebungen einzubinden. Zum Beispiel möchtest du vielleicht minifiziertes HTML für die Produktion verwenden.
Nur zur Info: Damit die PHP-Include-Option funktioniert, musst du deinem Webserver mitteilen, dass .html-Dateien wie PHP verarbeitet werden sollen. Wie das erreicht wird, hängt stark von deiner Serverkonfiguration ab. Unabhängig davon wirkt sich dies negativ auf die Leistung aus, da dein Server früher nur ein Textdokument abgerufen und zurückgegeben hat, nun aber einen PHP-Thread starten und das HTML so verarbeiten muss, als wäre es PHP-Code. Selbst für eine einfache Aufgabe wie diese wird zwangsläufig mehr CPU/Speicher verbraucht, für jede Seite – selbst wenn deine Seite kein PHP enthält, wird sie trotzdem von PHP geparst.
Wenn du Apache verwendest, sind SSIs eine weitaus bessere Option für ein einfaches Include wie dieses. Ich bin mir nicht sicher, was dein Problem gewesen sein mag (obwohl die Verwendung von .htaccess nur funktioniert, wenn die zugrunde liegende Apache-Konfiguration dies zulässt), aber ich habe es in der Vergangenheit sehr erfolgreich eingesetzt. Es ist hoch optimiert und hat daher (meiner Erfahrung nach) kaum Auswirkungen auf die Leistung.
Toller Artikel, Chris. Es ist ziemlich nervig, dass dies das Leben viel einfacher machen würde und die Nutzung von CMS wahrscheinlich signifikant zurückgehen würde. Ich erinnere mich, dass ich Dutzende Male statt nur HTML Drupal oder WordPress verwendet habe, nur weil ich dazwischen lag, die ganze Komplexität nicht brauchte, aber dennoch die Funktionen von HTML vermisste. Außerdem waren die Frameworks für ein so kleines Projekt zu viel… Hoffentlich eines Tages…
Prost!
Ich nutze das für einfache Menüs oben auf den Seiten
Funktioniert gut für einfache Seiten.
Hallo Chris, vielen Dank für all die großartigen Artikel, ich habe dadurch viel gelernt!
Du weißt wahrscheinlich schon, dass es möglich ist, die Syntax zu verwenden, die du in deinem oberen Beispiel beschreibst:
<include src="path_to/partial_file.html"></include>mit dem PostHTML Include Plugin.Wie wäre es mit PostHTML? https://github.com/posthtml/posthtml-include
Ich schäme mich zuzugeben, dass meine Portfolio-Seite, die ich ursprünglich um 2002 entwickelt habe (und die seitdem kaum aktualisiert wurde), shtml verwendet/verwendet hat. https://www.yourhtmlsource.com/sitemanagement/includes.html
Es war für mich erstaunlich einfach einzurichten und zu verwenden, genau wie du es für Header und Footer erwähnst.
Verwenden Sie eine PWA, um den Header/Footer zu cachen.
Wie hebt man die aktuell „ausgewählte“ oberste Menüebene hervor? Parsen des Headers nach der aktuellen URL und Hinzufügen einer Klasse? Es wäre schön, das in einer PWA-Lösung integriert zu sehen.
Es gibt noch einen anderen Weg, den ich vorher verwendet habe.
Zuerst – die Datei mit der Erweiterung .inc speichern.
Zweitens – zum Webserver gehen und die Unterstützung für die .Inc-Erweiterung und die Rendering-Engine, in diesem Fall HTML, erstellen oder aktualisieren. Dies kann auch über die .htaccess- oder web.config-Datei erfolgen.
Bitte npm-Skripte!!
Sie können auch eine Template-Engine wie Smarty verwenden. Einige Webshops, die ich kenne, nutzen diese Methode.
https://www.smarty.net/docs/en/language.function.include.tpl
Gibt es einen Grund zu glauben, dass ein HTML-Include andere Methoden übertreffen würde? Ich bin mir nicht sicher, warum jemand das für statisches HTML brauchen würde.
Damals, als wir ASP hatten, benutzten wir SSI (Server Side Includes).
Was ist aus SSI geworden?
Können wir CSS verwenden?
p:first-child{
content:“Text hier einfügen…”;
}
Twig! Leistungsfähiger als Handlebars/Mustache, aber immer noch sehr einfach zu bedienen (sehr ähnliche Syntax).
Damit SSI unter Apache läuft, möchten Sie dies in Ihrer .htaccess-Konfiguration verwenden:
Options +Includes
AddHandler server-parsed .shtml
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
Wenn jemand reguläre .html-Dateien parsen lassen möchte, ist es besser, XBitHack zu verwenden (es sei denn, Sie betreiben Apache unter Windows, natürlich).
XBitHack on
…zusammen mit
chmod +x somepage.html
….für Dateien, die geparst werden sollen. Beachten Sie: „Diese Direktive wirkt sich nur auf Dateien aus, die mit dem MIME-Typ text/html assoziiert sind.“ Stellen Sie sicher, dass Ihre Apache-Installation mod_include installiert und aktiviert hat, sowie mod_expires, um Probleme mit SSI bei Verwendung bestimmter Direktiven zu vermeiden.
Includes für HTML in weniger als 1 KB JavaScript
https://github.com/Paul-Browne/HTMLInclude
Wenn Sie eine native Alternative wünschen, siehe diese Diskussion: https://github.com/whatwg/html/issues/2791
IIS kann SSI auch. Ich benutze SSI seit Jahren auf Apache und IIS. Die Implementierung in IIS ist flexibler: Sie können mit relativen Pfaden auf Dateien zugreifen, die sich höher im Dateisystem befinden (../../../otherdirectory/file.shtm), während Apache dafür absolute Pfade benötigt (/otherdirectory/file.shtml).
Oh Mann! Vielen Dank, ich konnte endlich HTML-Snippets statisch einbinden. Gulp war meine bevorzugte Option und sie funktioniert perfekt.
Riesiger Fan der
.kit-Sprache von CodeKit. Ich benutze sie über Gulp…gulp-kit. Sehr empfehlenswert für einfache statische Websites.Es gab früher auch etwas namens shtml, das das ebenfalls getan hat.
Perfekt! Ich habe es sofort zum Laufen gebracht, indem ich den HTML-Include auf Apache mit dem von Ihnen erstellten .htaccess-Code verwendet habe. Ich arbeite gerade an einer flachen Seite und das hat wunderbar funktioniert!
document.write hat für mich den Trick gemacht. Keine Bibliotheken, Frameworks, serverseitigen Dinge.
Hallo
Es scheint immer noch, dass die ursprüngliche Frage nicht beantwortet wurde: Gibt es eine einfache Möglichkeit, eine HTML-Datei in eine HTML-Datei einzubinden? Ich codiere HTML seit 25 Jahren von Hand, daher ist das, was ich tue, ziemlich einfach, aber meinen Bedürfnissen und den Bedürfnissen meiner Benutzer angemessen. Nenn mich einen Ludditen, in Ordnung. ;-)
Aber man sollte meinen, wie am Anfang dieses Threads erwähnt, dass dies Teil von HTML 0.01 wäre.
Etwas Äquivalentes zu „img src picture.gif“, aber für HTML. ;-)
An zweiter Stelle wäre ein konkretes Beispiel, anstatt nur Code-Schnipsel ohne Kontext, weil man annimmt, dass jeder weiß, was zur Hölle gemeint ist.
Ich möchte etwas wie: „html src file.html“, das im Wesentlichen die Parameter des aufrufenden HTML-Dokuments erbt, sodass es so eingefügt wird, als ob der Text an dieser Stelle eingefügt worden wäre. Im Wesentlichen das Aufrufen von Textblöcken aus mehreren Webseiten, damit sie nicht dupliziert und einzeln im Haupt-HTML-Dokument gepflegt werden müssen.
Vielen Dank,
— Sam